Quickstart

Use a free blockchain RPC API with no API key: read a block height keyless, then create a key for authenticated calls and webhooks.

Developers and AI agents can use this free blockchain RPC API with no API key: try the public RPC without a key, then create a key to continue.

1. Read a block height without a key

Call the public JSON-RPC endpoint for the example chain without creating an account or providing an API key:

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet/public" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

The response's id: 1 matches this request; result is a hexadecimal block height and can change between calls. If the response contains error, check its code and reason. See free public RPC endpoints for public methods, history ranges and per-IP limits.

2. Create an API key

Go to the console, log in with GitHub, Google or an Ethereum wallet (your account is created on first login), and create an API key. The secret is only displayed once: store it securely and set it as the environment variable BLOCKVECTRA_API_KEY. Keep it out of client-side browser code. New accounts get 30,000,000 CU on sign-up — no credit card.

No API key yet?

If you have an Ethereum wallet: follow the Programmatic sign-up guide to sign up and create an API key using an Ethereum wallet signature without a browser. If you do not have a wallet: ask the user to sign in at console.blockvectra.com, create a key, and set it as the environment variable BLOCKVECTRA_API_KEY. Do not ask the user to paste the key into the chat.

3. Send your first authenticated call

Read the same chain's block height with the x-api-key header. The URL ends with the chain name, without a trailing slash:

: "${BLOCKVECTRA_API_KEY:?Set BLOCKVECTRA_API_KEY first}"

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

result is again a hexadecimal block height. This request consumes CU; see the JSON-RPC reference for method weights and error codes, and Pricing for current prices. A new key takes effect in about 5 seconds; if you get invalid_api_key, wait a moment and retry. See Common errors below for other failures.

4. Continue with a business task

Reference

API keys and balance

Complete starter template: blockvectra/agent-quickstart

Every key looks like rgw_ followed by 64 hex characters, for example rgw_1f2e... (truncated). Keep it secret — anyone with the key can spend your balance.

When your balance is insufficient, the server returns HTTP 402 (JSON-RPC error code -32020; Data API error.code insufficient_balance). Go to the console Billing page to check your balance and top-up methods.

Try without a key

You can call the public JSON-RPC endpoint immediately without creating an account or providing an API key.

# Direct public endpoint:
curl -s "https://api.blockvectra.com/v1/robinhood_mainnet/public" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

# Or using the API key fallback pattern (defaults to public when BLOCKVECTRA_API_KEY is unset):
curl -s "https://api.blockvectra.com/v1/robinhood_mainnet/${BLOCKVECTRA_API_KEY:-public}" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

The endpoint in the example below is rate-limited per IP (3 req/s, burst 20, batch max 10). Requests that exceed rate limits return HTTP 429 with reason public_rate_limit or public_pool_busy (with a Retry-After header); unsupported methods return JSON-RPC error -32601 (method_not_public).

Public endpoints by chain

  • Arbitrum One: https://api.blockvectra.com/v1/arb_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Base: https://api.blockvectra.com/v1/base_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • BNB Smart Chain: https://api.blockvectra.com/v1/bsc_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Ethereum: https://api.blockvectra.com/v1/eth_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Ethereum Sepolia: https://api.blockvectra.com/v1/eth_sepolia/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Fraxtal: https://api.blockvectra.com/v1/fraxtal_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • HyperEVM: https://api.blockvectra.com/v1/hyperevm_mainnet/public — Read-only
  • Ink: https://api.blockvectra.com/v1/ink_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Katana: https://api.blockvectra.com/v1/katana_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Polygon: https://api.blockvectra.com/v1/polygon_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Robinhood Chain: https://api.blockvectra.com/v1/robinhood_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Robinhood Chain Testnet: https://api.blockvectra.com/v1/robinhood_testnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)
  • Unichain: https://api.blockvectra.com/v1/unichain_mainnet/public — Read and broadcast signed transactions (eth_sendRawTransaction)

The following two public metadata endpoints show service status and each chain's configuration; they require no API key and are not billed.

Check service and chain health status

curl https://api.blockvectra.com/v1/status

Returns the check timestamp checked_at, service operational status gateway.status, and each supported chain's node sync progress sync, head block height, and latency head:

{
  "checked_at": "2026-10-03T13:30:47Z",
  "gateway": {
    "status": "ok"
  },
  "chains": [
    {
      "chain": "bsc_mainnet",
      "name": "BNB Smart Chain",
      "chain_id": 56,
      "jsonrpc": true,
      "data": true,
      "data_features": [
        "blocks",
        "transactions",
        "address_transactions",
        "transfers",
        "token_metadata",
        "freshness"
      ],
      "data_status": "ok",
      "data_head_block": 125492675,
      "data_head_age_seconds": 3,
      "status": "ok",
      "sync": {
        "stage": "synced",
        "node_block": 125492676,
        "target_block": null
      },
      "head": {
        "block": 125492676,
        "time": "2026-10-03T13:30:45Z",
        "lag_seconds": 2
      }
    }
  ]
}

Query supported chains and method policies

curl https://api.blockvectra.com/v1/chains

Returns each supported chain's chain_id, capability flags for JSON-RPC, Data API, and WebSocket, method allow and deny policies (methods.allow and methods.deny), single-query log block range limit max_logs_block_range, and historical state window state_window_blocks:

{
  "chains": [
    {
      "chain": "bsc_mainnet",
      "name": "BNB Smart Chain",
      "chain_id": 56,
      "jsonrpc": true,
      "data": true,
      "ws": false,
      "subscriptions": [],
      "methods": {
        "allow": [
          "eth_blockNumber",
          "eth_call",
          "eth_chainId",
          "eth_getLogs"
        ],
        "deny": [
          "eth_newFilter",
          "eth_subscribe",
          "eth_unsubscribe"
        ]
      },
      "max_logs_block_range": 1000,
      "state_window_blocks": 100,
      "info": {}
    }
  ]
}

Choose a chain

Every BlockVectra endpoint is scoped to a chain: JSON-RPC requests carry the chain name {chain} in the URL path, and Data API requests prefix the route with it. See Supported Chains for the chains currently available and their identifiers.

Chain{chain}Chain IDTracingPublic EndpointWebSocketData APIMethods with an API keyWebhook pushSend TransactionsSend Transactions (Keyless Public Endpoint)State History Windoweth_getLogs Max Block RangeData API DatasetsRelated testnetsRelated guides
Arbitrum One RPC and Data APIarb_mainnet42161✓https://api.blockvectra.com/v1/arb_mainnet/publicSupported (newHeads, logs)Open43Supported · Confirmations 1–120 (default 120)
Webhook push guide
SupportedSupportedHistorical state for the most recent 5,000 blocks1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Data FreshnessUnknownUnknown
Base RPC and Data APIbase_mainnet8453—https://api.blockvectra.com/v1/base_mainnet/publicSupported (newHeads, logs)Open39Supported · Confirmations 1–519 (default 1)
Webhook push guide
SupportedSupportedHistorical state for the most recent 10,000 blocks1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Data FreshnessUnknownBase
BNB Smart Chain RPC and Data APIbsc_mainnet56—https://api.blockvectra.com/v1/bsc_mainnet/publicSupported (newHeads, logs)Open25Supported · Confirmations 1–2 (default 1)
Webhook push guide
SupportedSupportedHistorical state for the most recent 100 blocks1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Data FreshnessUnknownUnknown
Ethereum RPC and Data APIeth_mainnet1✓https://api.blockvectra.com/v1/eth_mainnet/publicSupported (newHeads, logs)Open38Supported · Confirmations 1–82 (default 6)
Webhook push guide
SupportedSupportedHistorical state for the most recent 250,000 blocks1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Data FreshnessUnknownUnknown
Ethereum Sepolia RPC and Data APIeth_sepolia11155111—https://api.blockvectra.com/v1/eth_sepolia/publicSupported (newHeads, logs)Open29Supported · Confirmations 1–67 (default 6)
Webhook push guide
SupportedSupportedUnknown1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Data FreshnessUnknownUnknown
Fraxtal RPCfraxtal_mainnet252—https://api.blockvectra.com/v1/fraxtal_mainnet/publicSupported (newHeads, logs)Not available yet39Not supportedSupportedSupportedHistorical state for the most recent 10,000 blocks1,000 blocksNot supportedUnknownUnknown
HyperEVM RPC and Data APIhyperevm_mainnet999—https://api.blockvectra.com/v1/hyperevm_mainnet/publicSupported (newHeads, logs)Open25Supported · Confirmations 1–1 (default 1)
Webhook push guide
SupportedNot supportedUnknown1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Balances, Holders, NFTs, Data FreshnessUnknownHyperEVM backfill and polling
Ink RPCink_mainnet57073—https://api.blockvectra.com/v1/ink_mainnet/publicSupported (newHeads, logs)Not available yet39Not supportedSupportedSupportedHistorical state for the most recent 60,000 blocks1,000 blocksNot supportedUnknownInk pool discovery
Katana RPCkatana_mainnet747474—https://api.blockvectra.com/v1/katana_mainnet/publicSupported (newHeads, logs)Not available yet39Not supportedSupportedSupportedHistorical state for the most recent 86,400 blocks1,000 blocksNot supportedUnknownUnknown
Polygon RPC and Data APIpolygon_mainnet137✓https://api.blockvectra.com/v1/polygon_mainnet/publicSupported (newHeads, logs)Open43Supported · Confirmations 1–200 (default 200)
Webhook push guide
SupportedSupportedHistorical state for the most recent 126 blocks1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Data FreshnessUnknownUnknown
Robinhood Chain RPC and Data APIrobinhood_mainnet4663✓https://api.blockvectra.com/v1/robinhood_mainnet/publicSupported (newHeads, logs)Open43Supported · Confirmations 1–1 (default 1)
Webhook push guide
SupportedSupportedHistorical state for the most recent 900 blocks1,000 blocksBlocks, Transactions, Address Transactions, Transfers, Token Metadata, Balances, Holders, NFTs, DEX Swaps, DEX Prices, Tokenized Stocks, Traces, Data FreshnessUnknownRobinhood Chain mainnet
Stock token multiplier

Tokenized stocks
Robinhood Chain Testnet RPCrobinhood_testnet46630✓https://api.blockvectra.com/v1/robinhood_testnet/publicSupported (newHeads, logs)Not available yet43Supported · Confirmations 1–1 (default 1)
Webhook push guide
SupportedSupportedHistorical state for the most recent 1,023 blocks1,000 blocksNot supportedUnknownTestnet faucet
Robinhood Chain Testnet starter
Unichain RPCunichain_mainnet130—https://api.blockvectra.com/v1/unichain_mainnet/publicSupported (newHeads, logs)Not available yet39Not supportedSupportedSupportedHistorical state for the most recent 85,500 blocks1,000 blocksNot supportedUnknownUnknown

Next steps with an API key

Arbitrum One

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/arb_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/arb_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/arb_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/arb_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Base

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/base_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/base_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/base_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/base_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

BNB Smart Chain

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/bsc_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/bsc_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/bsc_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/bsc_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Ethereum

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/eth_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/eth_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/eth_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/eth_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Ethereum Sepolia

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/eth_sepolia' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/eth_sepolia' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/eth_sepolia/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/eth_sepolia'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Fraxtal

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/fraxtal_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/fraxtal_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/fraxtal_mainnet'
WebSocket

Usage and CU · Top up

HyperEVM

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/hyperevm_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/hyperevm_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/hyperevm_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/hyperevm_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Ink

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/ink_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/ink_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/ink_mainnet'
WebSocket

Usage and CU · Top up

Katana

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/katana_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/katana_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/katana_mainnet'
WebSocket

Usage and CU · Top up

Polygon

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/polygon_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/polygon_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/polygon_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/polygon_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Robinhood Chain

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/robinhood_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/robinhood_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

Data API

curl -fsS 'https://api.blockvectra.com/v1/data/robinhood_mainnet/status/freshness' -H "x-api-key: $BLOCKVECTRA_API_KEY"
Data API

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/robinhood_mainnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Robinhood Chain Testnet

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/robinhood_testnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/robinhood_testnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/robinhood_testnet'
WebSocket

Create a Webhook subscription · Create a Webhook subscription · Usage and CU · Top up

Unichain

eth_getLogs

set -eu
MAX_LOGS_BLOCK_RANGE=1000
head=$(curl -fsS 'https://api.blockvectra.com/v1/unichain_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"],16))')
from=$((head >= MAX_LOGS_BLOCK_RANGE ? head - MAX_LOGS_BLOCK_RANGE + 1 : 0))
from_hex=$(printf '0x%x' "$from")
to_hex=$(printf '0x%x' "$head")
curl -fsS 'https://api.blockvectra.com/v1/unichain_mainnet' -H "x-api-key: $BLOCKVECTRA_API_KEY" -H 'Content-Type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"$from_hex\",\"toBlock\":\"$to_hex\"}]}"
eth_getLogs

WebSocket

echo '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}' | websocat --no-close -H="x-api-key: $BLOCKVECTRA_API_KEY" 'wss://api.blockvectra.com/v1/unichain_mainnet'
WebSocket

Usage and CU · Top up

HyperEVM

HyperEVM blocks include HyperCore system transactions (from address 0x2222…2222 or 0x20…, gasPrice 0).

JSON-RPC endpoint examples follow the example chain selection. The Data API examples below use robinhood_mainnet.

Tip: choose a chain that supports the example's service, method and history window in the matrix above, then replace robinhood_mainnet with its {chain}. The same API key works across all supported chains.

Other authentication options and language examples

JSON-RPC endpoints are scoped to a chain: POST /v1/{chain}/{api_key} with the key in the path, or POST /v1/{chain} with the key in the x-api-key header. {chain} is the chain name the Data API also uses; the example endpoint is https://api.blockvectra.com/v1/robinhood_mainnet. Calling eth_subscribe over HTTP returns -32601; WebSocket subscriptions are listed per chain in Supported Chains. The API sends Access-Control-Allow-Origin: *, but you should keep your API key secret and make requests from a backend service rather than client-side browser code.

You can pass the key in one of three ways: in the URL path (POST /v1/{chain}/{api_key}, which uses only the key in the path and ignores both headers), in the x-api-key header, or in an Authorization: Bearer <api_key> header.

Key in the URL path

: "${BLOCKVECTRA_API_KEY:?Set BLOCKVECTRA_API_KEY first}"

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet/$BLOCKVECTRA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

Key in a request header

: "${BLOCKVECTRA_API_KEY:?Set BLOCKVECTRA_API_KEY first}"

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

No trailing slash

When you pass the key in a header, call https://api.blockvectra.com/v1/robinhood_mainnet exactly as shown: the URL ends with the chain name, without a trailing slash. JSON-RPC is served only at /v1/{chain} and /v1/{chain}/{api_key}. A trailing slash (like /v1/{chain}/) or a request without a chain segment (like /v1 or /v1/) returns 404 with an empty body.

An Authorization: Bearer <api_key> header also works. On POST /v1/{chain}, a non-empty x-api-key takes precedence over Bearer, and Bearer is used only when x-api-key is absent or empty. The path form ignores both headers.

Batch calls

Send an array to make several calls in one request (up to 100 per batch). Note that each API key has a CU bucket (cu_per_sec refill, burst_cu capacity — defaults are 100 CU/s and burst 400 CU; after a paid top-up each key is at least 2,000 CU/s and burst 10,000 CU, and higher custom limits are kept; shown per key in the console Keys table); a single request — including a whole JSON-RPC batch — whose total CU exceeds the key's burst capacity is rejected with -32022 request_exceeds_burst, even under the 100-calls-per-batch limit; split it into smaller batches. This example reads the chain ID and an account balance in a single round trip:

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '[
    {"jsonrpc":"2.0","id":1,"method":"eth_chainId"},
    {"jsonrpc":"2.0","id":2,"method":"eth_getBalance","params":["0x1111111111111111111111111111111111111111","latest"]}
  ]'

Responses come back as an array, in the same order as the requests, matched by id.

If the server rejects the whole batch instead — insufficient balance, rate limiting, burst capacity, or an oversized batch (see Common errors below) — it returns a single JSON-RPC error object instead of an array; viem's batch: true mode then surfaces this as an opaque UnknownRpcError, so retry a single call to see the actual error.

Understand CU billing

Every billed call consumes Compute Units (CU): cheap calls like eth_blockNumber or eth_chainId cost the least, common reads like eth_getBlockByNumber cost a little more, heavier calls like eth_call or eth_getLogs cost more, and execution trace methods (such as debug_traceTransaction) cost the most. Usage is charged per account per hourly period, rounded down to whole billing units (1 unit = 1,000 CU), with the remainder carrying over to the next period (so across periods the total charged is floor(total CU / 1,000)); settlement runs about 15 minutes after the period ends. For example: 508 CU carried over + 2557 CU consumed = 3065 CU, resulting in 3 billing units charged and 65 CU carried over to the next period. See Pricing for current prices.

The full method-by-method weight table and error codes live in API Reference → JSON-RPC — this page only covers the shape of a request.

Common errors

What you didWhat comes backAction
Unknown or not yet public chainHTTP 404 with JSON body error.data.reason: "unknown_chain"Check the chain name in the URL
Request without a chain segment (e.g. /v1 or /v1/)HTTP 404 with an empty bodyInclude the chain name in the URL (/v1/{chain})
API key missing, unknown or disabledHTTP 401, JSON-RPC code -32024 (missing_api_key or invalid_api_key)Use a valid, active API key (brand-new or rotated keys take effect on every instance within about 5 seconds; during this time they may return 401 invalid_api_key, or 503 -32021 (with Retry-After) when the billing state cannot be confirmed for the moment, so wait a moment and retry)
Balance is zero or negativeHTTP 402, JSON-RPC code -32020Top up your balance or wait for the free refill
Sent requests too quickly (rate limit or temporary overload)HTTP 429 (or 200), JSON-RPC code -32005Retry later (honour Retry-After when present)
Single request or batch exceeds key burst capacity (burst_cu, default 400 CU; default rate 100 CU/s) (paid accounts: at least 10,000 CU burst, 2,000 CU/s)HTTP 429, JSON-RPC code -32022 (request_exceeds_burst)Split the request into smaller batches (can never succeed as sent)
Free-plan batch exceeds the per-second call-count limit (25 calls/s)HTTP 429, JSON-RPC code -32022 (free_plan_batch_too_large), with error.data.maxSplit the batch to fit the call-count limit (can never succeed as sent)
Upstream node is temporarily unavailableHTTP 200, JSON-RPC code -32603 (upstream unavailable), not billedRetry the request
Historical state outside this chain's state window (see state_window_blocks in GET /v1/chains)HTTP 200, JSON-RPC code -32011, not billedQuery a more recent block
Transaction or block not found, or response too large; on Ethereum, block / receipt / log queries outside the recent window also return -32000 "old data not available due to pruning" (not billed; see Supported Chains → Ethereum)HTTP 200, JSON-RPC code -32000Change the request (verify hash or block number; malformed trace hashes return transaction not found)
Tracer not allowed, or trace timeout not allowed (debug_trace calls)HTTP 200, JSON-RPC code -32602, not billedUse an allowed native tracer (callTracer, flatCallTracer, prestateTracer, 4byteTracer, noopTracer, or omit) and timeout ≤ 30s
A method the chain's method list does not allow (see Supported Chains)HTTP 200, JSON-RPC code -32601, not billedCall only methods the chain allows
Malformed JSON bodyHTTP 200, JSON-RPC code -32700, not billedFix request JSON syntax
More than 100 calls in one batchHTTP 200, JSON-RPC code -32600 (batch too large), not billedSplit the batch into at most 100 calls

For key-authenticated JSON-RPC requests, within these two limit checks, the free-plan call-count check precedes the key CU burst check. If both limits would reject the batch, the reason is free_plan_batch_too_large. Neither -32022 rejection includes Retry-After; split the request rather than retrying it unchanged.

The rejections above are never billed. Every accepted call that gets a response is charged at the method's published CU weight; the error-code table lists the cases that are not billed (see the Billed column in Error Codes).

Call the Data API

The Data API exposes read-only chain data (blocks, transactions, balances, holders, DEX activity, and more) as REST/JSON. Every route except GET https://api.blockvectra.com/v1/data/chains is prefixed with a chain identifier: robinhood_mainnet is the chain identifier (the chain field returned by /chains and in meta) used in every path below. GET https://api.blockvectra.com/v1/data/chains lists only public chains and returns only {"data": [...]} (no meta, no next_cursor). Requests are metered and billed in Compute Units (CU); only 2xx successful responses are billed.

Every request requires the same API key as JSON-RPC — pass it in the x-api-key header. Every chain-scoped success response contains data (the payload) and meta (chain, chain_slug (upper-case form of chain), chain_external_id, as_of_block, safe_block, finalized_block, coverage, refreshed_at; refreshed_at may be null, which means the update time of the data is unknown and it should be treated as stale — block-based endpoints always return a value). Paginated list endpoints may also return next_cursor (an opaque string, never null). Pass a returned cursor back unchanged and continue until next_cursor is absent; some endpoints return an optimistic cursor after a full page, so the next page may be empty. Check the Data API reference for each endpoint's pagination support. Error responses usually contain {"error":{"code","message"}} — 409 not_indexed_yet adds indexed_through (the highest indexed block). An unknown or not-public chain returns HTTP 404 with error.code not_found (not billed; chain names must be exact lowercase slugs); a missing, unknown, or disabled API key returns HTTP 401 with error.code missing_api_key or invalid_api_key. Rate-limited requests return HTTP 429 (error.code rate_limited, data.reason: "key_rate_limit"), and exhausted balance returns HTTP 402 (error.code insufficient_balance); both are not billed. Values that can exceed 2^53 (balances, token amounts) are decimal strings, never JSON numbers.

Look up a block by number:

curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/72838701" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
{
  "data": {
    "number": 72838701,
    "hash": "0x9f2c1e7a4b6d3f805e1c9a72b4d6f1e0a3c8b5d7e2f4a1c6b9d3e7f0a2c4b6d8",
    "parent_hash": "0x1a3c5e7f9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a",
    "timestamp": "2026-09-26T05:41:07Z",
    "miner": "0x00000000000000000000000000000000000a4b05",
    "gas_limit": 32000000,
    "gas_used": 4821932,
    "base_fee_per_gas": "100000000",
    "state_root": "0x2b4d6f8a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d",
    "transactions_root": "0x3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e",
    "receipts_root": "0x4d6f8a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f",
    "tx_count": 239,
    "size": 48213,
    "l1_block_number": null,
    "extra": {}
  },
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72838957,
    "safe_block": 72838800,
    "finalized_block": 72838701,
    "coverage": "full",
    "refreshed_at": "2026-09-27T02:15:03Z"
  }
}

A number above the indexed head (as_of_block) is 409 (error.code: "not_indexed_yet") with indexed_through telling you the highest indexed block — the data isn't there yet, so retry later. A block number entirely before the chain's covered history (coverage.from_block) returns 422 (error.code: "no_coverage"). Within coverage, a number at or below as_of_block with no live row (never indexed, or rolled back by a reorg) is 404 (error.code: "not_found").

Check data freshness (how far each tracked dataset lags behind the chain head — useful for a status page or a pre-flight check before you trust a query):

curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/status/freshness" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
{
  "data": [
    {
      "dataset": "blocks",
      "category": "raw",
      "max_block_number": 72838957,
      "max_day": null,
      "max_time": "2026-09-27T02:15:01Z",
      "seconds_behind": 0,
      "blocks_behind": null,
      "days_behind": null,
      "checked_at": "2026-09-27T02:15:07Z"
    }
  ],
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72838957,
    "safe_block": 72838800,
    "finalized_block": 72838701,
    "coverage": "full",
    "refreshed_at": "2026-09-27T02:15:07Z"
  }
}

(Abridged: the response has one row per dataset; only the blocks row is shown. The traces row also carries coverage_from_block, coverage_to_block and coverage_complete.)

If freshness data is temporarily unavailable for this chain, this returns 503 (error.code: "unavailable") instead of a partial result; the response carries a Retry-After header (seconds) — wait at least that long, then retry.

List an address's ERC-20 balances (a snapshot filtered to non-zero balances, ordered by token):

curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
{
  "data": [
    { "token": "0x0bd7d308f8e1639fab988df18a8011f41eacad73", "balance": "185371464119396", "symbol": "WETH", "decimals": 18 },
    { "token": "0x2295f15bd4914ae9b4685f01d52f4e6f89bf8b03", "balance": "10000000000000000", "symbol": "WNVDA", "decimals": 18 }
  ],
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72838957,
    "safe_block": 72838800,
    "finalized_block": 72838701,
    "coverage": "full",
    "refreshed_at": "2026-09-27T02:10:00Z"
  }
}

An address with no non-zero balances still returns 200 with data: [] — never 404. Pass ?limit= (default 50, max 500) and the returned next_cursor to page through more.

Full endpoint coverage — blocks, transactions, addresses, tokens, NFTs, DEX, tokenized stocks — is available in API Reference → Data API.

Further reading

FAQ

Which chains are supported?

13 chains are supported: Arbitrum One, Base, BNB Smart Chain, Ethereum, Ethereum Sepolia, Fraxtal, HyperEVM, Ink, Katana, Polygon, Robinhood Chain, Robinhood Chain Testnet, Unichain. The list follows GET /v1/chains and updates when new chains launch. See the status page for live status. See supported chains →

Is WebSocket supported?

Calling eth_subscribe over HTTP returns -32601; on chains where ws is true in /v1/chains, eth_subscribe is available over WebSocket. Otherwise, poll eth_getLogs. See supported chains →

Can I query historical state and traces?

Yes, but it varies by chain. The historical state window is the state_window_blocks field of /v1/chains (null means full history); whether traces are available depends on whether methods.allow for that chain includes debug_trace methods (such as debug_traceTransaction); the maximum block span for a single eth_getLogs request is max_logs_block_range. See the chain directory and per-chain parameters →

Can one API key be used on all chains?

Yes. One API key works for JSON-RPC on every supported chain and for the Data API on chains that offer it; a key belongs to the account, not to a specific chain. Read the one key, many chains guide →

Last updated:

On this page