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

# Orderbook mapping

> How each upstream exchange schema maps to OpenPX Orderbook.

*Full-depth L2 orderbook for one asset.*

Every field is one of three entry types — **direct** (taken from upstream), **synthetic** (computed by OpenPX), or **omitted** (not exposed upstream).

## Coverage

| Exchange   | Direct | Synthetic | Omitted |
| ---------- | ------ | --------- | ------- |
| kalshi     | 2      | 3         | 1       |
| polymarket | 5      | 0         | 1       |

## Field crosswalk

| Unified field    | Type                | kalshi source                  | polymarket source            | Notes                                                                                                                                                                                              |
| ---------------- | ------------------- | ------------------------------ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `asset_id`       | string              | `MarketOrderbookFp.ticker`     | `OrderBookSummary.asset_id`  | **kalshi:** Kalshi market ticker; the single-market REST endpoint stamps the path parameter. **polymarket:** Polymarket CTF token id of one outcome.                                               |
| `bids`           | array               | `OrderbookCountFp.yes_dollars` | `OrderBookSummary.bids`      | **kalshi:** YES bids parsed from `[price_$, count_fp]` tuples and sorted descending. **polymarket:** `OrderSummary \{ price, size \}` strings parsed to f64 and sorted descending.                 |
| `asks`           | array               | *synthetic*                    | `OrderBookSummary.asks`      | **kalshi:** Synthesized from `no_dollars` via the binary identity: NO bid at p == YES ask at (1 − p). **polymarket:** `OrderSummary \{ price, size \}` strings parsed to f64 and sorted ascending. |
| `last_update_id` | integer? (uint64)   | *synthetic*                    | *omitted*                    | **kalshi:** WS `seq` on snapshot/delta messages; null on REST since the endpoint omits it. **polymarket:** Polymarket emits no per-message sequence — book integrity is verified via `hash`.       |
| `timestamp`      | string? (date-time) | *synthetic*                    | `OrderBookSummary.timestamp` | **kalshi:** WS `ts_ms` on delta messages; REST stamps `Utc::now()` at receive time. **polymarket:** Unix millis encoded as a string.                                                               |
| `hash`           | string?             | *omitted*                      | `OrderBookSummary.hash`      | **kalshi:** Kalshi exposes no orderbook hash on REST or WS. **polymarket:** Exchange-provided book-state hash for replay integrity.                                                                |

## Source specs

* **kalshi** · [`schema/upstream/kalshi.openapi.yaml`](https://github.com/openpx-trade/openpx/blob/main/schema/upstream/kalshi.openapi.yaml)
* **polymarket** · [`schema/upstream/polymarket-clob.openapi.yaml`](https://github.com/openpx-trade/openpx/blob/main/schema/upstream/polymarket-clob.openapi.yaml)

> Tables are auto-generated from `schema/mappings/`. CI fails if any `direct` ref no longer resolves in the cached upstream spec; the daily upstream-refresh PR surfaces drift here.
