Skip to main content

What it streams

Realtime odds updates for outcomes within markets, scoped to a specific fixtureId. Odds are grouped by bookmaker and keyed by a unique oddsId per outcome. Each entry represents a single oddsId (one price for one outcome).

Routing

  • Entity key: payload.fixtureId
  • Filters: sportIds, tournamentIds, fixtureIds, bookmakers
  • Access: determined by your apiKey
  • Bookmaker-gated: ✅ Yes

Delivery semantics

The odds channel delivers conflated state on a fixed ~6 ms batching window: if multiple updates for the same oddsId occur within one window, only the newest is sent.
  • No state is lost — the final value of every price move is always delivered
  • Bounded staleness — a delivered price is never more than one batching window behind our observation of the bookmaker
  • The window is a fixed performance parameter, not a load-shedding mechanism
What is not delivered: intermediate ticks superseded within the same window. Treat every message as a state update, not a ledger.
Need every price move or the closing line? For full tick-level movement use Historical Odds and for opening/closing prices use CLV.

Payload structure

oddsId:

outcome object (full schema)

Each odds entry is an outcome, with the following fields:

Notes on timestamps

Each update carries the full delivery chain: changedAt − bookmakerChangedAt is the observation delay for that update. Per-bookmaker freshness bounds are published on GET /bookmakers — see Latency and freshness.

Limits

limit is the maximum accepted stake at the current price — for a trading system, size-at-price matters as much as the price itself. OddsPapi normalizes limits across books and carries them for close to every sharp book (see "limit": 19354 on Pinnacle below). Limit changes are delivered as regular odds updates. limit and the meta ladders bound different things: limit bounds a single order, the ladder bounds the fill. On a traditional book limit is the only size signal there is; on an exchange you have both and they constrain you independently. See sharp-line trading & CLV for using limits together with per-book delay, main-line filtering, and closing line value.

Advanced metadata (meta)

Exchanges and prediction markets carry their orderbook on the quote itself, under meta.

Ladder entries

back and lay are arrays of rungs, best price first, up to three deep. Each rung: Either side can be []. A one-sided book is normal on a thin market, not an error, and best back touching best lay is a crossed book — read changedAt before trading it.

Additional keys

On polymarket, polymarket.us, kalshi and prophetx, meta also carries bookmakerLayOutcomeId — the venue’s own id for the opposite side of the market. You need it to route a lay order, because bookmakerOutcomeId on the quote addresses the back side only. Those four share the same back / lay semantics, so one parser covers all of them. Treat meta as additive and preserve keys you do not recognise.
betfair-ex uses a venue-specific shape instead: availableToBack and availableToLay (rungs of { price, size } only — no cents or limit), plus tradedVolume, betDelay and, on handicap markets, bookmakerHandicap.
See building on prediction markets & exchanges for reading the ladders, deriving top-of-book, and routing orders back to the venue with bookmakerMarketId / bookmakerOutcomeId.

Example: traditional bookmaker odds


Example: prediction market odds (extended fields)


Implementation guidance

  • Always key storage by
  • Group outcomes by marketId (see Concepts) for:
    • arbitrage detection
    • overround calculations
    • probability normalization
  • Treat active=false or marketActive=false as hard stops
  • Preserve unknown fields in meta to remain forward-compatible
End-to-end patterns built on this channel: prediction markets & exchanges, sharp-line trading & CLV, running a second feed, and powering a sportsbook.