---
title: "Whole-Block Subscription (blockreq_newBlocks)"
description: "Receive every new block with all its transactions over WebSocket, with no extra block fetch after each chain head"
url: "https://blockreq.com/docs/build/blockreq-new-blocks/"
---

# Whole-Block Subscription (blockreq_newBlocks)

`blockreq_newBlocks` is a BlockReq subscription type for `eth_subscribe`. Each time the chain produces a block, you receive one standard `eth_subscription` notification whose `params.result` is the whole block with full transaction objects. It is the same object `eth_getBlockByHash(hash, true)` returns, with every field passed through as the node produced it.

It replaces the usual two-step loop: subscribe to `newHeads`, then call `eth_getBlockByHash` for every head you receive.

This is a BlockReq extension, not an Ethereum standard subscription. The built-in block listeners of ethers and viem do not use it, so send a raw `eth_subscribe` as in the examples below.

## Supported chains

Available on the mainnets served by BlockReq's own nodes. Every other chain, and every testnet, refuses the subscription.

| Chain            | Chain ID | WSS endpoint                                           |
| ---------------- | -------- | ------------------------------------------------------ |
| Ethereum         | `1`      | `wss://ethereum-rpc.blockreq.com/v1/rpc/BRQ1P0000000000000000000000000000000000000000000000000000000`     |
| Base             | `8453`   | `wss://base-rpc.blockreq.com/v1/rpc/BRQ1P0000000000000000000000000000000000000000000000000000000`         |
| Arbitrum One     | `42161`  | `wss://arbitrum-one-rpc.blockreq.com/v1/rpc/BRQ1P0000000000000000000000000000000000000000000000000000000` |
| BNB Smart Chain  | `56`     | `wss://bsc-rpc.blockreq.com/v1/rpc/BRQ1P0000000000000000000000000000000000000000000000000000000`          |
| Robinhood        | `4663`   | `wss://robinhood-mainnet-rpc.blockreq.com/v1/rpc/BRQ1P0000000000000000000000000000000000000000000000000000000` |
| Arc              | `5042`   | `wss://arc-rpc.blockreq.com/v1/rpc/BRQ1P0000000000000000000000000000000000000000000000000000000`          |

The subscription needs an endpoint with an API key. The public endpoint (`/v1/rpc/public`) refuses it.

## Subscribe

Send exactly one parameter, `"blockreq_newBlocks"`, written exactly like that. Any other shape is an `invalid params` error.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_subscribe",
  "params": ["blockreq_newBlocks"]
}
```

The response carries the subscription ID, as for every other subscription:

```json
{ "jsonrpc": "2.0", "id": 1, "result": "0x9a1c3f0e5b7d2a48c6e1f3b5d7a9c2e4" }
```

Each new block then arrives as a notification. The example is shortened: values are illustrative, `logsBloom` is cut, and the transaction list holds one of the block's transactions.

```json
{
  "jsonrpc": "2.0",
  "method": "eth_subscription",
  "params": {
    "subscription": "0x9a1c3f0e5b7d2a48c6e1f3b5d7a9c2e4",
    "result": {
      "number": "0x1312d00",
      "hash": "0x5e1c0b7c2c4f0a9d6b3e8f21a7d4c9b05e6f1a2b3c4d5e6f708192a3b4c5d6e7",
      "parentHash": "0x3b9f4a1d8c7e6052f1a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f809",
      "timestamp": "0x6745a9c3",
      "miner": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97",
      "gasLimit": "0x1c9c380",
      "gasUsed": "0xb71b00",
      "baseFeePerGas": "0x3b9aca00",
      "logsBloom": "0x00a1…0004",
      "transactionsRoot": "0x7a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
      "stateRoot": "0x1f2e3d4c5b6a79880716253443526170899a8b7c6d5e4f30211203f4e5d6c7b8",
      "receiptsRoot": "0x9c8b7a69584736251403f2e1d0c9b8a7968574635241302f1e0d1c2b3a495867",
      "transactions": [
        {
          "hash": "0xa1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90",
          "blockHash": "0x5e1c0b7c2c4f0a9d6b3e8f21a7d4c9b05e6f1a2b3c4d5e6f708192a3b4c5d6e7",
          "blockNumber": "0x1312d00",
          "transactionIndex": "0x0",
          "from": "0x00000000219ab540356cbb839cbe05303d7705fa",
          "to": "0xdac17f958d2ee523a2206206994597c13d831ec7",
          "type": "0x2",
          "nonce": "0x2a",
          "gas": "0x186a0",
          "maxFeePerGas": "0x77359400",
          "maxPriorityFeePerGas": "0x59682f00",
          "value": "0x0",
          "input": "0xa9059cbb…",
          "chainId": "0x1",
          "accessList": []
        }
      ],
      "uncles": []
    }
  }
}
```

Which fields appear depends on the chain and its latest hard fork: the notification carries what the node returns for `eth_getBlockByHash(hash, true)`, including any chain-specific extension fields.

Cancel with `eth_unsubscribe`, passing the subscription ID:

```json
{ "jsonrpc": "2.0", "id": 2, "method": "eth_unsubscribe", "params": ["0x9a1c3f0e5b7d2a48c6e1f3b5d7a9c2e4"] }
```

## Examples

Replace `BRQ1P0000000000000000000000000000000000000000000000000000000` with your endpoint key, here read from the `BLOCKREQ_API_KEY` environment variable.

### wscat

```bash
npx wscat -c "wss://ethereum-rpc.blockreq.com/v1/rpc/$BLOCKREQ_API_KEY" \
  -x '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["blockreq_newBlocks"]}' -w 60
```

### Node.js

Node.js 22 or later, no packages needed:

```js
const ws = new WebSocket(`wss://ethereum-rpc.blockreq.com/v1/rpc/${process.env.BLOCKREQ_API_KEY}`);

ws.addEventListener("open", () => {
  ws.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_subscribe", params: ["blockreq_newBlocks"] }));
});

let lastNumber = null;
ws.addEventListener("message", (event) => {
  const message = JSON.parse(event.data);
  if (message.error) {
    console.error(message.error.code, message.error.message);
    ws.close();
    return;
  }
  if (message.method !== "eth_subscription") {
    console.log("subscription id:", message.result);
    return;
  }
  const block = message.params.result;
  const number = Number(block.number);
  if (lastNumber !== null && number > lastNumber + 1) {
    console.warn(`blocks ${lastNumber + 1}..${number - 1} were not pushed; fetch them with eth_getBlockByNumber`);
  }
  lastNumber = number;
  console.log(number, block.hash, `${block.transactions.length} transactions`);
});
```

### Python

Python 3.9 or later with `pip install websockets`:

```python
import asyncio
import json
import os

import websockets

URL = f"wss://ethereum-rpc.blockreq.com/v1/rpc/{os.environ['BLOCKREQ_API_KEY']}"

async def main() -> None:
    async with websockets.connect(URL, max_size=None) as ws:
        await ws.send(json.dumps({"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["blockreq_newBlocks"]}))
        last_number = None
        async for raw in ws:
            message = json.loads(raw)
            if "error" in message:
                print(message["error"]["code"], message["error"]["message"])
                return
            if message.get("method") != "eth_subscription":
                print("subscription id:", message["result"])
                continue
            block = message["params"]["result"]
            number = int(block["number"], 16)
            if last_number is not None and number > last_number + 1:
                print(f"blocks {last_number + 1}..{number - 1} were not pushed; fetch them with eth_getBlockByNumber")
            last_number = number
            print(number, block["hash"], f"{len(block['transactions'])} transactions")

asyncio.run(main())
```

`max_size=None` lifts the default 1 MiB message limit of the `websockets` library, which an Ethereum block can exceed.

## Errors

A refused subscription is not counted as a Request.

| Code     | When                                                                                        | What to do                                                                                  |
| -------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `-32601` | The chain does not offer the subscription, or the connection has no API key (public endpoint). The message is `subscription blockreq_newBlocks is not available on this network or endpoint`. | Use one of the [supported chains](#supported-chains) with a keyed endpoint. |
| `-32000` | The subscription capacity of this network is full for the moment. The message starts `blockreq_newBlocks subscriptions are temporarily unavailable on this network` and suggests trying again later. | Subscribe again a little later.                                                             |

## Request Counting

- `eth_subscribe` counts **1** Request, like any request.
- Each whole-block notification delivered to you counts **2** Requests: the `newHeads` notification it replaces, plus the block fetch you would otherwise send. A block you are not sent costs nothing.
- Refused subscriptions count nothing.

See [Request Counting](https://blockreq.com/docs/pricing/request-counting/index.md) for the general rule.

## Reorgs and gaps

The subscription follows `newHeads`:

- After a reorg, the replacing blocks are pushed as they arrive, so you can receive two blocks with the same `number`. Use `number` and `parentHash` to decide which blocks are on your chain.
- If the node cannot give a block's contents in time, that block is not pushed and you see the block number jump. A skipped block is not sent later, and nothing is replayed after you connect again. If you need every block, compare each `number` with the previous one and fetch the missing blocks with `eth_getBlockByNumber`.

## Message size

A whole block is far larger than a head. An Ethereum block is roughly 0.5-0.7 MB of JSON, a BNB Smart Chain block about 0.1 MB, and a block on the other chains a few KB to a few tens of KB. Messages are not compressed. A client that reads too slowly is disconnected, as for every other subscription, so read messages as they arrive and do heavy work off the socket loop.

## Compared with newHeads

| | `newHeads` | `blockreq_newBlocks` |
| --- | --- | --- |
| Standard Ethereum subscription | Yes | No, a BlockReq extension |
| Notification | Block header | Whole block with full transaction objects |
| Getting the transactions | A second call to `eth_getBlockByHash` per head | In the notification |
| Requests per notification | 1 | 2 |
| Chains | Every chain with WSS | The [six listed above](#supported-chains) |
| Access | Public endpoint or keyed endpoint | Keyed endpoint only |
| Message size | A header | The whole block, up to about 0.7 MB |

Use `newHeads` when you only need to know that a block exists. Use `blockreq_newBlocks` when you read the block's transactions for each new block.
