schema/upstream/.
Every source entry is one of three types — direct (taken from upstream), synthetic (constructed by OpenPX), or omitted (not exposed upstream).
Coverage
| Exchange | Direct | Synthetic | Omitted |
|---|---|---|---|
| kalshi | 3 | 3 | 1 |
| polymarket | 2 | 5 | 0 |
Subscribe payload
| Field | kalshi source | polymarket source | Notes |
|---|---|---|---|
market_id | #/components/messages/subscribeCommand | #/components/messages/subscriptionRequest | kalshi: Kalshi auto-subscribes the trade channel alongside orderbook_delta on every subscribe(market_ticker) call. polymarket: Polymarket assets_ids[*]. The market channel emits last_trade_price for the asset; trades on the user channel surface as fills, not trades. |
outcome | omitted | synthetic | kalshi: Trade frames carry side and taker_side; outcome (YES/NO) is implicit per Kalshi binary market. polymarket: Populated only when register_outcomes(yes_token, no_token) was called. Otherwise ActivityTrade.outcome is None. |
Receive messages
| Variant | kalshi source | polymarket source | Notes |
|---|---|---|---|
Trade | #/components/messages/trade | #/components/messages/lastTradePrice | kalshi: Public Kalshi trade frame — exchange-side fills (any maker/taker pair). Mapped to ActivityTrade \{ source_channel: "kalshi_public_trade" \}. polymarket: Polymarket last_trade_price carries the most recent trade for an asset. Mapped to ActivityTrade \{ source_channel: "polymarket_last_trade_price" \}. |
Session events
| Variant | kalshi source | polymarket source | Notes |
|---|---|---|---|
Connected | synthetic | synthetic | |
Reconnected | synthetic | synthetic | |
Lagged | synthetic | synthetic | |
Error | #/components/messages/errorResponse | synthetic |
Source specs
- kalshi ·
schema/upstream/kalshi.asyncapi.yaml - polymarket ·
schema/upstream/polymarket.asyncapi.json
Tables are auto-generated fromschema/mappings/. CI fails if anydirectref no longer resolves in the cached upstream AsyncAPI spec; the daily upstream-refresh PR surfaces drift here.

