Skip to main content

POST /

Proxy JSON-RPC requests to backend Solana RPC nodes. The router authenticates requests via API key, selects a healthy backend using weighted load balancing or method-based routing, and forwards the request.

Authentication

All proxy requests require an API key passed as a query parameter:
POST /?api-key=YOUR_API_KEY
The API key is validated against Redis and checked against per-key rate limits before forwarding.

Request

jsonrpc
string
required
JSON-RPC version (must be "2.0")
id
number | string
required
Request identifier
method
string
required
Solana RPC method name (e.g., getAccountInfo, getSlot, sendTransaction)
params
array
Method-specific parameters

Response

The response format matches the Solana JSON-RPC specification. Successful backend responses are proxied transparently:
jsonrpc
string
JSON-RPC version ("2.0")
id
number | string
Request identifier (matches request)
result
any
Method-specific result data from the backend
error
object
Error object (only present if backend returned an error)

Error Responses

401 Unauthorized
string
Returned when:
  • No api-key query parameter provided
  • Invalid API key
  • API key is inactive (active=false in Redis)
Response body: "Unauthorized"
429 Too Many Requests
string
Returned when the API key exceeds its configured rate limit (RPS).Response body: "Rate limit exceeded"
500 Internal Server Error
string
Returned when:
  • Redis connection error during key validation
  • Invalid backend URI configuration
Response body: "Internal Server Error" or "Invalid backend configuration"
502 Bad Gateway
string
Returned when the backend request fails (network error, invalid response, etc.).Response body: "Proxy error: {error_details}"
503 Service Unavailable
string
Returned when no healthy backends are available to handle the request.Response body: "No healthy backends available"
504 Gateway Timeout
string
Returned when the backend request exceeds the configured timeout (default 30s).Response body: "Upstream request timed out after {timeout}s"

Backend Selection

The router selects backends using this priority:
  1. Method-based routing: If the method field matches a configured route (e.g., getSlot -> mainnet-primary), that backend is used if healthy
  2. Weighted load balancing: Randomly selects from healthy backends using configured weights
  3. Fallback: Returns 503 if no healthy backends are available

Request Examples

curl -X POST "https://rpc.example.com/?api-key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getSlot",
    "params": []
  }'

Response Examples

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": 123456789
}

POST /*path

Proxy JSON-RPC requests with a custom path. This endpoint forwards requests to {backend_url}{path}?{query_params} while stripping the api-key parameter.

Path Parameters

path
string
Custom path to append to the backend URL (e.g., /v1/mainnet)

Authentication

Same as POST / - requires ?api-key=YOUR_API_KEY query parameter.

Request/Response

Identical to POST / endpoint. The only difference is the path forwarding behavior.

Path Handling

The router constructs the backend URL as:
  • Request: POST /v1/mainnet?api-key=abc123&commitment=finalized
  • Backend: {backend_url}/v1/mainnet?commitment=finalized
Security: The api-key query parameter is automatically stripped before forwarding requests to backends. This ensures backend nodes never see client API keys, and request logs on backend nodes don’t contain sensitive credentials.

Example

Custom Path
curl -X POST "https://rpc.example.com/v1/mainnet?api-key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getHealth"
  }'

Rate Limiting

Both POST / and POST /*path share the same rate limit counter per API key. Rate limits are enforced atomically in Redis using a Lua script:
  1. Increment rate_limit:{api_key} counter
  2. Set 1-second TTL if this is the first request in the window
  3. Compare count against the key’s configured rate_limit
  4. Return 429 if limit exceeded

Timeout Behavior

Backend requests timeout after the configured proxy.timeout_secs (default 30s). When a timeout occurs:
  • Status: 504 Gateway Timeout
  • Response: "Upstream request timed out after {timeout}s"
  • Metrics: Request is logged with backend label and timeout status

Host Header

The router automatically updates the Host header to match the selected backend, ensuring proper routing through CDNs and reverse proxies.

Build docs developers (and LLMs) love