Odds Data API for Sports Betting Models & Backtesting

Sports betting machine learning data API with historical odds, no-vig fair odds labels, and built-in bet settlement for training and backtesting models.

Updated June 2026Built on the live SportsGameOdds feed
How it works
  1. 1
    Feature engineering

    Use the de-vigged fairOdds as a baseline probability feature, derive open-to-close movement with includeOpenCloseOdds=true, and measure book disagreement from the spread of prices in byBookmaker, all joined on the normalized oddID.

  2. 2
    Labels and ground truth

    Once an event is finalized, grade each market from its score field against closeOverUnder for totals, the spread line for sides, or the moneyline result, to produce win, push, or loss labels without a second results API.

  3. 3
    Backtesting against closing line value (CLV)

    Check whether the prices a strategy would have taken consistently beat the de-vigged closing fairOdds, then pair that leading CLV signal with realized results from score to measure ROI.

To build or backtest a sports betting model you need two things in the same place: labeled features and ground-truth outcomes. SportsGameOdds carries both in one schema across 85+ bookmakers and 67+ leagues: opening and closing lines per bookmaker, no-vig fairOdds as a probability label, and a per-bet score settlement field for the result. You can engineer features, attach labels, and run a backtest without bolting on a second results or stats API.

Why use SportsGameOdds for betting models

  • Odds and outcomes live in one schema. Every odd object carries a score result plus started and ended flags, so the feature you train on and the outcome you grade against come pre-joined. There's no second results API to license, match, and reconcile.
  • fairOdds is a ready-made probability label. fairOdds, fairSpread, and fairOverUnder are the no-vig consensus across books, while bookOdds keeps the vig in. The de-vigged consensus is the market's implied probability, usable as a target, a feature, or a baseline to beat.
  • Opening and closing lines come from one flag. Set includeOpenCloseOdds=true and each book returns its open and close per market, giving you line-movement and steam features without polling and snapshotting the feed yourself.
  • score settlement is built-in ground truth. The same field that grades a bet labels your training row. Over/under, spread, and moneyline outcomes all settle from the result attached to each odd, at every plan tier.
  • Normalized oddID makes joins clean. One consistent oddID identifies the same market across every book and league, so cross-book and cross-sport joins don't need per-source string matching.
  • First-class SDKs, including Python. Official SDKs for Python, JavaScript/TypeScript, Ruby, Go, and Java, plus an MCP server, drop the feed straight into a notebook or training pipeline.

Building and backtesting a model with our data

With a betting model, the algorithm is rarely where projects stall. The hard part is assembling a clean, leakage-free dataset where features and outcomes line up. Here is how the schema maps to each stage.

Feature engineering

Start from the consensus. fairOdds (and fairOverUnder / fairSpread) gives you the de-vigged market probability for each market, a strong baseline feature and a sane prior. Layer movement on top: with includeOpenCloseOdds=true, each book exposes its openOdds/closeOdds and openOverUnder/closeOverUnder, so you can derive open-to-close drift, the magnitude and direction of the move, and which way the market steamed. Finally, measure disagreement: the spread of prices inside byBookmaker for a single oddID tells you how much books diverge, which is often more predictive than any single price. Because every record shares the normalized oddID, these features join cleanly across books and leagues.

Labels and ground truth

Your label is already in the payload. Each odd carries a score result and started/ended flags, so once an event is finalized you can grade the market directly. Compare score to closeOverUnder for a total, to the spread line for a side, or to the moneyline result. That gives you a binary win/push/loss label, or a continuous margin if you'd rather regress on it. No separate stats feed, and no fuzzy team-name matching between an odds provider and a results provider.

Backtesting against closing line value (CLV)

Closing line value, how your bet's price compares to the closing line, is the single best public proxy for long-term edge, because the closing line is the sharpest the market gets. With open and close captured per book and a no-vig fairOdds close, you can backtest a strategy by checking whether the prices it would have taken consistently beat the de-vigged closing number. Pair that with the score settlement to measure realized ROI, and you have both the leading indicator (CLV) and the lagging one (actual results) from the same dataset. Historical depth for these backtests is available on Pro plans and above.

Example request

import requests

API_KEY = "YOUR_API_KEY"

resp = requests.get(
    "https://api.sportsgameodds.com/v2/events",
    params={
        "leagueID": "NBA",
        "finalized": "true",            # settled games -> labels
        "includeOpenCloseOdds": "true", # open + close per book
        "limit": 100,
    },
    headers={"x-api-key": API_KEY},
)

events = resp.json()["data"]

Each market in an event's odds map arrives with its consensus, its per-book open/close, and its result, with features and label together:

{
  "points-all-game-ou-over": {
    "oddID": "points-all-game-ou-over",
    "fairOdds": "-103",
    "fairOverUnder": "224.5",
    "bookOdds": "-110",
    "score": 229,
    "started": true,
    "ended": true,
    "byBookmaker": {
      "draftkings": {
        "available": true,
        "odds": "-110",
        "overUnder": "224.5",
        "openOdds": "-115",
        "openOverUnder": "223.5",
        "closeOdds": "-108",
        "closeOverUnder": "224.5"
      }
    }
  }
}

Here the de-vigged fairOverUnder (224.5) is your probability-weighted line, the DraftKings openOverUnder to closeOverUnder move (223.5 to 224.5) is a line-movement feature, and score (229) settles the Over, your ground-truth label. See the docs and the handling odds guide for the full field reference.

SportsGameOdds vs assembling a dataset yourself

What you needSportsGameOddsScrape odds + source results separately
Odds + outcomes in one schemaYes, score/settlement on every oddTwo systems: an odds scraper plus a separate results/stats API
No-vig fair oddsBuilt in (fairOdds / fairSpread / fairOverUnder)You de-vig yourself, per book, per market
Opening & closing linesOne flag: includeOpenCloseOdds=true, per bookSnapshot and store every poll yourself
Normalized IDsOne oddID across books, sports, and leaguesReconcile each book's naming and team IDs
Historical depthYes (Pro+)Build and maintain your own archive
Join / cleaning effortMinimal, records arrive pre-joinedHigh: ETL, dedupe, matching, settlement logic

Frequently asked questions

Related use cases

Ready to build your model?

Free plan available. Set up in 5 minutes. No credit card required.