Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion api-reference/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,67 @@
}
]
},
"/rpc/evm/{chainId}": {
"post": {
"operationId": "postPublicRpc",
"tags": [
"RPC"
],
"summary": "Public JSON-RPC proxy (no API key)",
"description": "Send a single JSON-RPC request or a JSON-RPC batch (array) to the public, anonymous free tier. No API key required. Rate-limited per IP. For higher volume, use an API key at /rpc/{chainId}/{apiKey}.",
"parameters": [
{
"name": "chainId",
"in": "path",
"required": true,
"description": "Chain ID (e.g. 1 for Ethereum, 137 for Polygon, 8453 for Base).",
"schema": {
"type": "string"
},
"example": "1"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/JsonRpcRequest"
},
{
"$ref": "#/components/schemas/JsonRpcBatchRequest"
}
]
}
}
}
},
"responses": {
"200": {
"description": "JSON-RPC response (single or batch)",
"headers": {
"X-Batch-Id": {
"$ref": "#/components/headers/XBatchId"
}
}
},
"400": {
"description": "Bad request (e.g. invalid JSON or invalid JSON-RPC payload)"
},
"429": {
"description": "Too many requests (public per-IP rate limit exceeded)"
},
"503": {
"description": "Service temporarily unavailable (public free-tier capacity exhausted or unrelated)"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api-keys": {
"get": {
"operationId": "listMyApiKeys",
Expand Down Expand Up @@ -961,7 +1022,7 @@
"properties": {
"code": {
"type": "integer",
"description": "Router error codes: -32700 (parse error), -32600 (invalid request), -32602 (invalid params or eth_getLogs block span too large), -32603 (internal error), -32000 (server error), -32001 (chain not supported), -32002 (method not supported), -32003 (all nodes on cooldown), -32005 (eth_getLogs query limit exceeded)."
"description": "Router error codes: -32700 (parse error), -32600 (invalid request), -32601 (insufficient credits), -32602 (invalid params), -32603 (internal error), -32000 (server error), -32001 (chain not supported), -32002 (method not supported), -32003 (all nodes on cooldown), -32005 (eth_getLogs query limit exceeded), -32007 (no block-param capable nodes), -32008 (no providers available), -32009 (all nodes failed), -32011 (no opcode-capable nodes), -32012 (insufficient historical state depth), -32013 (no single provider satisfies all constraints), -32029 (public per-IP rate limit exceeded), -32030 (public free-tier capacity exhausted). See the RPC error codes guide for details."
},
"message": {
"type": "string",
Expand Down
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"group": "Integration",
"pages": [
"intro/request-behavior",
"intro/websockets",
"intro/debugging",
"intro/mcp-server",
"intro/network-support",
Expand Down
2 changes: 1 addition & 1 deletion intro/debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Every RPC request returns an `X-Batch-Id` response header (UUID). Save it in you
`X-Batch-Id` is per HTTP request:

- Single JSON-RPC request: one `X-Batch-Id`
- JSON-RPC batch (array): one `X-Batch-Id` for the whole batch
- JSON-RPC batch (array): one `X-Batch-Ids` header containing the comma-separated batch IDs for each item in the batch

### How to capture it

Expand Down
14 changes: 13 additions & 1 deletion intro/quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,19 @@ curl -X POST https://lb.routeme.sh/rpc/{chain_id}/{api_key} \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

For **allowed domains**, **cooldowns**, and **batch requests**, see [Request behavior](/intro/request-behavior). For **error handling**, see [RPC error codes](/intro/rpc-error-codes).
For **allowed domains**, **cooldowns**, and **batch requests**, see [Request behavior](/intro/request-behavior). For **error handling**, see [RPC error codes](/intro/rpc-error-codes). For **real-time event streams**, see [WebSocket API](/intro/websockets).

## **Public RPC (no API key)**

You can call RouteMesh without an API key for a limited free tier using the public path `POST /rpc/evm/{chain_id}`. This is intended for light, anonymous access:

```bash
curl -X POST https://lb.routeme.sh/rpc/evm/1 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

The public route is rate-limited per IP. If you hit the limit or it is temporarily unavailable, the response points you to sign up for a free account for full access. For higher volume, use an API key as shown in [Make your first request](#3-make-your-first-request).

## **Supported networks**

Expand Down
12 changes: 11 additions & 1 deletion intro/rpc-error-codes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,27 @@ For a successful HTTP 200, the response may still contain a JSON-RPC `error` (e.
| :----- | :------------------- | :---------------------------------------------------------------------- |
| -32700 | Parse error | Request body is not valid JSON. |
| -32600 | Invalid request | Malformed JSON-RPC (e.g. missing required fields) or an empty batch. |
| -32602 | Invalid params | Invalid `chainId` in the request path, or an `eth_getLogs` block span that exceeds the router limit. |
| -32601 | Insufficient credits | The API key's credit balance is too low to serve the request (HTTP 402). Top up in the dashboard and retry. |
| -32602 | Invalid params | Invalid `chainId` in the request path, an `eth_getLogs` block span that exceeds the router limit, or a response that is too large. |
| -32603 | Internal error | Router encountered an internal failure. Contact support if persistent. |
| -32000 | Server error | Unspecified server error (fallback when no specific code applies). |
| -32001 | Chain not supported | The given `chainId` has no available nodes or paid plan support. |
| -32002 | Method not supported | The JSON-RPC method is not enabled for this chain. |
| -32003 | All nodes on cooldown| Every node that could serve the route is temporarily in cooldown (e.g. after rate limits or errors). Retry after a short delay. |
| -32005 | Limit exceeded | An `eth_getLogs` query matched too many logs or produced a response that is too large for the requested block span. See [eth_getLogs limits](/intro/request-behavior#eth_getlogs-limits). |
| -32007 | No block-param nodes | No provider supports the custom block number parameter used in the request (e.g. an `eth_getLogs` query with a specific block range). |
| -32008 | No providers available| No providers are currently available to serve the route. |
| -32009 | All nodes failed | Every provider failed with a non-rate-limit error (HTTP 424). Retry once; if it persists, contact support. |
| -32011 | No opcode-capable nodes| No provider supports the requested opcode at the given block (e.g. an `eth_call` at a historical block). |
| -32012 | Insufficient historical depth| No provider has sufficient historical state depth (or `eth_getLogs` earliest-block support) for the requested block. |
| -32013 | No single provider satisfies all constraints| No single provider supports the full combination of requested constraints (e.g. block range, depth, method). Try reducing the block range or using a more recent block. |
| -32029 | Public rate limited | The public (no-API-key) route's per-IP rate limit was exceeded (HTTP 429). Sign up for a free account for full access. |
| -32030 | Public capacity exhausted| The public (no-API-key) route's free-tier capacity is temporarily exhausted. Sign up for a free account for full access. |

## Standard JSON-RPC codes

- **-32700** and **-32600** follow the [JSON-RPC 2.0 spec](https://www.jsonrpc.org/specification#error_object) for parse and invalid request errors.
- **-32601** is the JSON-RPC 2.0 "Method not found" code, repurposed here to signal an empty credit balance.
- **-32602** is used for invalid `chainId` (invalid params) and for `eth_getLogs` block-span rejections.
- **-32603** is used for internal router errors.
- **-32005** follows [EIP-1474](https://eips.ethereum.org/EIPS/eip-1474#error-codes) (limit exceeded) for `eth_getLogs` query-density failures.
Expand Down
62 changes: 62 additions & 0 deletions intro/websockets.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: "WebSocket API"
---

RouteMesh supports real-time event streams over WebSocket using the standard Ethereum `eth_subscribe` / `eth_unsubscribe` protocol. This lets you receive pushed notifications — like new blocks or contract logs — without polling.

## Connecting

Connect to the WebSocket URL with your API key in the path (same keys you use for HTTP RPC):

```text
wss://lb.routeme.sh/rpc/{chain_id}/{api_key}
```

The connection must be upgraded from HTTP. On a successful handshake, the server returns an `X-WebSocket-Session-ID` header you can use for debugging.

The handshake validates your API key, origin, and credit balance before the socket is upgraded. Common handshake failures return an HTTP status before upgrade:

- **402** — Insufficient credits
- **429** — Service draining or too many concurrent connections from your IP (a `Retry-After` header tells you when to retry)
- **503** — All connection slots are currently in use
- **401** — Unauthorized (invalid or inactive API key)

## Subscribing and receiving notifications

To subscribe, send `eth_subscribe` with a subscription type:

```json
{"jsonrpc":"2.0","method":"eth_subscribe","params":["newHeads"],"id":1}
```

The server replies with a subscription ID, then streams notifications to you as JSON-RPC `eth_subscription` messages:

```json
{
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"subscription": "0x0f5f...",
"result": { ... }
}
}
```

To stop receiving events for a subscription, send `eth_unsubscribe` with the subscription ID.

## Supported subscription types and pricing

The available subscription types (and their prices) can change as we add chains and providers, so instead of a static list use the live endpoints:

- `GET /pricing/ws` — current WebSocket notification prices per chain and subscription type (price per million notifications)
- `GET /chains/ws` — the chains currently supported over WebSocket

## Reliability

RouteMesh runs WebSocket streams with the same redundancy we apply to HTTP RPC:

- **Seamless provider failover** — if the upstream node behind your subscription goes down, RouteMesh transparently reconnects to an alternate provider while keeping your connection alive. You don't need to re-subscribe.
- **Gap backfill and deduplication** — when we fail over to an alternate provider, we replay any notifications missed during the switch, drop duplicate events, and keep the stream in order, so you don't lose data while connected.

Because this recovery happens while your connection stays open, you get a durable event stream for the lifetime of the socket. If your client disconnects, subscriptions end with the connection — reconnect and re-subscribe to continue.

Loading