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

# Fill mapping

> How each upstream exchange schema maps to OpenPX Fill.

*A single fill (trade execution) from one of the caller's orders.*

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     | 10     | 0         | 0       |
| polymarket | 7      | 0         | 3       |

## Field crosswalk

| Unified field   | Type               | kalshi source                                              | polymarket source       | Notes                                                                                                                                                                                                |
| --------------- | ------------------ | ---------------------------------------------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fill_id`       | string             | `Fill.fill_id`                                             | `Trade.transactionHash` | **kalshi:** Kalshi-issued unique fill id. **polymarket:** Polygon transaction hash; doubles as fill id since one trade lands per tx.                                                                 |
| `order_id`      | string             | `Fill.order_id`                                            | *omitted*               | **kalshi:** Kalshi-issued order id that produced this fill. **polymarket:** Public-tape `Trade` does not expose order ids; live WebSocket events do via `liquidity_role`.                            |
| `market_ticker` | string             | `Fill.ticker`, fallback `Fill.market_ticker`               | `Trade.conditionId`     | **kalshi:** Prefers canonical `ticker`, falls back to legacy alias `market_ticker`. **polymarket:** On-chain condition id; `Position.market_ticker` (slug) intentionally diverges from this surface. |
| `outcome`       | string             | `Fill.side`                                                | `Trade.outcome`         | **kalshi:** Title-cased from the YES/NO `side` field (buy/sell lives on `action`). **polymarket:** Outcome label as published by Polymarket.                                                         |
| `side`          | OrderSide          | `Fill.action`                                              | `Trade.side`            | **kalshi:** Buy/Sell sourced from `action` (the YES/NO `side` field is unrelated). **polymarket:** BUY/SELL enum, 1:1 with unified `OrderSide`.                                                      |
| `price`         | number (double)    | `Fill.yes_price_dollars`, fallback `Fill.no_price_dollars` | `Trade.price`           | **kalshi:** Outcome-aware: uses `yes_price_dollars` on YES fills and `no_price_dollars` on NO fills. **polymarket:** Decimal probability for the row's outcome token in \[0, 1].                     |
| `size`          | number (double)    | `Fill.count_fp`                                            | `Trade.size`            | **kalshi:** FixedPointCount string parsed to f64. **polymarket:** Non-negative size in contracts.                                                                                                    |
| `is_taker`      | boolean            | `Fill.is_taker`                                            | *omitted*               | **kalshi:** Boolean: `true` if the fill removed liquidity, `false` if it added. **polymarket:** Public tape lacks per-fill maker/taker flag; the WebSocket user channel carries `liquidity_role`.    |
| `fee`           | number (double)    | `Fill.fee_cost`                                            | *omitted*               | **kalshi:** Per-fill fee in FixedPointDollars. **polymarket:** Polymarket does not expose a per-fill fee on the Data API; defaults to 0.0.                                                           |
| `created_at`    | string (date-time) | `Fill.created_time`                                        | `Trade.timestamp`       | **kalshi:** RFC3339 string parsed to UTC. **polymarket:** Unix seconds (not milliseconds) parsed to UTC.                                                                                             |

## 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-data.openapi.yaml`](https://github.com/openpx-trade/openpx/blob/main/schema/upstream/polymarket-data.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.
