Skip to content

WebSockets

Live subscription streaming over WebSocket:

wss://rpc.au.ro/ws/<chain>?apikey=<YOUR_API_KEY>

The handshake is authenticated exactly like an HTTPS request; after the upgrade the connection is a transparent pipe to the chain node's own WebSocket endpoint — you speak each chain's native subscription protocol (matrix below), not a platform-invented event format.

Authentication

Two ways to present the same API key (Authentication):

  • Query parameter?apikey=<YOUR_API_KEY>. The browser form: the WebSocket() constructor can't set headers. URLs tend to end up in logs, so prefer the header wherever you control the client.
  • apikey header — non-browser clients (wscat, Node ws, Go, Python) send it on the handshake request instead:
bash
npx wscat -H "apikey: $YOUR_API_KEY" -c wss://rpc.au.ro/ws/eth

Handshakes are rate-limited per key (~10/min — it bounds reconnect storms, not open streams). Frames on an established stream are not metered as CU: the handshake is gated, the stream itself is free.

Chain matrix

ChainWS endpointSubscription API
Ethereum/ws/etheth_subscribenewHeads, logs, newPendingTransactions
BNB Smart Chain/ws/bsceth_subscribe — same surface as Ethereum
Polygon/ws/polygoneth_subscribe — same surface as Ethereum
Avalanche C-Chain/ws/avaxeth_subscribe (C-Chain EVM)
Solana/ws/solanapubsub — slotSubscribe, accountSubscribe, logsSubscribe
Cosmos Hub/ws/cosmosCometBFT JSON-RPC subscribe (tm.event='NewBlock')
XRP Ledger/ws/xrpnative XRPL WebSocket API (subscribe command) — WS is XRPL's primary transport
Cardano/ws/cardanoOgmios JSON-RPC over WS — chainSync, ledger-state queries

Chains not in the table (Bitcoin family, NEAR, Stellar, Sui, Aptos, TON) have no public WebSocket — /ws/<chain> answers an honest 404 for them, and webhooks / cached polling cover those event needs.

Project chain scoping applies to WS exactly as to HTTPS: a key scoped away from a chain gets 403 on the handshake.

Subscribe examples

EVM — eth_subscribe (eth / bsc / polygon / avax)

bash
npx wscat -c "wss://rpc.au.ro/ws/eth?apikey=$YOUR_API_KEY"
> {"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}
< {"jsonrpc":"2.0","id":1,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}
< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x9ce5...","result":{"number":"0x18213bb",...}}}

Or let ethers manage the socket:

js
import { ethers } from 'ethers'

const provider = new ethers.WebSocketProvider(
  `wss://rpc.au.ro/ws/eth?apikey=${process.env.YOUR_API_KEY}`
)
provider.on('block', (n) => console.log('new block', n))

logs subscriptions take the same filter object as eth_getLogs ({"address":"0x...","topics":[...]} as the second param); newPendingTransactions streams mempool hashes.

Solana — pubsub

bash
npx wscat -c "wss://rpc.au.ro/ws/solana?apikey=$YOUR_API_KEY"
> {"jsonrpc":"2.0","id":1,"method":"slotSubscribe"}
< {"jsonrpc":"2.0","result":1,"id":1}
< {"jsonrpc":"2.0","method":"slotNotification","params":{"result":{"parent":371980276,"root":371980244,"slot":371980277},"subscription":1}}

accountSubscribe, logsSubscribe, signatureSubscribe work the same way — the full Solana pubsub API.

Cosmos Hub — CometBFT events

bash
npx wscat -c "wss://rpc.au.ro/ws/cosmos?apikey=$YOUR_API_KEY"
> {"jsonrpc":"2.0","id":1,"method":"subscribe","params":{"query":"tm.event='NewBlock'"}}

Every new block arrives as a JSON-RPC notification. Other queries: tm.event='Tx', tm.event='ValidatorSetUpdates', or attribute matches like tm.event='Tx' AND transfer.recipient='cosmos1...'.

XRP Ledger — native XRPL API

WebSocket is XRPL's primary transport — xrpl.js's Client connects directly:

js
import { Client } from 'xrpl'

const client = new Client(`wss://rpc.au.ro/ws/xrp?apikey=${process.env.YOUR_API_KEY}`)
await client.connect()
await client.request({ command: 'subscribe', streams: ['ledger'] })
client.on('ledgerClosed', (l) => console.log('ledger', l.ledger_index))

Raw frame form: {"id":1,"command":"subscribe","streams":["ledger"]} — plus transactions, or accounts: ["r..."] for per-account activity.

Cardano — Ogmios over WS

The same Ogmios JSON-RPC the HTTPS endpoint serves, plus the chain-synchronization protocol that only works on a stream:

bash
npx wscat -c "wss://rpc.au.ro/ws/cardano?apikey=$YOUR_API_KEY"
> {"jsonrpc":"2.0","method":"queryNetwork/tip","id":1}
> {"jsonrpc":"2.0","method":"nextBlock","id":2}

(nextBlock drives chainSync: first responses roll back to an intersection, then stream blocks forward — see the Ogmios docs.)

Keeping the stream alive & reconnecting

  • The gateway pings the client every 30 s — reply with pongs (every mainstream WS library does this automatically) or the connection is reaped as dead.
  • Idle is fine: a quiet subscription is kept open for hours; you don't need application-level keepalive chatter.
  • Reconnect with backoff + jitter and treat it as routine: node restarts, rollouts and failovers close streams. Handshakes are rate-limited (~10/min per key), so a hot reconnect loop locks you out — back off exponentially (1 s → 2 s → 4 s … cap ~30 s).
  • Re-subscribe after every reconnect. Subscription IDs live on one connection; a new socket starts empty.
  • Expect a gap: events emitted while you were disconnected are not replayed. On reconnect, backfill via HTTPS (eth_getLogs, getBlock, …) from the last item you processed.

When webhooks fit better

For "react to chain activity" workloads that must survive your process restarts, webhooks deliver new_block / address_activity events to your HTTPS endpoint with signed payloads and retries — no connection for you to babysit. WS is the right tool for low-latency streams (mempool, account/log firehose) and for chains where the native protocol is subscription-shaped (XRPL, Ogmios chainSync).