Skip to main content
RPC operator referenceHTTPS · JSON-RPC 2.0

Public RPC endpoints

SolidRPC provides keyless HTTPS endpoints for wallets, development, testing, and lightweight application traffic. No account or API key is required.

Endpoint format

Request example
https://rpc.solidrpc.io/public/evm/{chainId}

For example, fetch the latest Ethereum block number:

Request example
curl https://rpc.solidrpc.io/public/evm/1 \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

Requests use JSON-RPC 2.0 over HTTPS POST. Browser requests are supported through CORS. There is no WebSocket endpoint.

Supported networks

NetworkChain IDPublic endpoint
Ethereum1https://rpc.solidrpc.io/public/evm/1
Optimism10https://rpc.solidrpc.io/public/evm/10
BNB Smart Chain56https://rpc.solidrpc.io/public/evm/56
Polygon PoS137https://rpc.solidrpc.io/public/evm/137
Robinhood Chain4663https://rpc.solidrpc.io/public/evm/4663
Base8453https://rpc.solidrpc.io/public/evm/8453
Arbitrum One42161https://rpc.solidrpc.io/public/evm/42161
Avalanche C-Chain43114https://rpc.solidrpc.io/public/evm/43114
Arc Testnet5042002https://rpc.solidrpc.io/public/evm/5042002

Method policy

The public route accepts the standard eth_*, net_*, and web3_* namespaces, including eth_sendRawTransaction. Method matching is case-insensitive.

debug_*, trace_*, client-specific namespaces, and node-control methods are rejected with JSON-RPC -32601. Every request is validated before it is proxied or counted.

The stateful filter and subscription methods are rejected the same way, despite their eth_ prefix: eth_newFilter, eth_newBlockFilter, eth_newPendingTransactionFilter, eth_getFilterChanges, eth_getFilterLogs, eth_uninstallFilter, eth_subscribe and eth_unsubscribe. A filter is server-side state whose eventual eth_getFilterLogs carries no block range for the log query limit to check, and subscriptions need a transport the keyless route does not offer. Use eth_getLogs with an explicit range, or an authenticated endpoint.

One call per request

The public endpoint accepts one JSON-RPC call per HTTP request. An array body with more than one entry is rejected with HTTP 200 and JSON-RPC -32600. A single-entry array is accepted, so clients that always frame requests as arrays keep working. Multi-call batching must be disabled. For ethers v6, set batchMaxCount: 1. For viem, leave batch unset. A rejected batch is answered with a JSON-RPC array carrying one error object per call, each with that call's own id.

Request example
[
  {
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
      "code": -32600,
      "message": "Batch requests are not supported on the public endpoint",
      "data": {
        "reason": "batch_limit",
        "maxBatchEntries": 1,
        "receivedBatchEntries": 2,
        "resolution": "Send one JSON-RPC call per HTTP request (disable client-side batching, e.g. ethers batchMaxCount: 1), or create a free API key for batched workloads.",
        "documentation_url": "https://solidrpc.io/docs/public-rpc"
      }
    }
  },
  { "jsonrpc": "2.0", "id": 2, "error": { "code": -32600, "...": "..." } }
]

This rejection is permanent, not a throttle: unlike a -32005 rate-limit response, retrying the same batch never succeeds. Reconfigure the client instead. Batched workloads belong on an authenticated endpoint: a free API key supports batching within your plan's burst capacity.

Log query limit

eth_getLogs is bounded per chain, and a query that selects logs gets a wider range than one that does not. A filter counts when address is a non-empty string or array, or when topics contains at least one topic or list of alternatives. Empty selectors — [], [null], [[]] — are not filters.

NetworkChain IDUnfiltered blocksFiltered blocks
Ethereum1252,000
Optimism10252,000
BNB Smart Chain *562525
Polygon PoS *13755
Robinhood Chain466316200
Base8453252,000
Arbitrum One42161200500
Avalanche C-Chain *431146060
Arc Testnet *5042002100100

The limits are per chain because log density differs by chain, and 2,000 is the ceiling no chain exceeds. On some chains a query that carries an address or topics filter is allowed a wider range than one that scans everything; rows marked * currently keep the two limits equal. Limits may be tuned over time — the error response always states the current limit and suggests a range that will succeed. See the next section for that shape. A blockHash filter addresses one known block: it neither counts toward the request budget nor tightens it. Dynamic upper tags are resolved before the range is checked. The limit is the budget for the whole HTTP request, so a batch is checked on its combined range as well as per call, against the tightest limit any call in it earned.

The table covers the networks this route serves. Other chains the gateway can reach carry their own entries in the same policy table, and a chain with no entry at all uses a conservative 25 unfiltered and 100 filtered blocks.

Malformed, reversed, indeterminate, or oversized ranges return HTTP 200 with JSON-RPC -32602. An oversized range names both remedies and suggests a range you can re-send as-is:

Request example
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "eth_getLogs block range too large: 2000 blocks requested, unfiltered queries on this chain are limited to 16 blocks (add an address or topics filter for up to 200). Try with this block range [0x3412d2c, 0x3412d3b], or retry with the range 54603052-54603067.",
    "data": {
      "reason": "unfiltered_range_limit",
      "maxBlockRange": 16,
      "maxUnfilteredBlockRange": 16,
      "maxFilteredBlockRange": 200,
      "requestedBlockRange": "2000",
      "from": "0x3412d2c",
      "to": "0x3412d3b",
      "resolution": "Add an address or topics filter for up to 200 blocks per call, or chunk unfiltered queries into 16-block spans. A free API key lifts both limits.",
      "documentation_url": "https://solidrpc.io/docs/public-rpc"
    }
  }
}

Response size limit

A keyless response is capped at 2 MB (2,097,152 bytes). The limit is measured in uncompressed payload bytes, applies to the whole HTTP response — so a batch is measured on its combined result — and is shared by the public and demo routes. It exists because the public route runs on anonymous capacity: a single dense log scan can return tens of megabytes, which one caller can repeat faster than any per-request policy can absorb.

When a response exceeds the cap the transfer is abandoned and the request returns HTTP 200 with JSON-RPC -32020. Narrow the block range, add address or topics filters, or use an authenticated endpoint, which has no public-policy response cap:

Request example
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32020,
    "message": "Response size exceeds the 2097152-byte limit on the keyless endpoint. Narrow the block range, add address or topic filters, or use an API key for authenticated access.",
    "data": {
      "reason": "response_too_large",
      "maxResponseBytes": 2097152,
      "resolution": "Split the query into smaller block ranges, add address or topic filters, or create a free API key for unchunked responses.",
      "documentation_url": "https://solidrpc.io/docs/public-rpc"
    }
  }
}

The request side is bounded too: a keyless request body is limited to 64 KB and a larger one returns HTTP 200 with JSON-RPC -32600.

The keyless routes also share a fixed pool of response buffer memory — a byte budget, not a request slot: a request is charged only for the bytes it actually buffers, so a small call costs almost nothing and large responses in flight do not each reserve a full slot. While the pool is full, though, new requests are refused, and a response already streaming is cut off if its next chunk would overflow it. Either way the reply is HTTP 429 with JSON-RPC -32005 and Retry-After: 1. It is a throttle, not a rejection: retry with backoff and it clears as other responses finish.

Throttling and 429 responses

Cloudflare applies one per-IP counter shared by the public and demo routes: 20 requests per 10 seconds, followed by a 10-second mitigation period. The public service also has shared gateway rate and daily capacity limits.

Throttled requests return HTTP 429 and JSON-RPC -32005. Honor Retry-After and use exponential backoff with jitter. Gateway responses also include X-RateLimit-* and X-Quota-* headers.

Request example
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32005,
    "message": "Public RPC rate limit exceeded",
    "data": {
      "reason": "rate_limit",
      "retryAfterSeconds": 3,
      "resolution": "Wait for retryAfterSeconds, then retry with exponential backoff and jitter.",
      "documentation_url": "https://solidrpc.io/docs/public-rpc"
    }
  }
}

Privacy

SolidRPC processes request metadata such as timestamp, chain, method, response status, and byte count for operations and abuse prevention. RPC request bodies and responses are not logged. Cloudflare processes source IP addresses for security, DDoS protection, and edge rate limiting.

See the Privacy Policy for retention, subprocessors, and privacy-contact details.