WebSockets
The same JSON-RPC over one WebSocket, plus eth_subscribe for new blocks and logs as they happen.
Contents
Connect
Browsers cannot send headers on a WebSocket, so the token is in the path.
wss://rpc.blockmetric.io/<chain>/YOUR_TOKENAvailable on Ethereum, Base, Arbitrum One, OP Mainnet, Polygon PoS, BNB Smart Chain, Avalanche C-Chain, HyperEVM, Sepolia, Base Sepolia and Arbitrum Sepolia. HyperCore is HTTPS only.
Subscribe
newHeads (one event per block) and logs (filter by address and topics). Any other JSON-RPC call works on the same connection.
import { createPublicClient, webSocket } from 'viem'
import { base } from 'viem/chains'
const url = `wss://rpc.blockmetric.io/base/${process.env.BLOCKMETRIC_RPC_TOKEN}`
const client = createPublicClient({ chain: base, transport: webSocket(url, { reconnect: true }) })
// One eth_subscribe("newHeads") under the hood; viem resubscribes after a reconnect.
const stop = client.watchBlocks({ onBlock: (block) => console.log(block.number, block.hash) })- logs filters: up to 16 addresses and 4 topics with up to 16 alternatives each. No block range: you get new logs from now on.
- Not offered: newPendingTransactions (mempool) and syncing.
- Unsubscribe with
eth_unsubscribeand the subscription id, or close the connection.
Reconnects and gaps
If our connection to a node drops, the gateway reconnects and subscribes again. Your connection stays open.
- newHeads: blocks you missed in between are sent in order (up to 128 blocks). After a longer gap you get the gap notice below.
- logs: you get one
blockmetric_gapnotification with the block range we could not watch. Re-read that range witheth_getLogs; nothing else is lost. - Your own reconnects: if your connection closes, reconnect with a growing delay (1 s, 2 s, 4 s, at most 30 s), subscribe again, and fill the gap with
eth_getLogsfrom the last block you processed.
{
"jsonrpc": "2.0",
"method": "blockmetric_gap",
"params": {
"subscription": "0x3f2a…",
"result": {
"fromBlock": "0x1312d00",
"toBlock": "0x1312d05"
}
}
}Credits
A subscription call costs 1 credit. Notifications cost 1 credit per started 4 KB of payload delivered on the connection, so a quiet subscription costs almost nothing.
Connections per plan
Open connections per account, all chains and tokens together. One more answers ws_limit (HTTP 429 on the upgrade).
| Plan | Connections |
|---|---|
| Free | 2 |
| Starter | 10 |
| Growth | 50 |
| Scale | 200 |
| Enterprise | 500 or by contract |
Messages you send count against the same requests per second as HTTPS. A client that stops reading is disconnected to protect the other connections.
Subscriptions per connection and close codes
- At most 50 subscriptions per connection; one more answers
ws_limit. Open another connection for more. - If a subscription cannot be started on our side, you get
blockmetric_subscription_failedwith its id: subscribe again. - We ping every 30 s and close a connection that stops answering. Open connections are checked every 15 s: a revoked token (it reaches the gateway within a minute) or used-up credits close them.
| Code | Reason |
|---|---|
| 4001 | The token was revoked or is no longer valid. Use a token from your dashboard. |
| 4029 | The monthly credits are used up (switch on overage or upgrade). |
| 1008 | Too many messages per second, or more than 4 MB waiting because the client stopped reading. |
| 1009 | A message larger than 256 KB. Split it into smaller batches. |
| 1003 | A binary frame. Send JSON-RPC as text frames. |
| 1001 | No answer to our pings, or the gateway restarts. Reconnect with a growing delay. |
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.