Skip to main content

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.

Unified prediction market model.

Coverage

ExchangeSourcedSyntheticOmitted
kalshi1564
polymarket1960
Sourced — value copied or transformed from a documented upstream field.
Synthetic — computed by OpenPX, not present upstream.
Omitted — upstream does not expose this concept.

Field crosswalk

Unified fieldTypekalshi sourcepolymarket sourceTransformNotes
tickerstringMarket.ticker (string)Market.slug (string)directpolymarket: Polymarket exposes both a slug and a numeric id; we use slug as the unified ticker because it’s stable and human-readable. The on-chain conditionId lives in condition_id; the numeric id lives in numeric_id for REST-only deep links.
openpx_idstringcomputed{exchange}:{ticker}computed{exchange}:{ticker}syntheticComposite primary key, never sourced from upstream.
exchangestringcomputed — literal exchange identifier (“kalshi” or “polymarket”)computed — literal exchange identifier (“kalshi” or “polymarket”)synthetic
numeric_idstring?not exposedMarket.id (string)directkalshi: Kalshi has no separate numeric id surface.
event_tickerstring?Market.event_ticker (string)computed — events[0].slug from the embedded events relationdirect / synthetickalshi: Kalshi exposes the parent event identifier as event_ticker. polymarket: Polymarket’s parent event is embedded under events[] on each market object; we read events[0].slug (the human-readable identifier matching the unified event_ticker semantics). Falls back to events[0].id only when slug is missing on the upstream payload.
titlestringcomputed{yes_sub_title} | {no_sub_title}Market.question (string)synthetic / directkalshi: Composed from the spec-canonical short titles for each side of the binary contract. The deprecated title field is ignored.
rulesstring?computed{rules_primary} | {rules_secondary}Market.description (string)synthetic / directkalshi: Concatenation of the two upstream prose fields with ” | ” separator. Sources: rules_primary, rules_secondary.
statusMarketStatusMarket.status (string)Market.active (boolean)enum_remapkalshi: Kalshi values: initialized, inactive, active, closed, determined, disputed, amended, finalized → unified MarketStatus. polymarket: Polymarket exposes active, closed, archived as booleans; combined into unified MarketStatus enum.
market_typeMarketTypeMarket.market_type (string)computed — derived from outcomes.len() (binary if 2, else categorical)enum_remap / synthetickalshi: binary | scalar → MarketType::Binary / MarketType::Scalar
resultstring?Market.result (string)computed — outcomes[i] where outcomePrices[i] == 1.0 (resolved markets only)direct / syntheticpolymarket: Polymarket has no single result field; the winning outcome is derived from outcomePrices after settlement. None for unresolved markets. Sources: outcomes, outcomePrices.
open_timestring? (date-time)Market.open_time (string (date-time))Market.startDate (string (date-time))parse_datetime
close_timestring? (date-time)Market.close_time (string (date-time))Market.endDate (string (date-time))parse_datetime
created_atstring? (date-time)Market.created_time (string (date-time))Market.createdAt (string (date-time))parse_datetime
settlement_timestring? (date-time)Market.settlement_ts (string (date-time))Market.closedTime (string)parse_datetimepolymarket: closedTime is the actual on-chain settlement timestamp (distinct from endDate, which is the scheduled close). Populated only after settlement.
best_bidnumber? (double)Market.yes_bid_dollars (FixedPointDollars)Market.bestBid (number)fixed_point_dollars / directpolymarket: Polymarket already in [0,1] decimal.
best_asknumber? (double)Market.yes_ask_dollars (FixedPointDollars)Market.bestAsk (number)fixed_point_dollars / direct
last_trade_pricenumber? (double)Market.last_price_dollars (FixedPointDollars)Market.lastTradePrice (number)fixed_point_dollars / direct
tick_sizenumber? (double)Market.price_ranges (array)Market.orderPriceMinTickSize (number)tick_size / directkalshi: Kalshi exposes a tiered structure (PriceRange array, each with start/end/step strings); the unified value is the smallest step across all tiers — the finest precision the market accepts anywhere on its price curve. Coarser tiers still require their own step, but the single-number unified surface answers “what’s the tightest tick I can ever quote?”. The deprecated scalar tick_size integer is ignored. polymarket: Polymarket publishes a single scalar.
min_order_sizenumber? (double)computed — 1.0 (or 0.01 when fractional_trading_enabled)Market.orderMinSize (number)synthetic / directkalshi: Kalshi has no upstream min_order_size field. Synthesized from fractional_trading_enabled. Source: fractional_trading_enabled.
volumenumber (double)Market.volume_fp (FixedPointCount)Market.volumeNum (number)fixed_point_count / direct
volume_24hnumber? (double)Market.volume_24h_fp (FixedPointCount)Market.volume24hr (number)fixed_point_count / direct
outcomesarraycomputedper-exchange Vec<Outcome{label, price, token_id}>computedper-exchange Vec<Outcome{label, price, token_id}>syntheticKalshi binary: two entries with labels “Yes” and “No”; price computed from yes_ask_dollars/last_price_dollars (No price = 1 - Yes); token_id always None (no per-outcome token surface). Polymarket: zipped element-wise from the stringified-JSON arrays outcomes, outcomePrices, and clobTokenIds. Replaces the previous trio of outcome_prices map + outcome_tokens vec + binary-only token_id_yes/token_id_no.
condition_idstring?not exposedMarket.conditionId (string)direct
neg_riskboolean?not exposednegRiskspec gapdirectpolymarket: Spec gap: the gamma OpenAPI defines negRisk on Event and Template, not on Market, but live /markets and /markets/keyset responses include it on each market object. The parser reads it directly. Re-check on each daily upstream refresh — when Polymarket adds it to Market properties, promote to a regular ref: here.
neg_risk_market_idstring?not exposednegRiskMarketIDspec gapdirectpolymarket: Spec gap (same pattern as neg_risk).

Source specs

Tables are auto-generated from schema/mappings/. CI fails on unresolved $refs and on type mismatches for transform: direct. Drift in upstream specs surfaces here on the daily refresh PR.