{"openapi":"3.1.0","info":{"title":"Betting Data API","description":"Normalized sports odds + real-time signals for developers.\n\nMulti-book coverage across 20+ sports — NBA, MLB, NFL, NHL, NCAAB, NCAAF, WNBA, UFC, MLS, EPL, Champions League, La Liga, Bundesliga, Serie A, Ligue 1, Liga MX, Eredivisie, Championship, Europa League, Cricket, Boxing, Tennis, and Euroleague — with near real-time updates from 50+ sportsbooks including Pinnacle.\n\n**Markets:** h2h (moneyline), spreads, and totals are returned by default. Filter with `?markets=` on `/odds/`. MMA/UFC returns h2h + totals only (no spreads).\n\n**Quick Start** — get live odds in seconds:\n\n```\ncurl https://api.bettingdataapi.com/odds/?sport_key=basketball_nba \\\n  -H \"x-api-key: YOUR_API_KEY\"\n```","contact":{"name":"Betting Data API","url":"https://bettingdataapi.com/","email":"hello@bettingdataapi.com"},"version":"3.0.0"},"servers":[{"url":"https://api.bettingdataapi.com","description":"Production"}],"paths":{"/sports/":{"get":{"tags":["Core Data"],"summary":"List Sports","description":"Return the list of supported sports.\n\n**No API key required** to browse the catalog — each sport carries a\n`min_tier` field (Free / Pro / Business) so you can see availability\nbefore signing up. With a valid key, the list is filtered to the sports\nyour tier can access (unchanged behavior).\n\n**Free tier:** NFL + NBA + MLB only · **Pro/Business:** 20+ sports including NBA, MLB, NFL, NHL, NCAAB, NCAAF, WNBA, UFC, MLS, EPL, Champions League, La Liga, Bundesliga, Serie A, Ligue 1, Liga MX, Eredivisie, Championship, Cricket, Boxing, Tennis, Euroleague, Europa League","operationId":"ListSports","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key (optional for this endpoint)","title":"X-Api-Key"},"description":"Your API key (optional for this endpoint)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/sports/{sport_key}":{"get":{"tags":["Core Data"],"summary":"Get Sport","description":"Return details for a specific sport.\nReturns 404 if the sport doesn't exist or isn't available for this tier.\n404 (not 403) is intentional — don't confirm a sport exists to a tier\nthat can't access it.","operationId":"GetSport","parameters":[{"name":"sport_key","in":"path","required":true,"schema":{"type":"string","title":"Sport Key"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/events/":{"get":{"tags":["Core Data"],"summary":"List Events","description":"Return cached event summaries for the given sport.","operationId":"ListEvents","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Required. Use /sports/ for the full list. Examples: basketball_nba, baseball_mlb, americanfootball_nfl, icehockey_nhl, basketball_ncaab, basketball_wnba, americanfootball_ncaaf, soccer_epl, soccer_uefa_champs_league, soccer_spain_la_liga, soccer_mexico_ligamx, cricket, boxing_boxing, tennis, and more (20+ sports)","title":"Sport Key"},"description":"Required. Use /sports/ for the full list. Examples: basketball_nba, baseball_mlb, americanfootball_nfl, icehockey_nhl, basketball_ncaab, basketball_wnba, americanfootball_ncaaf, soccer_epl, soccer_uefa_champs_league, soccer_spain_la_liga, soccer_mexico_ligamx, cricket, boxing_boxing, tennis, and more (20+ sports)"},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter to a single event","title":"Event Id"},"description":"Optional. Filter to a single event"},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/odds/":{"get":{"tags":["Core Data"],"summary":"List Odds","description":"Return normalized odds from multiple sportsbooks for the given sport.\n\n**Live feed:** returns upcoming and in-play games only; finished games\nroll off the feed. Each game's start time is the `start_time` field\n(ISO 8601 UTC). To pull a specific day's full slate regardless of when\nyou poll, use `commenceTimeFrom` / `commenceTimeTo` (they filter on\n`start_time`). For games that have already concluded, use\n`/historical/odds` (Business tier).\n\n**Markets:** h2h (moneyline), spreads, totals. All three are returned\nby default. Use `?markets=h2h` or `?markets=spreads,totals` to filter.\nNote: MMA/UFC returns h2h + totals only (no spreads — fighter spreads\nare not a standard US market).\n\n**Free tier:** NFL + NBA + MLB, h2h only · **Pro:** 20+ sports, main markets (h2h, spreads, totals) · **Business:** all sports and markets","operationId":"ListOdds","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Required. Use /sports/ for the full list. Examples: basketball_nba, baseball_mlb, americanfootball_nfl, icehockey_nhl, basketball_ncaab, basketball_wnba, americanfootball_ncaaf, soccer_epl, soccer_uefa_champs_league, soccer_spain_la_liga, soccer_mexico_ligamx, cricket, boxing_boxing, tennis, and more (20+ sports)","title":"Sport Key"},"description":"Required. Use /sports/ for the full list. Examples: basketball_nba, baseball_mlb, americanfootball_nfl, icehockey_nhl, basketball_ncaab, basketball_wnba, americanfootball_ncaaf, soccer_epl, soccer_uefa_champs_league, soccer_spain_la_liga, soccer_mexico_ligamx, cricket, boxing_boxing, tennis, and more (20+ sports)"},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter to a single event.","title":"Event Id"},"description":"Optional. Filter to a single event."},{"name":"markets","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Comma-separated list of markets to include. One or more of: h2h, spreads, totals. Defaults to all available markets.","title":"Markets"},"description":"Optional. Comma-separated list of markets to include. One or more of: h2h, spreads, totals. Defaults to all available markets."},{"name":"regions","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Comma-separated list of bookmaker regions to include. One or more of: us, uk, eu, au. Defaults to all regions (every book the sport has).","title":"Regions"},"description":"Optional. Comma-separated list of bookmaker regions to include. One or more of: us, uk, eu, au. Defaults to all regions (every book the sport has)."},{"name":"bookmakers","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Comma-separated list of bookmaker keys to include. Examples: draftkings, fanduel, pinnacle, betmgm, williamhill_us. Discover the keys for a sport by reading the `book` values in an unfiltered /odds/ response for that sport — coverage varies by sport, so that is the set a filter can usefully name. An unrecognised key returns 400 naming the key that was not recognised. Composes with `regions` as an intersection.","title":"Bookmakers"},"description":"Optional. Comma-separated list of bookmaker keys to include. Examples: draftkings, fanduel, pinnacle, betmgm, williamhill_us. Discover the keys for a sport by reading the `book` values in an unfiltered /odds/ response for that sport — coverage varies by sport, so that is the set a filter can usefully name. An unrecognised key returns 400 naming the key that was not recognised. Composes with `regions` as an intersection."},{"name":"commenceTimeFrom","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Only return games starting at/after this time (ISO 8601 UTC, e.g. 2026-05-27T00:00:00Z). Filters the live upcoming/in-play feed by each game's start_time; does not return finished games (use /historical/odds for those).","title":"Commencetimefrom"},"description":"Optional. Only return games starting at/after this time (ISO 8601 UTC, e.g. 2026-05-27T00:00:00Z). Filters the live upcoming/in-play feed by each game's start_time; does not return finished games (use /historical/odds for those)."},{"name":"commenceTimeTo","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Only return games starting at/before this time (ISO 8601 UTC). Pair with commenceTimeFrom to pull a full day's slate.","title":"Commencetimeto"},"description":"Optional. Only return games starting at/before this time (ISO 8601 UTC). Pair with commenceTimeFrom to pull a full day's slate."},{"name":"oddsFormat","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Odds format for the `price` field: 'american' (default; e.g. -110, +145) or 'decimal' (e.g. 1.909, 2.45). Invalid values return 400. Currently applies to /odds/ only — other endpoints serve American.","title":"Oddsformat"},"description":"Odds format for the `price` field: 'american' (default; e.g. -110, +145) or 'decimal' (e.g. 1.909, 2.45). Invalid values return 400. Currently applies to /odds/ only — other endpoints serve American."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/best-lines/":{"get":{"tags":["Core Data"],"summary":"Get Best Lines","description":"Return best available line per outcome from cached normalized odds.","operationId":"GetBestLines","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Required. Use /sports/ for the full list. Examples: basketball_nba, baseball_mlb, americanfootball_nfl, icehockey_nhl, basketball_ncaab, basketball_wnba, americanfootball_ncaaf, soccer_epl, soccer_uefa_champs_league, soccer_spain_la_liga, soccer_mexico_ligamx, cricket, boxing_boxing, tennis, and more (20+ sports)","title":"Sport Key"},"description":"Required. Use /sports/ for the full list. Examples: basketball_nba, baseball_mlb, americanfootball_nfl, icehockey_nhl, basketball_ncaab, basketball_wnba, americanfootball_ncaaf, soccer_epl, soccer_uefa_champs_league, soccer_spain_la_liga, soccer_mexico_ligamx, cricket, boxing_boxing, tennis, and more (20+ sports)"},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter to a single event","title":"Event Id"},"description":"Optional. Filter to a single event"},{"name":"oddsFormat","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. `american` (default) or `decimal`.","title":"Oddsformat"},"description":"Optional. `american` (default) or `decimal`."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/props/":{"get":{"tags":["Player Props"],"summary":"List Props","description":"Player props for the requested sport.\n\n**Tier:** Business plan or higher. Pro keys receive a 403 with an\nupgrade pointer.\n\n**Coverage:** NFL, NCAAF, NBA, WNBA, MLB, NHL and eleven soccer leagues (EPL, La Liga, Bundesliga, Serie A, Ligue 1, Eredivisie, EFL Championship, Liga MX, MLS, UEFA Champions League, UEFA Europa League). Most markets carry an `_alternate` line ladder. Send an unknown `markets` value to get a 400 that lists the valid markets for that sport.\n\nBooks include both US (DraftKings, FanDuel, BetMGM, ...) and EU sharps\n(Pinnacle for NBA/NHL/MLB), refreshed every few minutes for events starting within 24h.\n\nThe `regions=` filter (us, uk, eu, au) is honored at the route layer and\nnarrows each market's book list to the requested regions.\n\n**Outcome shape:**\n```json\n{ \"name\": \"Over\", \"description\": \"LeBron James\",\n  \"price\": -115, \"point\": 25.5 }\n```\n`name` is \"Over\" or \"Under\"; `description` is the player.","operationId":"ListProps","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sport Key"},"description":"Required. Supported: `americanfootball_ncaaf`, `americanfootball_nfl`, `baseball_mlb`, `basketball_nba`, `basketball_wnba`, `icehockey_nhl`, `soccer_efl_champ`, `soccer_epl`, `soccer_france_ligue_one`, `soccer_germany_bundesliga`, `soccer_italy_serie_a`, `soccer_mexico_ligamx`, `soccer_netherlands_eredivisie`, `soccer_spain_la_liga`, `soccer_uefa_champs_league`, `soccer_uefa_europa_league`, `soccer_usa_mls`. Send an unsupported value to get a 400 that lists the valid ones."},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter the response to a single event.","title":"Event Id"},"description":"Optional. Filter the response to a single event."},{"name":"markets","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Comma-separated subset of the supported prop markets for the requested sport. NBA: `player_points`, `player_rebounds`, `player_assists`, `player_points_rebounds_assists`, `player_threes`, `player_blocks`, `player_steals`, `player_double_double`. NHL: `player_points`, `player_goals`, `player_assists`, `player_shots_on_goal`, `player_power_play_points`. MLB: `batter_hits`, `batter_total_bases`, `pitcher_strikeouts`, `batter_home_runs`, `batter_rbis`, `batter_runs_scored`, `batter_hits_runs_rbis`, `pitcher_outs`, `pitcher_strikeouts_alternate`. WNBA: `player_points`, `player_rebounds`, `player_assists`, `player_points_rebounds_assists`, `player_threes`, `player_blocks`, `player_steals`, `player_double_double`, `player_points_alternate`, `player_rebounds_alternate`, `player_assists_alternate`. AFL: `player_disposals_over`, `player_goals_scored_over`, `player_marks_over`, `player_tackles_over`. NRL: `player_try_scorer_first`, `player_try_scorer_last`, `player_try_scorer_anytime`, `player_try_scorer_over`. Defaults to all markets for the sport. Where a `{market}_alternate` name is accepted, requesting it returns that market's additional lines under `{market}_alternate`; `{market}` then carries the main line. Requests that do not name an `_alternate` market are unaffected.","title":"Markets"},"description":"Optional. Comma-separated subset of the supported prop markets for the requested sport. NBA: `player_points`, `player_rebounds`, `player_assists`, `player_points_rebounds_assists`, `player_threes`, `player_blocks`, `player_steals`, `player_double_double`. NHL: `player_points`, `player_goals`, `player_assists`, `player_shots_on_goal`, `player_power_play_points`. MLB: `batter_hits`, `batter_total_bases`, `pitcher_strikeouts`, `batter_home_runs`, `batter_rbis`, `batter_runs_scored`, `batter_hits_runs_rbis`, `pitcher_outs`, `pitcher_strikeouts_alternate`. WNBA: `player_points`, `player_rebounds`, `player_assists`, `player_points_rebounds_assists`, `player_threes`, `player_blocks`, `player_steals`, `player_double_double`, `player_points_alternate`, `player_rebounds_alternate`, `player_assists_alternate`. AFL: `player_disposals_over`, `player_goals_scored_over`, `player_marks_over`, `player_tackles_over`. NRL: `player_try_scorer_first`, `player_try_scorer_last`, `player_try_scorer_anytime`, `player_try_scorer_over`. Defaults to all markets for the sport. Where a `{market}_alternate` name is accepted, requesting it returns that market's additional lines under `{market}_alternate`; `{market}` then carries the main line. Requests that do not name an `_alternate` market are unaffected."},{"name":"regions","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Comma-separated list of bookmaker regions to include. One or more of: us, uk, eu, au. Defaults to all regions (every book the sport has).","title":"Regions"},"description":"Optional. Comma-separated list of bookmaker regions to include. One or more of: us, uk, eu, au. Defaults to all regions (every book the sport has)."},{"name":"oddsFormat","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. `american` (default) or `decimal`.","title":"Oddsformat"},"description":"Optional. `american` (default) or `decimal`."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/period-markets/":{"get":{"tags":["Period Markets"],"summary":"List Period Markets","description":"Period markets — game-segment markets scoped to a portion of a game.\n\n**v1 coverage:** MLB first-5-innings (`h2h_1st_5_innings`,\n`spreads_1st_5_innings`, `totals_1st_5_innings`,\n`alternate_totals_1st_5_innings`).\n\n**Tier:** Business plan or higher. Pro keys receive a 403 with an\nupgrade pointer.\n\n**Refresh cadence:** 5 minutes during the active window\n(T-2h pregame through ~end of the 5th, T+1.5h). Outside that window\nthe cache is intentionally empty — `active_window` metadata makes the\n\"no games right now\" vs \"outage\" distinction explicit.\n\n**Books:** US sportsbooks plus Pinnacle (via us+eu region pull) as the\nsharp anchor for line comparison.\n\n**Response shape:**\n```json\n{\n  \"success\": true,\n  \"source\": \"cache\",\n  \"data\": [\n    {\n      \"event_id\":   \"...\",\n      \"home_team\":  \"...\",\n      \"away_team\":  \"...\",\n      \"start_time\": \"...\",\n      \"markets\": [\n        { \"market\": \"totals_1st_5_innings\",\n          \"books\": [ { \"book\": \"pinnacle\", \"outcomes\": [...] }, ... ] }\n      ]\n    }\n  ],\n  \"active_window\": {\n    \"start\": \"<ISO>\",\n    \"end\":   \"<ISO>\",\n    \"events_in_window\": 0,\n    \"next_event_at\":    \"<ISO|null>\"\n  }\n}\n```","operationId":"ListPeriodMarkets","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Required. Supported in v1: `baseball_mlb` (first-5-innings markets). More sports added based on demand.","title":"Sport Key"},"description":"Required. Supported in v1: `baseball_mlb` (first-5-innings markets). More sports added based on demand."},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter the response to a single event.","title":"Event Id"},"description":"Optional. Filter the response to a single event."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/additional/":{"get":{"tags":["Additional Markets"],"summary":"List Additional Markets","description":"Additional markets — soccer match-level markets beyond the standard\nh2h / spreads / totals trio.\n\n**v1 coverage:** World Cup 2026 (`soccer_fifa_world_cup`) with\n`btts` (both teams to score), `double_chance` (1X / X2 / 12), and\n`draw_no_bet` (match winner, draw refunds stake).\n\n**Tier:** Business plan or higher. Pro keys receive a 403 with an\nupgrade pointer.\n\n**Refresh cadence:** 60 seconds during the active window\n(T-12h pregame through ~T+2h in-play). Outside that window the cache\nis intentionally empty — `active_window` metadata makes the\n\"no games right now\" vs \"outage\" distinction explicit.\n\n**Books:** US + UK + EU sportsbooks. Coverage varies by market —\nbtts has the widest book coverage (~16 books on a typical event),\ndraw_no_bet and double_chance are thinner (~10-11 books each).\n\n**Response shape:**\n```json\n{\n  \"success\": true,\n  \"source\": \"cache\",\n  \"data\": [\n    {\n      \"event_id\":   \"...\",\n      \"home_team\":  \"...\",\n      \"away_team\":  \"...\",\n      \"start_time\": \"...\",\n      \"markets\": [\n        { \"market\": \"btts\",\n          \"books\": [ { \"book\": \"pinnacle\", \"outcomes\": [...] }, ... ] }\n      ]\n    }\n  ],\n  \"active_window\": {\n    \"start\": \"<ISO>\",\n    \"end\":   \"<ISO>\",\n    \"events_in_window\": 0,\n    \"next_event_at\":    \"<ISO|null>\"\n  }\n}\n```","operationId":"ListAdditionalMarkets","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Required. Supported in v1: `soccer_fifa_world_cup` (btts, double_chance, draw_no_bet).","title":"Sport Key"},"description":"Required. Supported in v1: `soccer_fifa_world_cup` (btts, double_chance, draw_no_bet)."},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter the response to a single event.","title":"Event Id"},"description":"Optional. Filter the response to a single event."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/me/":{"get":{"tags":["Account"],"summary":"Get My Info","operationId":"GetMyInfo","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/me/usage":{"get":{"tags":["Account"],"summary":"Get My Usage","description":"Dashboard payload — everything the /me.html usage dashboard renders.\n\nAuth-only, zero quota cost (same policy as /me: a customer over their\nlimit must still be able to see WHY). Read-only aggregates; no raw keys\nor query params are ever returned.\n\nResponse `data`:\n  tier, requests_today, daily_limit, remaining   (live counters)\n  monthly_quota          (as sold; null for tiers without monthly framing)\n  stats                  (30-day aggregates from your request history,\n                          cached 5 minutes;\n                          null if stats backend is unavailable — render\n                          the basic meters and hide the charts)\n    .daily[]             {day, total, ok, err}\n    .month_total         requests this calendar month\n    .endpoints[]         {endpoint, total, err, avg_ms} top 10\n    .error_rate_30d      percent\n    .avg_latency_ms_30d\n    .recent_errors[]     {status_code, endpoint, n, last_seen} top 5, 7d","operationId":"GetMyUsage","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/intelligence/arbitrage":{"get":{"tags":["Intelligence"],"summary":"Get Arbitrage","description":"Cross-book arbitrage opportunities (precomputed, refreshed with odds).\n\nEach arb is flagged with `likely_stale` when profit_pct exceeds\nSTALE_ARB_PROFIT_PCT_THRESHOLD (5%). Real cross-book arbs are typically\n0.5-3% — larger numbers usually indicate a stale line, limit-restricted\nbook, or a pricing error that will void.","operationId":"GetArbitrage","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Sport key (e.g., basketball_nba)","title":"Sport Key"},"description":"Sport key (e.g., basketball_nba)"},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/intelligence/value":{"get":{"tags":["Intelligence"],"summary":"Get Value Bets","description":"Value bets vs vig-removed soft-market consensus (precomputed).\n\n\"Value\" is a book's offered price against the vig-removed, EQUAL-WEIGHTED\nconsensus of the books that actually priced that event. Pinnacle is not\nrequired; whether it was present is reported per row and in the top-level\n`sharp_anchor` block.","operationId":"GetValueBets","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Sport key","title":"Sport Key"},"description":"Sport key"},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/intelligence/market-analysis":{"get":{"tags":["Intelligence"],"summary":"Get Market Analysis","description":"Per-event market health: hold %, efficiency, tightest/widest book (precomputed).","operationId":"GetMarketAnalysis","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Sport key","title":"Sport Key"},"description":"Sport key"},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/intelligence/edges":{"get":{"tags":["Intelligence"],"summary":"Get Edges","description":"Cross-book raw price deviations from market average (precomputed).\n\nRaw price delta WITHOUT vig removal. Included for customers who want the\nunprocessed delta for their own pipelines. For rigorous +EV signals use\n/intelligence/value instead.","operationId":"GetEdges","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Sport key","title":"Sport Key"},"description":"Sport key"},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/intelligence/fair-odds":{"get":{"tags":["Intelligence"],"summary":"Get Fair Odds","description":"Vig-removed fair prices per outcome (precomputed). H2h moneyline only today.\n\nFair probability is the vig-removed, EQUAL-WEIGHTED average across the\nbooks that actually priced each event. Pinnacle is not required; whether it\nwas present is reported per event and in the top-level `sharp_anchor` block.","operationId":"GetFairOdds","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Sport key","title":"Sport Key"},"description":"Sport key"},{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Currently supports h2h (moneyline) only. Other markets (spreads, totals, player props) return 400 with a pointer to /edges/ for prop edge detection.","title":"Market"},"description":"Optional. Currently supports h2h (moneyline) only. Other markets (spreads, totals, player props) return 400 with a pointer to /edges/ for prop edge detection."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/intelligence/consensus":{"get":{"tags":["Intelligence"],"summary":"Get Consensus","description":"Median/mean market center per outcome (precomputed). H2h moneyline only today.","operationId":"GetConsensus","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Sport key","title":"Sport Key"},"description":"Sport key"},{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Currently supports h2h (moneyline) only. Other markets (spreads, totals, player props) return 400 with a pointer to /edges/ for prop edge detection.","title":"Market"},"description":"Optional. Currently supports h2h (moneyline) only. Other markets (spreads, totals, player props) return 400 with a pointer to /edges/ for prop edge detection."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/edges/":{"get":{"tags":["Edge Detection"],"summary":"List Edges","description":"Cross-book edges vs Pinnacle (sharp anchor), precomputed.\n\n**Tier:** Business plan or higher. Pro keys receive a 403 with an\nupgrade pointer.\n\n**Edge types:**\n- `line_gap` — soft book has a different point/spread than Pinnacle.\n- `price_gap` — same line, soft book paying more than 10 cents over\n  Pinnacle.\n- `dream_combo` — line gap AND soft book paying more (rarest).\n\n**Sign convention:** `line_gap = sharp_line - soft_line`; positive\nwhen the soft book's line is lower than Pinnacle's. Whether a lower\nline is favorable depends on the bet direction — Over wants lower,\nUnder wants higher, spreads want higher numerically for the side\nbeing bet. The `direction` field is provided so callers can interpret\nthe sign correctly.\n\n**Coverage:** every sport refreshed by the scheduler. For\n`basketball_nba`, `icehockey_nhl`, and `baseball_mlb`, player-prop\nedges are merged into the same response (distinguished by `market`).\n\n**Grading:** sports where settlement results are not available\n(currently tennis and cricket) return `\"grading\": \"unavailable\"`. Their edges are still\nserved as line-comparison signals for line shopping, but are not graded\npicks with a verified hit rate.","operationId":"ListEdges","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Required. Sport key, e.g. basketball_nba, soccer_epl, baseball_mlb. Sports without Pinnacle coverage (MLS, UFC, AFL, NRL) return an empty list with a message.","title":"Sport Key"},"description":"Required. Sport key, e.g. basketball_nba, soccer_epl, baseball_mlb. Sports without Pinnacle coverage (MLS, UFC, AFL, NRL) return an empty list with a message."},{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter to one market: h2h, spreads, totals, or a player-prop market like player_points, player_rebounds, player_assists, player_points_rebounds_assists. Omit to include every market.","title":"Market"},"description":"Optional. Filter to one market: h2h, spreads, totals, or a player-prop market like player_points, player_rebounds, player_assists, player_points_rebounds_assists. Omit to include every market."},{"name":"min_edge","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Minimum edge_score to include. Default 50 — filters out market-microstructure noise. Set to 0 to include everything detected above the detection floor (>10 cents price gap OR >=0.5 point line gap).","default":50,"title":"Min Edge"},"description":"Minimum edge_score to include. Default 50 — filters out market-microstructure noise. Set to 0 to include everything detected above the detection floor (>10 cents price gap OR >=0.5 point line gap)."},{"name":"book","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Filter to a single soft book by key (e.g. draftkings, fanduel, betmgm). Case-insensitive.","title":"Book"},"description":"Optional. Filter to a single soft book by key (e.g. draftkings, fanduel, betmgm). Case-insensitive."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max edges to return. Default 50, capped at 500.","default":50,"title":"Limit"},"description":"Max edges to return. Default 50, capped at 500."},{"name":"oddsFormat","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. `american` (default) or `decimal`. Applies to both `soft_price` and `sharp_price`.","title":"Oddsformat"},"description":"Optional. `american` (default) or `decimal`. Applies to both `soft_price` and `sharp_price`."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/historical/odds":{"get":{"tags":["Historical"],"summary":"Get Historical Odds","description":"Historical odds snapshots from Betting Data API archive.\n\nReturns timestamped price snapshots for completed and in-progress events.\nData collected since 2026-05-13, capturing price changes across 20+ sports\nand 50+ sportsbooks including Pinnacle, Betfair Exchange, William Hill,\nDraftKings, FanDuel, BetMGM, and Marathonbet.\n\n**Use cases:** Backtesting, model training, line movement analysis.\n\n**Coverage:** NBA, MLB, NHL, WNBA, NCAAF, NCAAB, Tennis, Cricket, MLS,\nEPL, La Liga, Bundesliga, Serie A, Ligue 1, Eredivisie, EFL Championship,\nChampions League, Europa League, Liga MX, Euroleague, Boxing, MMA.\nMore sports added regularly.\n\n**Markets:** Standard markets (h2h, spreads, totals) for all sports.\nPlayer props for NBA (player_points, player_rebounds, player_assists,\nplayer_points_rebounds_assists), NHL (player_goals, player_shots_on_goal,\nplayer_power_play_points), MLB (batter_hits, batter_total_bases,\npitcher_strikeouts, batter_home_runs, batter_rbis, batter_runs_scored,\nbatter_hits_runs_rbis, pitcher_outs, pitcher_strikeouts_alternate), and\nWNBA alternate ladders (player_points_alternate, player_rebounds_alternate,\nplayer_assists_alternate — collected from 2026-07-21), and NFL props\n(passing, rushing, receiving, receptions, touchdowns, kicking and more —\ncollected from 2026-09-08). Pass `?market=` to\nfilter to a single market, or omit to receive all available markets for the\nsport.\n\n**Business plan required.** Free and Pro tiers return 403.\n\n**Pagination:** page with `cursor` (`meta.next_cursor`) and stop on an\nempty page. `meta.has_more` says whether rows exist beyond this page.\nWhen `meta.total_rows_exact` is true, `meta.total_rows` is the exact\ncount. When it is false, `meta.total_rows` equals\n`meta.total_rows_lower_bound`: a lower bound, never an estimate.\n\n**One market per request:** use `market=`. `markets=` is not supported\nand returns 400.\n\n**Row timestamps:** `captured_at` is when Betting Data API recorded the price\nchange. `last_update` is the bookmaker's own quote time when available\n(null on older rows).\n\n**Bookmakers:** public aliases are accepted (e.g. `caesars`), but rows are\nreturned under the canonical key (e.g. `williamhill_us`).\n\n**Coverage:** pre-match price-change history. Rows record changes, not\nremovals: a line that left the board has no closing row.","operationId":"GetHistoricalOdds","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Required. e.g., `baseball_mlb`, `basketball_nba`, `icehockey_nhl`, `soccer_epl`, etc.","title":"Sport Key"},"description":"Required. e.g., `baseball_mlb`, `basketball_nba`, `icehockey_nhl`, `soccer_epl`, etc."},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start of date range (ISO 8601). Default: 7 days ago.","title":"From"},"description":"Start of date range (ISO 8601). Default: 7 days ago."},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End of date range (ISO 8601). Default: now.","title":"To"},"description":"End of date range (ISO 8601). Default: now."},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a single event.","title":"Event Id"},"description":"Filter to a single event."},{"name":"book","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated. Use `bookmakers` instead. Single bookmaker filter (kept for backward compat).","deprecated":true,"title":"Book"},"description":"Deprecated. Use `bookmakers` instead. Single bookmaker filter (kept for backward compat).","deprecated":true},{"name":"bookmakers","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated bookmaker keys, max 3. Example: `draftkings,fanduel,betmgm`. Takes precedence over the deprecated `book` param.","title":"Bookmakers"},"description":"Comma-separated bookmaker keys, max 3. Example: `draftkings,fanduel,betmgm`. Takes precedence over the deprecated `book` param."},{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a single market. Standard: h2h, spreads, totals. Player props — NBA: player_points, player_rebounds, player_assists, player_points_rebounds_assists. NHL: player_goals, player_shots_on_goal, player_power_play_points. MLB: batter_hits, batter_total_bases, pitcher_strikeouts, batter_home_runs, batter_rbis, batter_runs_scored, batter_hits_runs_rbis, pitcher_outs, pitcher_strikeouts_alternate. WNBA alternates: player_points_alternate, player_rebounds_alternate, player_assists_alternate (collected from 2026-07-21). NFL (collected from 2026-09-08): player_pass_yds, player_pass_tds, player_pass_attempts, player_pass_completions, player_pass_interceptions, player_pass_longest_completion, player_rush_yds, player_rush_attempts, player_rush_longest, player_receptions, player_reception_yds, player_reception_longest, player_rush_reception_yds, player_pass_rush_yds, player_pass_rush_reception_yds, player_anytime_td, player_first_td, player_kicking_points, player_field_goals_made, player_tackles. Omit to receive all markets for the sport.","title":"Market"},"description":"Filter to a single market. Standard: h2h, spreads, totals. Player props — NBA: player_points, player_rebounds, player_assists, player_points_rebounds_assists. NHL: player_goals, player_shots_on_goal, player_power_play_points. MLB: batter_hits, batter_total_bases, pitcher_strikeouts, batter_home_runs, batter_rbis, batter_runs_scored, batter_hits_runs_rbis, pitcher_outs, pitcher_strikeouts_alternate. WNBA alternates: player_points_alternate, player_rebounds_alternate, player_assists_alternate (collected from 2026-07-21). NFL (collected from 2026-09-08): player_pass_yds, player_pass_tds, player_pass_attempts, player_pass_completions, player_pass_interceptions, player_pass_longest_completion, player_rush_yds, player_rush_attempts, player_rush_longest, player_receptions, player_reception_yds, player_reception_longest, player_rush_reception_yds, player_pass_rush_yds, player_pass_rush_reception_yds, player_anytime_td, player_first_td, player_kicking_points, player_field_goals_made, player_tackles. Omit to receive all markets for the sport."},{"name":"markets","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Not supported on this endpoint — returns 400. Historical odds accept one market per request via `market`.","title":"Markets"},"description":"Not supported on this endpoint — returns 400. Historical odds accept one market per request via `market`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Pagination limit (max 1000).","default":100,"title":"Limit"},"description":"Pagination limit (max 1000)."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset.","default":0,"title":"Offset"},"description":"Pagination offset."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Keyset pagination token. Pass back `meta.next_cursor` from the previous response to get the next page. O(limit) at any depth, unlike `offset`, which re-walks every preceding row. Mutually exclusive with a non-zero `offset`. Stop when a page comes back with no rows — not when a page is short.","title":"Cursor"},"description":"Keyset pagination token. Pass back `meta.next_cursor` from the previous response to get the next page. O(limit) at any depth, unlike `offset`, which re-walks every preceding row. Mutually exclusive with a non-zero `offset`. Stop when a page comes back with no rows — not when a page is short."},{"name":"oddsFormat","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. `american` (default) or `decimal`.","title":"Oddsformat"},"description":"Optional. `american` (default) or `decimal`."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/historical/settlements":{"get":{"tags":["Historical"],"summary":"Get Historical Settlements","description":"Settlement results for graded edge snapshots — each graded edge paired\nwith the final score for its event.\n\nEach row shows the original edge (soft book/price/point + sharp reference),\nthe grading result (hit/miss/push/void), the realized payout (American\nodds, 1.0 = +100), and the final score for the event.\n\n**Use cases:** Strategy backtesting, P&L attribution, edge calibration.\n\n**Coverage:** Graded edges available from 2026-04-25. Settlements are\npublished once final scores are confirmed, typically within a few hours\nof game end. Stale ungraded edges are voided after 7 days past\ncommence_time.\n\n**Business plan required.** Free and Pro tiers return 403.","operationId":"GetHistoricalSettlements","parameters":[{"name":"sport_key","in":"query","required":true,"schema":{"type":"string","description":"Required. e.g., `baseball_mlb`, `basketball_nba`, `icehockey_nhl`.","title":"Sport Key"},"description":"Required. e.g., `baseball_mlb`, `basketball_nba`, `icehockey_nhl`."},{"name":"event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a single event.","title":"Event Id"},"description":"Filter to a single event."},{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by market: h2h, spreads, or totals.","title":"Market"},"description":"Filter by market: h2h, spreads, or totals."},{"name":"result","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by grading result: hit, miss, push, or void. If omitted, void edges are excluded by default.","title":"Result"},"description":"Filter by grading result: hit, miss, push, or void. If omitted, void edges are excluded by default."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Pagination limit (max 500).","default":100,"title":"Limit"},"description":"Pagination limit (max 500)."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset.","default":0,"title":"Offset"},"description":"Pagination offset."},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","description":"Your API key","title":"X-Api-Key"},"description":"Your API key"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"Core Data","description":"Sports, events, odds, and best lines."},{"name":"Intelligence","description":"Consensus odds · Fair value · Edge detection. Business plan required."},{"name":"Edge Detection","description":"Cross-book edges vs Pinnacle (sharp anchor) — standard odds + NBA, NHL, MLB, WNBA, AFL & NRL player props. Business plan required."},{"name":"Account","description":"Your account info and usage stats."},{"name":"Historical","description":"Archived odds snapshots for backtesting and model training. Business plan required."},{"name":"Player Props","description":"Player prop markets for NFL, NCAAF, NBA, WNBA, MLB, NHL and eleven soccer leagues. Business plan required."},{"name":"Period Markets","description":"Game-segment markets (e.g., MLB first-5-innings). v1: MLB only. Business plan required."},{"name":"Additional Markets","description":"Soccer match-level markets beyond h2h/spreads/totals: btts, double_chance, draw_no_bet. v1: FIFA World Cup 2026. Business plan required."}]}