> ## 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

# Greek flow by expiry

> Receive live delta & vega flow broken out by option expiry, for every ticker at once or for a single ticker.

**NOTE:**
This is the documentation for the websocket channels `greek_flow_expiry` and
`greek_flow_expiry:<TICKER>`.
For the same data aggregated across all expiries, see [`greek_flow`](/docs/websocket/greek-flow).
Websocket access for personal use is only available through the [Advanced plan](https://unusualwhales.com/pricing?product=api).

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 `greek_flow_expiry:SPY` for SPY's
delta and vega flow broken out per option expiry. Omit the ticker suffix to receive updates
for every ticker.

Each message carries the delta and vega exposure of the option trades that printed for one
ticker, in one minute, **for a single option expiry**, and arrived since the previous message
for that minute and expiry; see Delivery characteristics below for how to sum them. Both
channels are built from the same option trades, so once every message for a minute has
arrived, that minute's expiries sum to the same minute on the
[`greek_flow`](/docs/websocket/greek-flow)
channel. `total_*` fields carry the greek's own sign - for delta that means calls contribute
positive and puts negative - so they are net greek exposure regardless of who was the
aggressor. `dir_*` fields instead sign the magnitude by trade sentiment: for delta, bullish
trades (bought calls, sold puts) positive and bearish negative; for vega, buys (ask side)
positive and sells (bid side) negative. Mid/no-side trades are excluded from every `dir_*`
field.

### Delivery characteristics

Read these before writing a client, they are not obvious from the payload:

* **Each message is a partial sum, not a running total.** A minute's bucket is flushed
  roughly once per second as trades arrive, so to get that minute's total for one expiry you
  must **add together every message sharing the same `ticker`, `timestamp` and `expiry`**.
  Grouping on `timestamp` alone is wrong even on the per-ticker channel, since every expiry
  that traded carries that same minute; on the global channel every ticker does too. A client
  that overwrites on the key instead of adding will silently under-report.
* Because of that, a dropped frame does not just delay a value, it changes your sum. Read
  from the socket promptly: a slow consumer is not disconnected, but frames it fails to keep
  up with are dropped.
* **Updates are trade-driven, not scheduled.** An expiry with no option trades in the window
  produces no message at all - there is no per-minute tick and no zero-valued heartbeat. A
  minute bucket is also never announced as closed: messages carrying a given `timestamp`
  simply stop arriving.
* **This channel carries considerably more messages than `greek_flow`** - one per expiry that
  traded, rather than one per ticker.
* The channels are keyed by the **root** ticker: weekly/PM index series are folded into their
  root (`SPXW` under `SPX`, `NDXP` under `NDX`, `VIXW` under `VIX`, `RUTW` under `RUT`).
  Joining `greek_flow_expiry:SPXW` is acknowledged as, and streams, `greek_flow_expiry:SPX`.
* All flow values are decimal strings, matching the REST endpoint below.

This is the live counterpart of [`/stock/:ticker/greek-flow/:expiry`](https://api.unusualwhales.com/docs/operations/PublicApi.TickerController.greek_flow_expiry),
which returns the same fields with the same encodings. Note the REST endpoint serves each
minute's **accumulated total**, while this channel serves the per-second partials that add up
to it.

Payload format for `greek_flow_expiry:<TICKER>`:

```
[
  "greek_flow_expiry:SPY",
  {
    "ticker": "SPY",
    "timestamp": "2026-09-04T15:46:00Z",
    "expiry": "2026-10-16",
    "total_delta_flow": "-21257.36",
    "dir_delta_flow": "-43593.96",
    "otm_total_delta_flow": "-28564.02",
    "otm_dir_delta_flow": "14947.51",
    "total_vega_flow": "350944.58",
    "dir_vega_flow": "31243.04",
    "otm_total_vega_flow": "101745.64",
    "otm_dir_vega_flow": "11421.03",
    "transactions": 77,
    "volume": 4242
  }
]
```

### Field reference

| Field | Type | Description |
| - | - | - |
| `ticker` | string | Root ticker of the underlying. |
| `timestamp` | string | The minute bucket these trades fall into, ISO 8601 UTC. |
| `expiry` | string | The option expiry this bucket is broken out by, `YYYY-MM-DD`. |
| `total_delta_flow` | string | Sum of signed delta exposure: `delta * contracts * 100`. |
| `dir_delta_flow` | string | Delta magnitude signed by sentiment: positive for bullish trades (buy call / sell put), negative for bearish. |
| `otm_total_delta_flow` | string | `total_delta_flow` counting only trades identified as out of the money. |
| `otm_dir_delta_flow` | string | `dir_delta_flow` counting only trades identified as out of the money. |
| `total_vega_flow` | string | Sum of vega exposure: `vega * contracts * 100`. |
| `dir_vega_flow` | string | Vega magnitude signed by side: positive for buys (ask side), negative for sells (bid side). |
| `otm_total_vega_flow` | string | `total_vega_flow` counting only trades identified as out of the money. |
| `otm_dir_vega_flow` | string | `dir_vega_flow` counting only trades identified as out of the money. |
| `transactions` | integer | Number of option trades aggregated into this message. A trade whose delta or vega was unavailable still counts here and in `volume` but adds zero to that greek's flow fields. |
| `volume` | integer | Total contracts traded across the aggregated trades. |
