V1GameOdds

Odds lines (market + model)

Time-series odds lines, newest first — the derived market line (`source: "eo_market"`) and the proprietary model line (`source: "eo_model"`; ADR 0009). With `?match={id}` the response is that match's line history, and `?cursor=` pages through it. **Without `?match=` the default is a bulk snapshot** — the latest line per source per open market across the game, the product's headline endpoint for pulling a whole slate in one call; the snapshot is a single page, so it **ignores `?cursor=`** (its `next_cursor` is always null). The movement fields (`open_price`, `delta_since_open`) are computed per response from the line's own series. Market rows appear once the multi-book scrape runs (`EXPOSE_MARKET_ODDS`; at least 2 contributing books per line); model rows only after the model's validation gate clears (`EXPOSE_MODEL_ODDS`) — before then model rows are simply absent, never faked. Raw per-book bookmaker rows are never returned (see the top-level description). **Markets & the `line` field.** Beyond match winner, the endpoint serves the derived line for additional markets as multi-book coverage arrives: `total_maps` (`outcome_key` `over`/`under`, `line` = the games threshold, e.g. `2.5`), `map_handicap` (`outcome_key` `home`/`away`, `line` = the **home team's signed handicap**, e.g. `-1.5`, carried by both complementary legs), and per-map `map_winner`. Because markets are distinguished by `line` as well as market and outcome, the **bulk snapshot may return more than one row per `market_id`** — one per distinct `line`. Each row is still the latest per `(market, outcome, line, source)`.

GET
/v1/{game}/odds

Time-series odds lines, newest first — the derived market line (source: "eo_market") and the proprietary model line (source: "eo_model"; ADR 0009). With ?match={id} the response is that match's line history, and ?cursor= pages through it. Without ?match= the default is a bulk snapshot — the latest line per source per open market across the game, the product's headline endpoint for pulling a whole slate in one call; the snapshot is a single page, so it ignores ?cursor= (its next_cursor is always null). The movement fields (open_price, delta_since_open) are computed per response from the line's own series. Market rows appear once the multi-book scrape runs (EXPOSE_MARKET_ODDS; at least 2 contributing books per line); model rows only after the model's validation gate clears (EXPOSE_MODEL_ODDS) — before then model rows are simply absent, never faked. Raw per-book bookmaker rows are never returned (see the top-level description).

Markets & the line field. Beyond match winner, the endpoint serves the derived line for additional markets as multi-book coverage arrives: total_maps (outcome_key over/under, line = the games threshold, e.g. 2.5), map_handicap (outcome_key home/away, line = the home team's signed handicap, e.g. -1.5, carried by both complementary legs), and per-map map_winner. Because markets are distinguished by line as well as market and outcome, the bulk snapshot may return more than one row per market_id — one per distinct line. Each row is still the latest per (market, outcome, line, source).

Authorization

AuthorizationBearer <token>

Primary auth (live). Authorization: Bearer <api-key> — the header takes precedence over the query fallback. The raw key is hashed (SHA-256, hex) and looked up in api.keys.key_hash; the raw value is never stored.

In: header

Path Parameters

game*string

Game slug. cs2 is the only populated title today; an un-onboarded game 404s cleanly.

Query Parameters

match?string

Scope to one match's line history (UUID). Omit for the bulk snapshot.

Formatuuid
source?string

Filter to one served source. Omit for both.

Value in

  • "eo_market"
  • "eo_model"
limit?integer

Page size. Clamped to a per-resource maximum; cursor carries the page position.

Range1 <= value
Default100
cursor?string

Opaque forward pagination cursor — pass the previous page's meta.next_cursor verbatim. Omit for the first page. Never construct one by hand.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/cs2/odds"
{  "data": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "match_id": "89006248-1085-4089-ad02-d2cbc517e718",      "tournament_id": "4f5acba7-e5ad-4a94-a930-e70660e2e15d",      "market_id": "6364d859-8e1b-477a-bacc-de8305a9292b",      "source": "eo_market",      "model_version": "v1",      "book_count": 4,      "outcome_key": "home",      "label": "NAVI",      "participant_type": "team",      "participant_id": "78084e63-1c1c-45af-adf1-2af96784867b",      "line": 0,      "price": 0,      "is_winner": true,      "is_closing": true,      "open_price": 0,      "delta_since_open": 0,      "captured_at": "2019-08-24T14:15:22Z"    }  ],  "meta": {    "count": 0,    "next_cursor": "string"  }}
{  "error": {    "code": "not_found",    "message": "not found",    "request_id": "018f9c7e-8b2a-7e3d-9f10-2a4b6c8d0e1f"  }}
{  "error": {    "code": "not_found",    "message": "not found",    "request_id": "018f9c7e-8b2a-7e3d-9f10-2a4b6c8d0e1f"  }}
{  "error": {    "code": "not_found",    "message": "not found",    "request_id": "018f9c7e-8b2a-7e3d-9f10-2a4b6c8d0e1f"  }}
{  "error": {    "code": "not_found",    "message": "not found",    "request_id": "018f9c7e-8b2a-7e3d-9f10-2a4b6c8d0e1f"  }}