# Odds data schema Sample file: `odds/data/samples/boxing_odds.json` Source: [The Odds API](https://the-odds-api.com/) v4 — `GET /sports/{sport}/odds` ## Top level The response is a **JSON array** of event objects. ```json [ { "id": "7605c958b8ffbe29c0dcb81e4d2c8a10", "sport_key": "boxing_boxing", "sport_title": "Boxing", "commence_time": "2025-05-10T16:00:00Z", "home_team": "Charlie Senior", "away_team": "Cesar Ignacio Paredes", "bookmakers": [ ... ] } ] ``` ## Event fields | Field | Type | Description | |-------|------|-------------| | `id` | string | Unique event id | | `sport_key` | string | API sport identifier | | `sport_title` | string | Human-readable sport name | | `commence_time` | ISO 8601 UTC | Scheduled start | | `home_team` | string | Home / first fighter name | | `away_team` | string | Away / second fighter name | | `bookmakers` | array | List of books offering lines on this event | ## Bookmaker object | Field | Type | Description | |-------|------|-------------| | `key` | string | Bookmaker slug (e.g. `unibet_uk`) | | `title` | string | Display name | | `last_update` | ISO 8601 | When this book’s lines were updated | | `link` | string \| null | Deep link to event on book site | | `sid` | string \| null | Book-specific event id | | `markets` | array | Markets offered for this event | ## Market object | Field | Type | Description | |-------|------|-------------| | `key` | string | Market type: `h2h` (moneyline), `h2h_lay` (exchange lay), etc. | | `last_update` | ISO 8601 | Market update time | | `outcomes` | array | Selections and prices | ## Outcome object | Field | Type | Description | |-------|------|-------------| | `name` | string | Fighter name or `Draw` | | `price` | number | **Decimal** odds (European format) | | `link` | string \| null | Selection deep link | | `sid` | string \| null | Selection id at book | | `bet_limit` | number \| null | Max stake if provided | ## Implied probability (for arbitrage) For decimal odds `d`: ``` implied_probability = 1 / d ``` For a **single** book’s full market (all mutually exclusive outcomes), sum of implied probabilities > 1 indicates book margin (overround). **Cross-book arbitrage** (simplified): for each outcome, take the **best** (highest) decimal odds across books, then: ``` arb_sum = sum(1 / best_odds_i for each outcome i) ``` If `arb_sum < 1`, a risk-free profit is theoretically possible before fees and limits. ## Normalized row (recommended for future code) | Column | Example | |--------|---------| | `event_id` | `7605c958...` | | `commence_time` | `2025-05-10T16:00:00Z` | | `home_team` | `Charlie Senior` | | `away_team` | `Cesar Ignacio Paredes` | | `bookmaker_key` | `unibet_uk` | | `market_key` | `h2h` | | `outcome_name` | `Charlie Senior` | | `price` | `1.03` | | `implied_prob` | `0.9709` | ## API usage notes - Responses count against your API quota; check response headers `x-requests-remaining`. - Region and market query params filter payload size; sample uses `uk,eu` and `h2h`. - Prices are decimal in this project (`oddsFormat=decimal` in fetch script).