Docs

chain_subscribeNewHeads - Kusama RPC Method

Subscribe to new block headers on Kusama. Real-time WebSocket notifications for every new block as it is produced — essential for monitoring, indexing, and event-driven applications on Polkadot's canary network for real-world testing with live economic conditions.

Subscribe to receive notifications when new block headers are produced on Kusama. This WebSocket subscription provides real-time, push-based updates for each new block, making it more efficient than polling.

Why Kusama? Build on Polkadot's canary network for real-world testing with live economic conditions with 7-day governance cycles (vs 1 month on Polkadot), lower bonding requirements, live KSM token economy, and first-to-market feature testing.

When to Use This Method

chain_subscribeNewHeads is essential for experimental dApp developers, parachain teams, and early adopters validating new features:

  • Block Monitoring — Track new blocks in real time on Kusama for parachain experimentation, early feature deployment, and production-grade testing with real value
  • Event Indexing — Trigger processing pipelines when new blocks arrive
  • Chain Synchronization — Keep external databases and systems in sync with the chain
  • Dashboard Updates — Push live block data to monitoring dashboards

Code Examples

Bash
# WebSocket subscription (requires wscat or similar tool)
wscat -c wss://kusama-rpc.n.dwellir.com -x '{
  "jsonrpc": "2.0",
  "method": "chain_subscribeNewHeads",
  "params": [],
  "id": 1
}'

Common Use Cases

1. Real-Time Block Indexer

Index new blocks and their events on Kusama as they arrive:

JavaScript
async function indexBlocks(api, onBlock) {
  const unsub = await api.rpc.chain.subscribeNewHeads(async (header) => {
    const blockHash = header.hash;
    const [block, events] = await Promise.all([
      api.rpc.chain.getBlock(blockHash),
      api.query.system.events.at(blockHash)
    ]);

    const blockData = {
      number: header.number.toNumber(),
      hash: blockHash.toHex(),
      parentHash: header.parentHash.toHex(),
      extrinsicCount: block.block.extrinsics.length,
      eventCount: events.length,
      timestamp: Date.now()
    };

    await onBlock(blockData);
  });

  return unsub;
}

2. Block Production Monitor

Detect block production delays on Kusama:

JavaScript
async function monitorBlockProduction(api, expectedBlockTimeMs = 6000) {
  let lastBlockTime = Date.now();
  const threshold = expectedBlockTimeMs * 3;

  const unsub = await api.rpc.chain.subscribeNewHeads((header) => {
    const now = Date.now();
    const elapsed = now - lastBlockTime;

    if (elapsed > threshold) {
      console.warn(
        `Block #${header.number}: ${elapsed}ms since last block (expected ~${expectedBlockTimeMs}ms)`
      );
    } else {
      console.log(`Block #${header.number}: ${elapsed}ms`);
    }

    lastBlockTime = now;
  });

  return unsub;
}

3. Live Dashboard Feed

Stream block data to a WebSocket-connected frontend:

JavaScript
async function streamToClients(api, wss) {
  const unsub = await api.rpc.chain.subscribeNewHeads(async (header) => {
    const message = JSON.stringify({
      type: 'new_block',
      number: header.number.toNumber(),
      hash: header.hash.toHex(),
      parentHash: header.parentHash.toHex(),
      stateRoot: header.stateRoot.toHex()
    });

    wss.clients.forEach((client) => {
      if (client.readyState === 1) {
        client.send(message);
      }
    });
  });

  return unsub;
}

Subscription vs Polling

ApproachLatencyResource UsageUse Case
subscribeNewHeadsImmediateLow (push-based)Real-time monitoring, indexing
Polling getHeaderBlock time + poll intervalHigher (repeated requests)Simple integrations, HTTP-only

Error Handling

Error CodeDescriptionSolution
-32603Internal errorNode may be syncing — retry connection
-32601Method not foundVerify the node supports WebSocket subscriptions
-32005Rate limit exceededReduce subscription count per connection
Connection closedWebSocket disconnectedImplement automatic reconnection with backoff