?book= and ?market= query filters so you can pull only the slices you care about in one round trip.
lib-gar-est-2026-04-14) or a raw game_id (40664-16839-2026-04-14). Both resolve to the same record. Unmatched games where pn_slug is null still work — just use the game_id.
string
required
Polynode slug (e.g.
nba-mia-cha-2026-04-14) or raw game_id (e.g. 40664-16839-2026-04-14).string
required
Your API key. Accepted via query param or
Authorization: Bearer header.string
Comma-separated list of
pn_market_type values to include (e.g. moneyline,spreads,totals). Omit for all markets.string
Comma-separated list of book names to include (e.g.
DraftKings,Polymarket,BetMGM). Omit for all books.Response
This is a real response for a live NBA game (Portland @ Phoenix, Q3 03:42) filtered tomarket=moneyline on three books:
Top-level shape
Outcome object
Same endpoint as /markets
/v1/games/{id} and /v1/games/{id}/markets return identical shapes and accept identical filters. They are aliases. Use whichever URL reads better in your code.
Book coverage varies by league and market
Not every book carries every market. A live NBA moneyline is carried by 60-90 books; a live AHL game might only have 5-10. DraftKings’ mainline sportsbook does not currently publish NBA moneylines — their NBA odds ship under theDraftKings Predictions book name. If you filter to ?book=DraftKings on an NBA game and get empty results, that’s why. Use List Books to see which books are currently known to the system.
Post-restart warmup window
For ~30 seconds after the service restarts, the market backfill runs one market type at a time across all sports. You may see fewerpn_market_type keys than the steady-state total. Retry a few seconds later or subscribe to /ws/odds to stream the fill as it happens.
Refresh semantics
- Live games re-poll every ~1 second.
- Idle (unplayed / final) games re-poll every ~10 seconds.
- For real-time deltas, subscribe to
/ws/oddsand applyprice_changeevents on top of this baseline.

