Best practices

Fewer requests, fewer surprises: batch, retry politely, page through logs and keep your tokens safe.

Contents
Chains, regions and plans open one by one when enough teams ask for them. These docs describe exactly how they work. What is open

Batch independent calls

Up to 100 calls in one request. Fewer round trips, the same credits.

  • viem: http(url, { batch: { batchSize: 100 } }) (viem’s default batch is larger than 100 calls). ethers v6 batches calls made within a few milliseconds of each other by default (batchStallTime), up to 100 per batch. web3.py: w3.batch_requests().
  • Each call counts against your requests per second, so very large batches can still answer rate_limited.
  • Results come back in the order you sent them, with your ids. One failing call does not fail the batch.

Retry 429 and 503 with backoff

Honour Retry-After when it is there; otherwise wait 0.5 s, 1 s, 2 s and so on, with a little random jitter.

// Retry 429 and 503 with Retry-After or exponential backoff (at most 5 tries).
async function rpc(body, tries = 5) {
  for (let i = 0; ; i++) {
    const res = await fetch(`https://rpc.blockmetric.io/eth/${process.env.BLOCKMETRIC_RPC_TOKEN}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
    })
    if ((res.status !== 429 && res.status !== 503) || i === tries - 1) return res.json()
    const wait = Number(res.headers.get('Retry-After')) * 1000 || Math.min(30_000, 500 * 2 ** i)
    await new Promise((r) => setTimeout(r, wait + Math.random() * 250))
  }
}

Do not retry 4xx errors other than 429: they mean the request itself is wrong (error codes). Never retry eth_sendRawTransaction blindly; check the transaction hash first.

Page through eth_getLogs

One call covers at most 10,000 blocks (HyperEVM 50). Narrow by address and topics; step through long ranges.

import { createPublicClient, http, parseAbiItem } from 'viem'
import { mainnet } from 'viem/chains'

const client = createPublicClient({ chain: mainnet, transport: http(`https://rpc.blockmetric.io/eth/${process.env.BLOCKMETRIC_RPC_TOKEN}`) })
const transfer = parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)')

// Page through a long range in steps the chain allows (10,000 blocks; HyperEVM 50).
const STEP = 10_000n
for (let from = 19_000_000n; from <= 19_100_000n; from += STEP) {
  const logs = await client.getLogs({ address: '0x0000000000000000000000000000000000000000', event: transfer, fromBlock: from, toBlock: from + STEP - 1n })
  console.log(from, logs.length)
}

Keep tokens safe

  • One token per app and environment (production, staging, a script). You see usage per token and can revoke one without touching the others.
  • Browser apps: a token in front-end code is public. Set allowed origins on the token, so other sites cannot use it.
  • Servers: set an IP allowlist and keep the token in an environment variable such as BLOCKMETRIC_RPC_TOKEN.
  • Never commit a token to a public repository. If one leaked, rotate it on your dashboard: the old token stops working within a minute.
  • Never put an API key in a URL. Only RPC endpoint tokens (bmr_…) belong in an RPC URL.

Cache what does not change

  • Blocks, receipts and transactions deep below the head do not change: keep them on your side instead of asking again.
  • eth_chainId and net_version are free, but a fixed chain id in your client (ethers staticNetwork, a viem chain) saves the round trip.
  • Poll eth_blockNumber at most once per block time, or subscribe to newHeads over WebSocket instead of polling.
  • Your requests on one chain stay on the same node for 30 seconds, so "latest" does not jump back between two nodes.

Watch your usage

  • Every answer on a Global plan carries X-Blockmetric-Credits and X-Blockmetric-Credits-Remaining (dedicated throughput has no credits).
  • Your dashboard shows credits per chain and day, recent errors and the latency our gateway measured for your requests.
  • We e-mail you at 80 % and 100 % of your monthly credits. Overage is optional and always capped by you.

Code snippets in these docs are licensed under MIT-0: copy them into your own code without attribution. Use of Blockmetric RPC is governed by the terms. Independent infrastructure, not affiliated with the chains or their foundations.

LiveHyperliquid markets 5sOperationalHyperliquid positions & whales 4sOperationalLiquidation heatmap & levels 5sOperationalLighter markets & liquidations 10sOperationalLighter positions & heatmap 5sOperationalLighter RH positions & heatmap 4sOperationalBinance markets 1mOperationalBybit markets 31sOperationalBinance liquidations 10sOperationalBybit liquidations 10sOperationaldYdX positions & heatmap 10sOperationalGMX positions & heatmap 10sOperationalLong/short & open interest history 42sOperationalOrder books & trade flow 4sOperationalOn-chain transfers 5sOperationalSecurity monitor 58sOperationalBlockmetric Sentiment 1mOperationalOfficial news 4mOperationalAlert delivery 4sOperational10:12:59 UTCData: Blockmetric Research · Binance · Bybit