> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agg.market/llms.txt
> Use this file to discover all available pages before exploring further.

# Building a Sports Market Detail Page

> Compose the discovery, orderbook, and chart endpoints into a cross-venue game detail page

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.

<Warning>
  `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.
</Warning>

## 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:
  * `sportsMarketType` ∈ `moneyline` / `spread` / `total` / `prop` / `completion` / `other`
    (`completion` = match-completion propositions, e.g. tennis "will the match be completed"
    rather than a winner market)
  * `period` ∈ `full` / `1h` / `2h` / `q1`..`q4` / `ot`
  * plus `lineValue` (number) and `sectionRank` (order) on each market.

### Prop tabs via `marketCategory` (deprecated — use `marketGroup` instead)

<Warning>
  `marketCategory` is **deprecated** in favor of `marketGroup` (see the Fields reference below).
  It remains populated for back-compat — the soccer-only prop tabs (`corners`, `goals`, `assists`,
  `shots`) still appear there — but new code should filter by `marketGroup`.
</Warning>

Each market 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 (soccer only)
* `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`.

<Note>
  Tab labels and grouping are yours to define. The API gives you normalized enums
  (`sportsMarketType`, `marketGroup`, `period`, `lineValue`, `sectionRank`); map them to whatever
  tabs your UI needs. The reference mapping lives in our demo app.
</Note>

## Fields reference

The following fields are available on `/venue-events` and `/venue-markets` for sports content.

### `sport` (on VenueEvent)

Normalized cross-venue sport classification. `null` for non-sports events.

Closed vocabulary:

| Value               | Description                                                           |
| ------------------- | --------------------------------------------------------------------- |
| `soccer`            | Association football                                                  |
| `basketball`        | Basketball (NBA, WNBA, college, international)                        |
| `baseball`          | Baseball (MLB, international)                                         |
| `american_football` | American football (NFL, college)                                      |
| `hockey`            | Ice hockey (NHL, international)                                       |
| `tennis`            | Tennis (ATP, WTA, Grand Slams)                                        |
| `cricket`           | Cricket (Test, ODI, T20)                                              |
| `golf`              | Golf (PGA, LIV, majors)                                               |
| `mma`               | Mixed martial arts (UFC, Bellator, etc.)                              |
| `boxing`            | Boxing                                                                |
| `motorsport`        | Racing (F1, NASCAR, IndyCar, etc.)                                    |
| `esports`           | Competitive gaming (CS2, Dota 2, LoL, Valorant, Honor of Kings, etc.) |
| `table_tennis`      | Table tennis / ping pong                                              |
| `rugby`             | Rugby (union & league — Top 14, NRL, Six Nations, etc.)               |
| `volleyball`        | Volleyball                                                            |
| `pickleball`        | Pickleball (MLP, PPA)                                                 |
| `lacrosse`          | Lacrosse (PLL, NLL)                                                   |
| `aussie_rules`      | Australian rules football (AFL/AFLW)                                  |
| `other_sport`       | Any sport not in the list above                                       |

### `marketGroup` (on VenueMarket)

Sport-aware FE grouping. Use this to build per-sport tab sets. **Supersedes `marketCategory`**
for sports tabs (see note above). The `marketGroup` query parameter on `/venue-markets` accepts
any value from this set.

Closed vocabulary:

| Value          | Description                                                                                  |
| -------------- | -------------------------------------------------------------------------------------------- |
| `game_lines`   | Full-game moneyline / winner markets                                                         |
| `spreads`      | Handicap / point-spread markets                                                              |
| `totals`       | Over/under total-points or total-goals markets                                               |
| `period_lines` | Intra-game moneyline, spread, or total scoped to a period (quarter, half, inning, set, map)  |
| `exact_score`  | Exact final score markets                                                                    |
| `team_props`   | Team-level proposition markets (NRFI, first-5-innings winner, both-teams-to-score, etc.)     |
| `player_props` | Player-level proposition markets (points, rebounds, strikeouts, etc.)                        |
| `specials`     | Novelty / event-level specials (toss winner, method of victory, championship outright, etc.) |
| `completion`   | "Will this match complete?" propositions (tennis, cricket)                                   |
| `other`        | Sports markets that don't fit the groups above                                               |

### `marketSubtype` (on VenueMarket)

Lossless raw venue market type string preserved from discovery. Examples:
`cricket_toss_winner`, `nrfi`, `tennis_set_winner`, `cs2_odd_even_total_kills`,
`baseball_team_first_five_winner`, `soccer_halftime_result`, `map_handicap`.

Use `marketSubtype` to label or disambiguate rows within a `marketGroup` (e.g. render the
`nrfi` row with its proper label rather than a generic "Team Props" heading). `null` when the
venue supplies no subtype.

### `period` (on VenueMarket)

Temporal scope of the market. Expanded from the original set to cover all sports:

| Tokens                               | Description                                                  |
| ------------------------------------ | ------------------------------------------------------------ |
| `full`                               | Full game / match                                            |
| `match`                              | Alias for full match (tennis, cricket)                       |
| `series`                             | Multi-game series result                                     |
| `1h` / `2h`                          | First / second half (soccer, basketball, american\_football) |
| `q1` / `q2` / `q3` / `q4`            | Quarters (basketball, american\_football)                    |
| `period_1` / `period_2` / `period_3` | Periods (hockey)                                             |
| `inning_1` … `inning_9`              | Individual innings (baseball)                                |
| `first_5_innings`                    | First-five-innings scope (baseball)                          |
| `set_1` … `set_5`                    | Individual sets (tennis)                                     |
| `map_1` … `map_5`                    | Individual maps (esports — CS2, Dota 2, etc.)                |
| `game_1` … `game_5`                  | Individual games within a series (esports, some tennis)      |
| `ot`                                 | Overtime / extra time                                        |

## Per-sport tab matrix

Use this table as the starting point for building per-sport tab UIs. Render only the
`marketGroup` values that appear for a given `sport`; hide empty tabs.

<Note>
  Coverage reflects what venues currently list. `other` and `other_sport` are catch-alls. The set
  is venue-driven and grows as new market types are listed.
</Note>

| Sport               | marketGroups present                                                           | Notable subtypes / periods                                                                                                                                                                       |
| ------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `soccer`            | `game_lines`, `spreads`, `totals`, `period_lines`, `exact_score`, `team_props` | `soccer_halftime_result` (periods `1h`/`2h`), `soccer_exact_score`, `both_teams_to_score`; legacy corners/goals/assists/shots via `marketCategory`                                               |
| `basketball`        | `game_lines`, `spreads`, `totals`, `period_lines`, `player_props`              | quarters `q1`–`q4`; player points / rebounds / assists props                                                                                                                                     |
| `baseball`          | `game_lines`, `spreads`, `totals`, `team_props`, `player_props`                | `nrfi` (`inning_1`), `baseball_team_first_five_winner` (`first_5_innings`), strikeout / home-run player props                                                                                    |
| `american_football` | `game_lines`, `spreads`, `totals`, `period_lines`                              | quarters `q1`–`q4`, halves `1h`/`2h`                                                                                                                                                             |
| `hockey`            | `game_lines`, `spreads`, `totals`, `period_lines`                              | `period_1`–`period_3`                                                                                                                                                                            |
| `tennis`            | `game_lines`, `totals`, `spreads`, `completion`                                | `tennis_set_winner` (`set_1`–`set_5`), `tennis_first_set_totals` (`set_1`), `tennis_match_totals` (`match`), `tennis_completed_match`                                                            |
| `cricket`           | `game_lines`, `totals`, `team_props`, `player_props`, `specials`, `completion` | `cricket_toss_winner` (`specials`), `cricket_team_top_batter` / `cricket_most_sixes` (`player_props`), `cricket_completed_match`                                                                 |
| `golf`              | `game_lines`, `specials`                                                       | Outright winner, matchup markets, MVP / championship specials                                                                                                                                    |
| `mma`               | `game_lines`, `specials`                                                       | Fight winner, method-of-victory / round specials                                                                                                                                                 |
| `boxing`            | `game_lines`, `specials`                                                       | Fight winner, method / round specials                                                                                                                                                            |
| `motorsport`        | `game_lines`, `specials`                                                       | Race winner, podium specials                                                                                                                                                                     |
| `esports`           | `game_lines`, `spreads`, `totals`, `player_props`, `specials`                  | `map_handicap` (`spreads`), `cs2_odd_even_total_kills` / `kill_over_under_game` (`player_props`), `first_blood_game` / `dota2_rampage` (`specials`); periods `map_1`–`map_5` / `game_1`–`game_5` |
| `rugby`             | `game_lines`, `totals`, `specials`                                             | Match winner, draw, handicap; mostly moneyline today                                                                                                                                             |
| `volleyball`        | `game_lines`, `totals`, `specials`                                             | Match/set winner, set totals                                                                                                                                                                     |
| `pickleball`        | `game_lines`, `specials`                                                       | Match winner; mostly moneyline today                                                                                                                                                             |
| `lacrosse`          | `game_lines`, `spreads`, `totals`                                              | Moneyline / spread / total                                                                                                                                                                       |
| `aussie_rules`      | `game_lines`, `spreads`, `totals`                                              | Moneyline / line / total (AFL)                                                                                                                                                                   |

<Note>
  `sport` is resolved from the venue's league code first, then its **tags** (which carry a clean
  sport name like "Rugby" or "Volleyball"), then the title. Sports a venue lists but that aren't yet
  in the vocabulary fall to `other_sport` (still classified into `marketGroup`s) until added.
</Note>

## Filter examples

### Baseball — team props for a specific game

```
GET /venue-markets?aggKey=agg_mlb_nyy_bos_260618&marketGroup=team_props
```

Returns the team-prop markets for that game: NRFI (`nrfi`, `period=inning_1`), first-5-innings
winner (`baseball_team_first_five_winner`, `period=first_5_innings`), and any other team-level
propositions available across venues. Each row's `matchedVenueMarkets[]` contains the cross-venue
pairings so you can show the best price without a second request.

### Tennis — set and match totals

```
GET /venue-markets?aggKey=agg_atp_djokovic_sinner_260618&marketGroup=totals
```

Returns all over/under totals for the match: per-set totals (`period=set_1`, `period=set_2`, …)
and full-match totals (`period=match`). Use `marketSubtype` to distinguish the rendering:
`tennis_first_set_totals` gets a "First Set" label; `tennis_match_totals` gets "Match Total".
