# slotsUpdatesSubscribe

> Streams fine-grained per-slot lifecycle events (unstable; shape may change without notice).

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

Where `slotSubscribe` gives one message when a slot starts processing, `slotsUpdatesSubscribe` gives one message for each lifecycle transition a slot passes through on the way to being rooted — first shred received, bank created, frozen (with block-production stats attached), optimistically confirmed, rooted, or dead — distinguished by the notification's `type` field.

Agave documents this subscription as unstable: the set of `type` values and the fields attached to each one have changed before and may change again without a deprecation cycle. It serves as a debugging/observability aid rather than a base for commitment-sensitive logic; `slotSubscribe`, `rootSubscribe`, or `signatureSubscribe` cover that instead.

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

## Parameters

None.

## Result

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

## Notifications

Updates arrive as `slotsUpdatesNotification` messages. Every variant carries `slot` and a millisecond `timestamp`. `frozen` additionally carries a `stats` object (`numTransactionEntries`, `numSuccessfulTransactions`, `numFailedTransactions`, `maxTransactionsPerEntry`); `createdBank` additionally carries `parent`; `dead` additionally carries `err` describing why the slot was abandoned. `firstShredReceived`, `completed`, `optimisticConfirmation`, and `root` carry no extra fields beyond `slot` and `timestamp`.

- `params.result` (object, optional)
  - `option 1` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.
  - `option 2` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.
  - `option 3` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `parent` (integer, optional): Parent slot.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.
  - `option 4` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.
    - `stats` (object, optional): Block-production statistics for this slot.
      - `numTransactionEntries` (integer, optional): Number of transaction entries in the slot.
      - `numSuccessfulTransactions` (integer, optional): Number of transactions that executed successfully.
      - `numFailedTransactions` (integer, optional): Number of transactions that failed.
      - `maxTransactionsPerEntry` (integer, optional): Highest number of transactions packed into a single entry.
  - `option 5` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.
    - `err` (string, optional): Human-readable reason the slot was abandoned instead of being replayed successfully.
  - `option 6` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.
  - `option 7` (object, optional)
    - `type` (string, optional): Discriminator naming which kind of update this notification carries.
    - `slot` (integer, optional): Slot number this applies to.
    - `timestamp` (integer, optional): Unix timestamp in milliseconds.

## Unsubscribe

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

## Example: Subscribe to slot lifecycle updates

Request (send after connecting):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "slotsUpdatesSubscribe"
}
```

Response:

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

Notification:

```json
{
  "jsonrpc": "2.0",
  "method": "slotsUpdatesNotification",
  "params": {
    "result": {
      "type": "frozen",
      "slot": 447946412,
      "timestamp": 1789696067986,
      "stats": {
        "numTransactionEntries": 1350,
        "numSuccessfulTransactions": 1350,
        "numFailedTransactions": 188,
        "maxTransactionsPerEntry": 1
      }
    },
    "subscription": 11071870
  }
}
```

## Notes

- 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.
- Captured live from `wss://api.mainnet-beta.solana.com`; `frozen` is shown here because it carries the richest payload. The same connection also produced, moments apart:

```json
{"type":"completed","slot":447946412,"timestamp":1789696067983}
```
```json
{"type":"root","slot":447946380,"timestamp":1789696067990}
```
- This subscription is unstable upstream: quoting Agave's own documentation, "the format may change in the future and may not always be supported."

