Skip to main content
A sports game’s markets are spread across companion events (moneyline, spreads, totals, props) and venues, all sharing one canonical game key (aggKey, e.g. agg_fifwc_bih_che_260618). Build the detail page with three steps and no client-side matching.

Listing the games (one tile per game)

GET /venue-events?grouped=true returns one tile per game: a venue’s companion events (… - More Markets, … - Exact Score, … : Spread) fold under their base, and cross-venue siblings collapse to the cluster anchor. Each tile carries the game aggKey and groupMarketCount (open markets across the whole game). Tap a tile, take its id, and load the detail page below.
grouped is opt-in — only pass grouped=true once you have the game-detail page below, because grouping hides the companion events from the listing and the detail page is what re-surfaces their markets (spreads, exact score, props) via aggKey. Omit grouped (the default) and companion events list as separate tiles.

1. Load the event

GET /venue-events/:id → read structureType (sport → render the game page) and aggKey (the game handle). The response also carries venues[] and the event’s own markets.

2. Load each section lazily

The detail page is tab/section based. Load one section per call by the game aggKey plus the normalized enums — do NOT fetch the whole game at once (a game can be hundreds of markets): GET /venue-markets?aggKey={gameAggKey}&sportsMarketType=spread&period=full&limit=50&cursor=…
  • aggKey here is game-scoped: pass the event-level aggKey and you get every market of the game across companion events + venues (moneyline, spreads, totals, props), deduped to one row per logical market (cross-venue siblings on matchedVenueMarkets[]).
  • Filter by the normalized enums to load one tab/section:
    • sportsMarketTypemoneyline / spread / total / prop / completion / other (completion = match-completion propositions, e.g. tennis “will the match be completed” rather than a winner market)
    • periodfull / 1h / 2h / q1..q4 / ot
    • plus lineValue (number) and sectionRank (order) on each market.

Prop tabs via marketCategory

Each market also carries a normalized marketCategory — the subject grouping for the prop tabs, orthogonal to sportsMarketType:
  • game_lines — moneyline / spreads / totals (sub-group with sportsMarketType + period)
  • exact_score, corners, goals, assists, shots — the dedicated prop tabs
  • other — recognized sports markets without a dedicated tab; null for non-sports markets
Load one prop tab the same way you load Game Lines: GET /venue-markets?aggKey={gameAggKey}&marketCategory=corners&limit=50 As with every other enum, the API exposes the category; your UI owns the tab label.
  • Compose your own tabs/labels from these enums — the API exposes data, not presentation. e.g. “Game Lines” = sportsMarketType ∈ {moneyline,spread,total}; “Halves” = period ∈ {1h,2h}.
  • Paginate large sections with cursor/limit.

3. Prices, order ticket, chart

  • Live cross-venue prices / best price: GET /orderbook/midpoints?venueMarketIds=… (the list returns last-known DB prices; midpoints are live).
  • Order ticket / smart routing (split across venues): GET /orderbook/{venueMarketOutcomeId}/route?maxSpend=…&compareVenues=true → per-venue fills[] + venueSoloQuotes[].
  • Price chart: GET /charts/bars?venueMarketOutcomeId=…&resolution=5.
Tab labels and grouping are yours to define. The API gives you normalized enums (sportsMarketType, period, lineValue, sectionRank); map them to whatever tabs your UI needs. The reference mapping lives in our demo app.