Guides

One key, many chains: switching an example to another chain

The same API key works on every supported chain. Learn how URLs are structured, how to discover chains programmatically, and how balances and limits are pooled.

1. One key across all supported chains

The same API key works on all supported chains for JSON-RPC, and for the Data API on chains where it is available. Keys belong to your account and are not bound to a specific chain; there is no need to generate separate API keys for each network.

Credits and rate limits are shared across all networks and across the JSON-RPC API and the Data API; they are not split by network. For detailed billing rules, see the Pricing page.

  • Pooled balance: Paid top-ups and free credits apply across all chains. Calls on any chain draw from the same account balance.
  • Pooled rate limits: Compute Unit (CU) refill rates and burst capacities apply across all chains for a given key. Free Plan per-second call limits are pooled across all supported chains rather than split per chain.
  • Upgrade path: After topping up, you are no longer constrained by the Free Plan's per-second call limit; each key remains subject to CU rate and burst limits, as described in the JSON-RPC documentation.

2. URL structure and the {chain} parameter

Every chain-scoped request specifies its target network in the URL path using {chain}. The {chain} parameter is the lowercase slug identifier of the chain (for example robinhood_mainnet).

ServiceAuthenticationURL templateDescription
JSON-RPCKey in URL pathPOST /v1/{chain}/{api_key}Simplest form, suitable for curl and HTTP clients
JSON-RPCKey in request headerPOST /v1/{chain}Pass key via x-api-key: {api_key} request header
Data APIREST routesGET /v1/data/{chain}/…Pass key via x-api-key: {api_key} request header
Public chain listUnauthenticatedGET /v1/chainsPublic list of chains and static facts (not billed, not rate-limited)
Public statusUnauthenticatedGET /v1/statusCurrent service status and chain heads (not billed, not rate-limited)

GET /v1/chains reports a jsonrpc and a data flag for each chain. Address a chain with the JSON-RPC URLs when it serves JSON-RPC, and with GET /v1/data/{chain}/… when its data flag is true (the Data API serves only those chains).

Tip: When passing your key via request headers, format the URL to end with the chain name, without a trailing slash. JSON-RPC is served exclusively at /v1/{chain} and /v1/{chain}/{api_key}. Requests with a trailing slash (such as /v1/{chain}/) or missing a chain segment return HTTP 404 with an empty body. Requests to an unknown {chain} return HTTP 404 with error.data.reason: "unknown_chain" (evaluated before reading the request body or key check, not billed, and not rate-limited).

3. Programmatic chain discovery and capabilities

Supported chains and their capabilities are served dynamically. Do not hardcode a static list of chains in your application. Instead, discover available networks and their capabilities at runtime:

Discover static facts via GET /v1/chains

This public endpoint is unauthenticated, not billed, and not rate-limited, returning all publicly available chains:

GET /v1/chains

Example response (from OpenAPI specification):

{
  "chains": [
    {
      "chain": "robinhood_mainnet", "name": "Robinhood Chain", "chain_id": 4663,
      "jsonrpc": true,
      "data": true,
      "methods": {
        "allow": ["eth_*", "net_*", "web3_*", "debug_trace*"],
        "deny": ["eth_newFilter", "eth_newBlockFilter", "eth_newPendingTransactionFilter", "eth_getFilterLogs", "eth_getFilterChanges", "eth_uninstallFilter", "eth_subscribe", "eth_unsubscribe"]
      },
      "max_logs_block_range": 1000,
      "state_window_blocks": 900,
      "info": {}
    }
  ]
}

Field reference:

  • chain: Chain identifier slug (used for {chain} in URLs)
  • name: Human-readable display name
  • chain_id: EIP-155 chain ID (decimal integer)
  • jsonrpc: Whether JSON-RPC is enabled
  • data: Whether the Data API is enabled
  • methods: JSON-RPC method policy for the chain, including allow (allowed methods or prefix wildcards) and deny (explicitly denied methods)
  • max_logs_block_range: Maximum block range allowed in a single eth_getLogs request
  • state_window_blocks: Historical state window size in blocks; null for full-history archive chains
  • info: Reserved object for extended network information

Check operational health via GET /v1/status

This public endpoint is unauthenticated, not billed, and not rate-limited, returning service readiness and chain head information:

GET /v1/status

Example response (from OpenAPI specification):

{
  "checked_at": "2026-09-28T12:00:00Z",
  "gateway": {
    "status": "ok"
  },
  "chains": [
    {
      "chain": "robinhood_mainnet", "name": "Robinhood Chain", "chain_id": 4663,
      "jsonrpc": true,
      "data": true,
      "data_features": ["blocks", "transactions", "address_transactions", "transfers", "token_metadata", "freshness"],
      "status": "ok",
      "head": {
        "block": 73017329,
        "time": "2026-09-28T11:59:58Z",
        "lag_seconds": 2
      }
    }
  ]
}

Field reference:

  • gateway.status: Service readiness status (ok or degraded)
  • chains[].data_features: Capabilities provided by the Data API for this chain
  • chains[].status: Node operational status (ok or unavailable)
  • chains[].head: Most recently polled block head (block, time, lag_seconds)

4. Per-chain differences to keep in mind

When switching between chains, review the fields provided in the specification and GET /v1/chains:

  1. Method allowance and policy (methods.allow / methods.deny): Available JSON-RPC methods vary by network according to their method policy. Requesting a disallowed method returns HTTP 200 with JSON-RPC error code -32601 (method not available, not billed).
  2. Log block range (max_logs_block_range): Maximum block spans for eth_getLogs queries differ by chain. Exceeding the chain's limit returns HTTP 200 with JSON-RPC error code -32602 (eth_getLogs block range too large, not billed).
  3. State retention window (state_window_blocks): Full-history chains return null. On chains with state pruning, historical state queries outside the window return HTTP 200 with JSON-RPC error code -32011 (historical state is not available beyond the most recent <N> blocks, not billed).
  4. Data API features and coverage (data / data_features): The chains that provide a dataset are listed on the Supported Chains page. Querying a dataset a chain does not support, or a block before its indexed coverage, returns HTTP 422 (error.code no_coverage, not billed). When the service is temporarily unavailable — for example, when a chain is busy — requests return HTTP 503 with a Retry-After header (not billed).

5. Code examples

The exact same code runs across different chains by updating the chain variable (or reading it from GET /v1/chains), querying eth_blockNumber via JSON-RPC and dataset freshness via the Data API:

export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# Change the chain variable to target another chain from Supported Chains
CHAIN="robinhood_mainnet"

# 1. JSON-RPC: Query eth_blockNumber (POST /v1/{chain}, key in the x-api-key header).
# The default-chain endpoint ends with its chain slug; swap that last segment for $CHAIN.
RPC_URL="https://dev-api.blockvectra.network/v1/robinhood_mainnet"
RPC_URL="${RPC_URL%/*}/$CHAIN"
curl -s "$RPC_URL" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

# 2. Data API: Query dataset freshness (GET /v1/data/{chain}/status/freshness)
curl -s "https://dev-api.blockvectra.network/v1/data/$CHAIN/status/freshness" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

Example responses (from specifications)

JSON-RPC eth_blockNumber successful response (billed at the method's CU weight):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x45a27f1"
}

Data API GET /v1/data/{chain}/status/freshness successful response (billed in CU, only 2xx successful responses are billed):

{
  "data": [
    {
      "dataset": "blocks",
      "category": "raw",
      "max_block_number": 72313256,
      "max_day": null,
      "max_time": "2026-09-28T03:41:07Z",
      "seconds_behind": 0,
      "blocks_behind": 0,
      "days_behind": null,
      "checked_at": "2026-09-28T03:41:10Z"
    },
    {
      "dataset": "traces",
      "category": "raw",
      "max_block_number": 72313256,
      "max_day": null,
      "max_time": "2026-09-28T03:41:07Z",
      "seconds_behind": 0,
      "blocks_behind": 0,
      "days_behind": null,
      "coverage_from_block": 72050949,
      "coverage_to_block": 72313256,
      "coverage_complete": true,
      "checked_at": "2026-09-28T03:41:10Z"
    },
    {
      "dataset": "dex_prices",
      "category": "derived",
      "max_block_number": null,
      "max_day": "2026-09-27",
      "max_time": "2026-09-27T00:00:00Z",
      "seconds_behind": 99667,
      "blocks_behind": null,
      "days_behind": 1,
      "checked_at": "2026-09-28T03:41:10Z"
    }
  ],
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72313256,
    "finalized_block": 72313000,
    "coverage": "full",
    "refreshed_at": "2026-09-28T03:41:10Z"
  }
}

On this page