# blockSubscribe

> Streams full block contents as each block reaches the requested commitment (unstable upstream).

Source: https://docs.constant-k.com/rpc/websocket/blocksubscribe/

`blockSubscribe` pushes block data as it is produced, either for every block (`"all"`) or only blocks containing a transaction that mentions a given account or program (`{"mentionsAccountOrProgram": "<pubkey>"}`). Each notification's `value.block` is shaped like the block object `getBlock` would return for that slot, with the level of transaction detail controlled by `transactionDetails`. The config object must set `maxSupportedTransactionVersion`, currently `1`; see [Transaction v1](/rpc/transaction-v1/).

Upstream Agave marks `blockSubscribe` unstable and ships it disabled by default, gated behind `--rpc-pubsub-enable-block-subscription` plus `--enable-rpc-transaction-history`; constant-k runs both flags, so the subscription works normally here even though many public RPC providers don't expose it. Because it ships whole blocks, it is the heaviest of the subscription methods; `logsSubscribe` or a filtered `programSubscribe` cover cases needing only confirmation that something happened, not full transaction payloads.

- Transport: WebSocket, JSON-RPC 2.0 over `wss://ws-newyork.constant-k.com:1337/ws?api-key=YOUR_API_KEY`
- Category: Subscriptions
- Availability: Nexus only

## Parameters

`params` is a positional JSON array, in this order:

- `filter` (string | object, required): Which blocks to receive.
  - `option 1` (string, optional, one of `all`): Every block.
  - `option 2` (object, optional): Only blocks containing a transaction that references this address.
    - `mentionsAccountOrProgram` (string, required): Base58 account or program id.
- `config` (object, required): Subscription settings. Required here, because `maxSupportedTransactionVersion` must be set. Every other field in it is optional.
  - `commitment` (string, optional, one of `confirmed`, `finalized`, default `"finalized"`): `processed` is not accepted for `blockSubscribe`; only `confirmed` and `finalized` blocks can be streamed.
  - `encoding` (string, optional, one of `json`, `jsonParsed`, `base58`, `base64`, `base64+zstd`, default `"base64"`): Format for each transaction's `message` bytes inside the block payload (irrelevant when `transactionDetails` is `signatures` or `none`, since no transaction bodies are returned).
  - `transactionDetails` (string, optional, one of `full`, `accounts`, `signatures`, `none`, default `"full"`): How much per-transaction detail to include: full transactions, an accounts-only summary, bare signatures, or nothing beyond the block's own metadata.
  - `showRewards` (boolean, optional, default `false`): Whether to populate the block's `rewards` array.
  - `maxSupportedTransactionVersion` (integer, required, min 0, max 1): Highest transaction version the caller can decode. **Required on constant-k**: `blockSubscribe` is refused with `-32602` at subscribe time if it is missing. It is a ceiling, not a filter — `1` streams a block's legacy, version 0 and version 1 transactions alike, sent as the JSON integer `1` rather than the string `"1"`. See [Transaction v1](/rpc/transaction-v1/).

## Result

- `result` (integer, optional): The subscription id, returned once in the initial RPC response. Passed to `blockUnsubscribe`, it cancels the stream.

## Notifications

Updates arrive as `blockNotification` messages. `result.context.slot` and `result.value.slot` both name the block's slot; `result.value.err` is `null` on success or an error object if the node failed to fully replay the block (in which case `block` is `null`); `result.value.block` is the block payload itself, shaped by `transactionDetails`/`encoding`/`showRewards`.

- `params.result` (object, optional)
  - `context` (object, optional): Response context, including the slot the data was read at.
    - `slot` (integer, optional): Slot number this applies to.
  - `value` (object, optional): The requested data; see the fields below.
    - `slot` (integer, optional): Slot number this applies to.
    - `err` (object | null, optional): Null on success, or an error object/string describing the failure.
    - `block` (object | null, optional): The block payload, or null when `err` is set.
      - `blockhash` (string, optional): Base58 hash identifying this block.
      - `previousBlockhash` (string, optional): Base58 hash of this block's parent.
      - `parentSlot` (integer, optional): Slot of this block's parent.
      - `blockTime` (integer | null, optional): Estimated production time as a Unix timestamp, or null if unavailable.
      - `blockHeight` (integer | null, optional): Number of blocks beneath this one, or null if unavailable.
      - `signatures` (string[], optional): Present only when `transactionDetails` is `signatures`.
      - `transactions` (array, optional): Present only when `transactionDetails` is `full` or `accounts`. Each entry matches a `getBlock` transaction, including `meta.costUnits` and, on version 1 transactions, `transaction.message.transactionConfig`.
      - `rewards` (array, optional): Present only when `showRewards` is true.

## Unsubscribe

`blockUnsubscribe`, called with the subscription id, returns `true` once the subscription is removed.

## Example: Subscribe to blocks mentioning the Token program, signatures only

Request (send after connecting):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "blockSubscribe",
  "params": [
    {
      "mentionsAccountOrProgram": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
    },
    {
      "commitment": "confirmed",
      "transactionDetails": "signatures",
      "showRewards": false,
      "maxSupportedTransactionVersion": 1
    }
  ]
}
```

Response:

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

Notification:

```json
{
  "jsonrpc": "2.0",
  "method": "blockNotification",
  "params": {
    "result": {
      "context": {
        "slot": 337812455
      },
      "value": {
        "slot": 337812455,
        "err": null,
        "block": {
          "blockhash": "6H8VVc1r9pxJLLB9GnEHYtxLLKgHqcuMBQdCnZ8s4Sp7",
          "previousBlockhash": "4uQeVjuHGdMv6BEMwiAaRSqQnrCJRhfvJ3RGxfvfoxLC",
          "parentSlot": 337812454,
          "blockTime": 1789696102,
          "blockHeight": 316534221,
          "signatures": [
            "4ZtTkSQTPGaySHpMx9H2iY6h8jKzcsMBCyZ9rzQjbYXMSusK7EiZEL8n3egnN4cLf7D8n1xkjMK2sBSCthY2udyo",
            "5LW4mBaWXeMMvyGGeZqacPbpCjcnFT7YbpvprXzSp3UEPC6x9HFUxmpqVKmE6ao3TKWEHEv5MQ6VkwLEzrw1y8y8",
            "2coZaJddj7JDqUPAaztNKvjvmYg7AQZ7U78hMuY3HwtUiaL5ywxWogAwK781dGjXMPFqJdVhA1TQSNFNiNihFLVv"
          ]
        }
      }
    },
    "subscription": 78915
  },
  "truncated": true
}
```

## Notes

- `blockSubscribe` is on the Nexus plan only. The other subscriptions start at Operator.
- WebSocket access is included on the Operator plan and above; it is not available on Free.
- Concurrent connections are capped per API key: 10 on Operator, 50 on Blade Runner, 100 on Nexus.
- Subscribe and unsubscribe calls draw from the same global per-plan request-rate limit as HTTP calls: 50 req/s on Operator, 200 req/s on Blade Runner, 500 req/s on Nexus.
- Only subscription methods (the `*Subscribe` / `*Unsubscribe` family) are accepted on the WebSocket endpoint; standard request/response RPC methods must go over HTTPS instead.
- A `getHealth` request sent over the open socket on a regular interval serves as a keepalive; connections that go quiet can be dropped by intermediate load balancers.
- Each region has its own WebSocket hostname, for example `wss://ws-newyork.constant-k.com:1337/ws?api-key=YOUR_API_KEY`; every region is listed on the Endpoints page.
- Hand-built rather than captured live, since mainnet-beta's public endpoint does not accept `blockSubscribe`.
- `blockSubscribe` is on Agave's own unstable list; the notification's field names have changed before and may again without a deprecation cycle.
- `maxSupportedTransactionVersion` is checked at subscribe time, not when a block arrives; a missing value, or the string `"1"` instead of the integer `1`, fails the subscribe call with `-32602` before any block is streamed.

