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

# Orderbook Stream

> Real-time L2 orderbook data: price changes, trades, and book snapshots for Polymarket markets

The orderbook channel (`"orderbook"`) streams real-time off-chain orderbook data from Polymarket's CLOB. Subscribe by `token_ids`, `condition_ids`, or `market_slugs`, or use wildcard (`["*"]`) for the full firehose of all 100k+ tokens.

* **Targeted subscriptions** deliver individual events as they happen. Latency is essentially identical to Polymarket's native feeds.
* **Wildcard subscriptions** deliver 250ms batched events with price-level conflation.

## Subscribe

```json theme={null}
{
  "action": "subscribe",
  "platform": "polymarket",
  "version": 1,
  "type": "orderbook",
  "filters": {
    "market_slugs": ["us-x-iran-ceasefire-by-april-7-278"]
  }
}
```

### Filter Types

Exactly one filter type per subscribe message.

| Filter          | Description          | Example                    |
| --------------- | -------------------- | -------------------------- |
| `token_ids`     | CLOB token IDs       | `["82855...", "55194..."]` |
| `condition_ids` | Market condition IDs | `["0x4c57..."]`            |
| `market_slugs`  | Market URL slugs     | `["bitcoin-100k-2026"]`    |

Use `["*"]` with any filter type for the full firehose.

When subscribing by `market_slugs` or `condition_ids`, both sides of the market (Yes + No) are resolved and subscribed automatically. You'll receive a `book_snapshot` for each outcome. When subscribing by `token_ids`, you receive only the specific outcome(s) you subscribed to.

<Note>
  `users` filter is not supported on the orderbook channel. Use the [trades channel](/websocket/trades) for wallet-level filtering.
</Note>

***

## Connection Lifecycle

### Targeted Subscriptions

```
→ subscribe
← ack
← book_snapshot (Yes side)
← book_snapshot (No side)
← snapshots_done
← price_change events (individual, as they happen)
← last_trade events
← tick_size_change events
```

### Wildcard / Firehose

```
→ subscribe
← ack
← event_batch (every ~250ms, conflated)
← event_batch
← ...
```

***

## Event Types

### book\_snapshot

Sent on subscribe. Includes full orderbook state and market metadata for enrichment.

```json theme={null}
{
  "type": "event",
  "subscription_id": "sub_xxx",
  "data": {
    "event_type": "book_snapshot",
    "token_id": "82855...",
    "condition_id": "0x4c57...",
    "slug": "us-x-iran-ceasefire-by-april-7-278",
    "question": "US x Iran ceasefire by April 7?",
    "event_title": "US x Iran ceasefire by...?",
    "outcome": "Yes",
    "timestamp": 1775196804071,
    "bids": [{"price": "0.02", "size": "5000"}, ...],
    "asks": [{"price": "0.98", "size": "3000"}, ...],
    "hash": "abc123..."
  }
}
```

<Note>
  `question` and `event_title` are included only in `book_snapshot` events. Live events (`price_change`, `last_trade`, `tick_size_change`) omit these for bandwidth efficiency. Use the snapshot for display metadata.
</Note>

***

### price\_change

Live delta for a single price level. Size `"0"` means the level was removed; otherwise upsert (add or update).

```json theme={null}
{
  "type": "event",
  "subscription_id": "sub_xxx",
  "data": {
    "event_type": "price_change",
    "token_id": "82855...",
    "condition_id": "0x4c57...",
    "slug": "us-x-iran-ceasefire-by-april-7-278",
    "outcome": "Yes",
    "timestamp": 1775196805000,
    "side": "BUY",
    "price": "0.03",
    "size": "71891.78",
    "best_bid": "0.03",
    "best_ask": "0.97"
  }
}
```

#### Field Reference

| Field          | Type   | Description                           |
| -------------- | ------ | ------------------------------------- |
| `event_type`   | string | `"price_change"`                      |
| `token_id`     | string | CLOB token ID                         |
| `condition_id` | string | Market condition ID (hex)             |
| `slug`         | string | Market URL slug                       |
| `outcome`      | string | `"Yes"` or `"No"`                     |
| `timestamp`    | number | Polymarket server timestamp (Unix ms) |
| `side`         | string | `"BUY"` (bid) or `"SELL"` (ask)       |
| `price`        | string | Price level (0 to 1)                  |
| `size`         | string | Size at this level (`"0"` = removed)  |
| `best_bid`     | string | Current best bid price for this token |
| `best_ask`     | string | Current best ask price for this token |

***

### last\_trade

Trade execution event.

```json theme={null}
{
  "type": "event",
  "subscription_id": "sub_xxx",
  "data": {
    "event_type": "last_trade",
    "token_id": "82855...",
    "condition_id": "0x4c57...",
    "slug": "us-x-iran-ceasefire-by-april-7-278",
    "outcome": "Yes",
    "timestamp": 1775196806000,
    "side": "BUY",
    "price": "0.46",
    "size": "219.22",
    "fee_rate_bps": "0"
  }
}
```

***

### tick\_size\_change

Emitted when the market's tick size changes.

```json theme={null}
{
  "type": "event",
  "subscription_id": "sub_xxx",
  "data": {
    "event_type": "tick_size_change",
    "token_id": "82855...",
    "condition_id": "0x4c57...",
    "slug": "us-x-iran-ceasefire",
    "outcome": "Yes",
    "timestamp": 1775196807000,
    "tick_size": "0.001"
  }
}
```

***

### snapshots\_done

Marker sent after all initial snapshots have been delivered. `count` is the number of `book_snapshot` events that preceded it.

```json theme={null}
{
  "type": "event",
  "subscription_id": "sub_xxx",
  "data": {
    "event_type": "snapshots_done",
    "count": 2
  }
}
```

***

### event\_batch

Firehose only. Batched every \~250ms with price-level conflation. Each element in the `events` array has the same shape as the `data` field in individual events (`price_change`, `last_trade`, `tick_size_change`, etc.).

```json theme={null}
{
  "type": "event_batch",
  "subscription_id": "sub_xxx",
  "count": 350,
  "events": [{...}, {...}, ...],
  "gap": false
}
```

If `gap: true`, events were missed during a reconnect. Client should rebuild state from the next snapshot.

***

### resync

Sent after an internal reconnect. Signals the client to discard local state and rebuild.

```json theme={null}
{
  "type": "event",
  "subscription_id": "sub_xxx",
  "data": {
    "event_type": "resync"
  }
}
```

After `resync`, fresh `book_snapshot` events and a `snapshots_done` follow automatically.

***

## Unsubscribe

To stop receiving orderbook events, send an unsubscribe with the subscription ID from the original `ack`:

```json theme={null}
{
  "action": "unsubscribe",
  "subscription_id": "sub_xxx"
}
```

Updating orderbook subscriptions is not supported. To change filters, unsubscribe and resubscribe.

See [Subscriptions](/websocket/subscriptions) for full details on subscription management.

***

## New Market Timing

Newly created markets are available within a few seconds of creation on Polymarket. Book snapshots may be empty initially. Live deltas will populate as the market becomes active.
