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

# Orderbook schema

> The shape of a Polymarket L2 snapshot and the convenience columns we precompute.

Every snapshot we surface — whether from
[`/v1/snapshots`](/docs/api-reference/snapshots/list-snapshots),
[`/v1/markets/{id}/orderbook`](/docs/api-reference/markets/orderbook), or the
[live WebSocket](/docs/websocket) — has the same shape.

## Snapshot fields

```json theme={null}
{
  "market_id": "0x198001cb01bbcd…",
  "ts": "2026-06-05T02:14:31.892000",
  "yes_bids": [{"price": 0.41, "size": 1200}, ...],
  "yes_asks": [{"price": 0.45, "size":  800}, ...],
  "no_bids":  [{"price": 0.54, "size":  900}, ...],
  "no_asks":  [{"price": 0.58, "size": 1100}, ...],
  "best_yes_bid": 0.41,
  "best_yes_ask": 0.45,
  "mid_yes": 0.43,
  "spread_yes": 0.04,
  "underlying_ticker": "BTC",
  "underlying_price": 75123.45,
  "source": "ws"
}
```

| Field                   | Type                     | Notes                                                         |
| ----------------------- | ------------------------ | ------------------------------------------------------------- |
| `market_id`             | string                   | Hex CLOB market hash (`0x…`).                                 |
| `ts`                    | ISO-8601 UTC             | Snapshot timestamp, millisecond precision.                    |
| `yes_bids` / `yes_asks` | array of `{price, size}` | YES side levels, sorted (bids desc, asks asc).                |
| `no_bids` / `no_asks`   | array of `{price, size}` | NO side levels, same ordering.                                |
| `best_yes_bid`          | float\|null              | First `yes_bids` price.                                       |
| `best_yes_ask`          | float\|null              | First `yes_asks` price.                                       |
| `mid_yes`               | float\|null              | `(best_yes_bid + best_yes_ask) / 2`.                          |
| `spread_yes`            | float\|null              | `best_yes_ask − best_yes_bid`.                                |
| `underlying_ticker`     | string                   | `BTC` / `ETH` / `SOL`.                                        |
| `underlying_price`      | float\|null              | Binance spot at `ts`, denormalised so you don't need to join. |
| `source`                | string                   | `"ws"` (real-time WS push) or `"price_change"` (CLOB delta).  |

## Level depth

`yes_*` / `no_*` arrays carry up to **10 levels** per side. That's
deeper than Polymarket's CLOB usually quotes (most books are 3–5
levels), but matches the cap the CLOB itself publishes.

If you need a quick top-of-book number, **use the precomputed
`best_*` / `mid_*` columns** rather than re-parsing the arrays — same
value, less JSON.

## Symmetry

Polymarket's CLOB enforces that YES and NO orderbooks are
**price-complement** mirrors: a YES bid at $0.41 implies a NO ask at
$0.59 of the same size, and vice versa.

We render both sides verbatim from the WS feed without dedup — both
columns are populated, and the symmetry should hold. If you spot a
violation (`yes_bid + no_ask < 1.0` or `> 1.0` by more than a few
cents), please report it — it's either a logical arb (see
[Arb audit](/docs/concepts/arb-audit)) or a feed glitch.

## Cadence

The Polymarket collector samples adaptively:

* **Active markets** (recent move or trade): up to 8 snapshots / sec.
* **Quiet markets**: throttle to \~2 sec base.
* **Median observed cadence**: 178 ms between snapshots, per-market.
* **p90 cadence**: 7.2 sec (during quiet periods).

If your downstream needs guaranteed-cadence data (e.g. a backtest with
zero gaps), interpolate from the snapshot stream — the
[`/v1/markets/{id}/orderbook`](/docs/api-reference/markets/orderbook) endpoint
returns the raw stream without resampling.

## L2 depth for exchanges

Polymarket-side L2 lives at the schema above. The exchange-side
(Binance spot / Bybit linear perp) L2 lives in separate endpoints with
a slightly different field shape (`bids`/`asks` directly as
`[[price, qty], …]` arrays):

* [`GET /v1/binance/depth`](/docs/api-reference/depth/binance-depth) — top-20 @ 100 ms
* [`GET /v1/bybit/depth`](/docs/api-reference/depth/bybit-depth) — top-50 @ \~200 ms

These were added in **Phase BF (June 2026)** so the historical window
is short. Going forward we keep them with no retention cap.
