> ## Documentation Index
> Fetch the complete documentation index at: https://api.unusualwhales.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> API requests use the base URL https://api.unusualwhales.com and require a bearer token in the `Authorization` header (`Authorization: Bearer <API_KEY>`). Create and manage API tokens at https://unusualwhales.com/dashboard/api.
> For live market data inside an AI tool, use the Unusual Whales MCP server at https://unusualwhales.com/public-api/mcp.
> Instructions for agents using Unusual Whales tools: https://unusualwhales.com/skill.md

# Futures block trades

> Receive live CME block trades in futures contracts and multi-leg futures strategies, across all symbols or for a single symbol.

**NOTE:**
This is the documentation for the websocket channels `futures_blocks` and `futures_blocks:<SYMBOL>`.
The channels are available on the Advanced API tier, or with the `futures` add-on. Contact [oskar@unusualwhales.com](mailto:oskar@unusualwhales.com), [enterprise@unusualwhales.com](mailto:enterprise@unusualwhales.com) or [nastja.petrovic@unusualwhales.com](mailto:nastja.petrovic@unusualwhales.com) for access.

You can find fully-functional examples that stream data from many channels here:

* Python: [https://github.com/unusual-whales/api-examples/tree/main/examples/ws-multi-channel-multi-output](https://github.com/unusual-whales/api-examples/tree/main/examples/ws-multi-channel-multi-output)
* Javascript: [https://github.com/unusual-whales/api-examples/tree/main/examples/ws-multi-channel-multi-output-nodejs](https://github.com/unusual-whales/api-examples/tree/main/examples/ws-multi-channel-multi-output-nodejs)

Connect to the websocket URI:

`wss://api.unusualwhales.com/socket?token=<YOUR_API_TOKEN>`

then `join` the channel you wish to stream, for example `futures_blocks:ESZ6` for block trades in `ESZ6`.
Omit the symbol suffix (`futures_blocks`) to receive block trades in every contract and strategy.

Each message carries one CME block trade in a futures contract or in a multi-leg futures strategy.
CME publishes a block trade after it executes: `executed_at` is when the trade executed and
`reported_at` is when CME reported it.

### Delivery characteristics

* **A block trade can be sent more than once.** CME reports a block with the action `new`, and
  reports it again with `update` when the block changes or `delete` when CME removes it. The
  newest message for a block replaces the earlier ones. Identify a block by `trade_id`,
  `exchange` and `trade_date` together, because CME reuses a `trade_id` in later sessions.
  A repeated report, or one older than the last message sent for the block, is not sent.
* **A multi-leg trade arrives as one message.** For a multi-leg (`MLEG`) block the `legs` array
  lists the legs. CME also reports each leg as a separate trade, and the channel does not send
  those.
* **`futures_blocks:<SYMBOL>` matches `sym` exactly, and the symbol is case-sensitive.** A
  multi-leg block goes to the channel of its strategy symbol, such as `futures_blocks:SR3:GN`,
  not to the channels of its leg contracts.
* **Only futures and multi-leg blocks are sent.** `sec_type` is `FUT` or `MLEG`. Block trades in
  options on futures are not sent on this channel.
* **The channel sends nothing when you join.** To load earlier block trades, call
  [`/futures/:contract/trades`](https://api.unusualwhales.com/docs/operations/PublicApi.FuturesController.trades)
  or [`/futures/flow`](https://api.unusualwhales.com/docs/operations/PublicApi.FuturesController.flow)
  with `blocks_only=true`.
* **Joining without access returns an error.** Without the Advanced API tier or the `futures`
  add-on, a join is answered with an `{"error": "..."}` frame and the connection stays open.

Payload format for a single contract:

```
[
  "futures_blocks:ESZ6",
  {
    "sym": "ESZ6",
    "product": "ES",
    "exchange": "XCME",
    "trade_date": "2026-09-18",
    "executed_at": 1789741867000,
    "reported_at": 1789741912000,
    "price": "6612.25",
    "qty": "250",
    "sec_type": "FUT",
    "action": "new",
    "trade_id": 84213907,
    "strategy_link_id": null,
    "legs": [],
    "quote_bid": "6612.00",
    "quote_ask": "6612.25",
    "quote_ts": 1789741866950,
    "is_block": true
  }
]
```

Payload format for a multi-leg strategy:

```
[
  "futures_blocks",
  {
    "sym": "SR3:GN",
    "product": "",
    "exchange": "XCME",
    "trade_date": "2026-09-18",
    "executed_at": 1789742100000,
    "reported_at": 1789742160000,
    "price": null,
    "qty": "2500",
    "sec_type": "MLEG",
    "action": "new",
    "trade_id": 22693914,
    "strategy_link_id": 22693914,
    "legs": [
      {
        "sym": "SR3Z6 C9606",
        "price": "0.12",
        "qty": "2500",
        "sec_type": "OOF",
        "leg_side": "BUY",
        "ratio_qty": "1"
      }
    ],
    "quote_bid": null,
    "quote_ask": null,
    "quote_ts": null,
    "is_block": true
  }
]
```

### Field reference

`price`, `qty` and the leg prices and quantities are decimal strings with at most 8 decimal places.
Timestamps are Unix timestamps in milliseconds.

| Field | Type | Description |
| - | - | - |
| `sym` | string | CME Globex symbol of the contract, such as `ESZ6`, or of the strategy for a multi-leg trade, such as `SR3:GN`. Same as the `:` suffix on the keyed channel name. |
| `product` | string | Globex product root of the contract, such as `ES` or `ZN`. Empty string for multi-leg trades and for contracts whose root is not known yet. |
| `exchange` | string | Exchange MIC, such as `XCME` or `XCBT`. Empty string when unavailable. |
| `trade_date` | string | CME trade date in `YYYY-MM-DD` format. |
| `executed_at` | int | Time the trade executed. |
| `reported_at` | int | Time CME reported the block trade. |
| `price` | decimal string \| null | Trade price. `null` when CME reports no price, which is the case for multi-leg trades. Their prices are on the legs. |
| `qty` | decimal string | Traded quantity. |
| `sec_type` | string | `FUT` for a futures contract, `MLEG` for a multi-leg strategy. |
| `action` | string | `new`, `update` or `delete`. |
| `trade_id` | int | CME trade ID. Unique only together with `exchange` and `trade_date`. |
| `strategy_link_id` | int \| null | CME strategy link ID. `null` when CME sends none. When present, it equals `trade_id`. |
| `legs` | object\[] | The legs of a multi-leg trade, described below. Empty for a single contract. |
| `quote_bid` | decimal string \| null | Best bid recorded with the contract's last regular (non-block) trade at or before `reported_at`, from at most 3 days earlier. `null` for multi-leg trades, for `delete` messages, and when there is no such trade. |
| `quote_ask` | decimal string \| null | Best ask recorded with the same trade as `quote_bid`. `null` in the same cases. |
| `quote_ts` | int \| null | Time that regular trade executed. `null` in the same cases. |
| `is_block` | boolean | Always `true`. The REST futures trade endpoints carry the same field to tell block trades from regular prints. |

Each entry of `legs`:

| Field | Type | Description |
| - | - | - |
| `sym` | string | CME Globex symbol of the leg, such as `SR3Z6 C9606`. |
| `price` | decimal string \| null | Leg price. `null` when CME sends none. |
| `qty` | decimal string | Leg quantity. |
| `sec_type` | string | Security type of the leg as CME reports it, such as `FUT` or `OOF` (option on a future). |
| `leg_side` | string \| null | Side of the leg as CME reports it, such as `BUY`. `null` when CME sends none. |
| `ratio_qty` | string \| null | Ratio quantity of the leg within the strategy, such as `1`. `null` when CME sends none. |
