Historical Odds Data API

A historical odds data API with opening and closing lines per book, no-vig fair odds, and settled results across 85+ books, built for backtesting, CLV, and line-movement research.

Updated June 2026Built on the live SportsGameOdds feed
How it works
  1. 1
    Acquire finalized events with open and close

    Query /v2/events with finalized=true and includeOpenCloseOdds=true, scoped by leagueID and a startsAfter and startsBefore window, paging with cursor until nextCursor is empty.

  2. 2
    Derive line-movement and CLV features

    Read each book's openOdds, closeOdds, openOverUnder, and closeOverUnder from byBookmaker to compute open-to-close drift, and use the no-vig fairOdds close as the sharpest probability estimate for CLV.

  3. 3
    Grade and measure realized results

    Once an event is finalized, grade each market from its score (against closeOverUnder for totals, the spread line for sides, or the moneyline result) to label outcomes and measure realized ROI.

A historical odds data API serves past sports odds (opening and closing lines, the prices that moved in between, and how each market settled) as structured records you can query and join rather than scrape and reconstruct. SportsGameOdds gives you exactly that in one feed: per-book openOdds/closeOdds and openOverUnder/closeOverUnder via includeOpenCloseOdds=true, no-vig fairOdds as the consensus, and a score settlement value on every odd, across 85+ books and 67+ leagues. Historical depth is available on the Pro plan and above.

Why build your odds history on SportsGameOdds

  • Opening and closing lines come from one flag. Set includeOpenCloseOdds=true and each book in byBookmaker returns its openOdds/closeOdds and openOverUnder/closeOverUnder (plus openSpread/closeSpread), so you get the full open-to-close move per market without polling and snapshotting the feed yourself.
  • No-vig fairOdds history is built in. fairOdds, fairSpread, and fairOverUnder are the de-vigged consensus across books, while bookOdds keeps the vig in. Your historical records carry the market's implied probability, not just the prices a single book was showing.
  • score settlement is ground-truth labels. Every odd carries a score result plus started/ended flags, and status.finalized marks the event done. The same field that grades a bet also labels each backtest row, so there's no second results or stats API to license and reconcile.
  • Normalized oddID makes joins clean. One consistent oddID (format {statID}-{statEntityID}-{periodID}-{betTypeID}-{sideID}) identifies the same market across every book and league, so cross-book and cross-sport joins don't need per-source string matching.
  • Line-movement features come pre-assembled. Open-to-close drift, the magnitude and direction of the move, and the spread of prices inside byBookmaker for a single oddID are all derivable from the same payload. That's the raw material for line-movement history and steam research.
  • Sharp anchors are named explicitly. byBookmaker keys like pinnacle and circa let you benchmark your closing line value against the sharpest books on the board, alongside draftkings, fanduel, betmgm, bet365, and caesars.

How an odds-history backtest works with our data

Most backtests stall on data, not strategy. You need a clean, leakage-free dataset where prices, the lines they closed at, and the result all line up, and assembling that is most of the work. Here is how the schema maps to each stage.

Acquire finalized events with open and close

Query /v2/events with finalized=true and includeOpenCloseOdds=true, scoped by leagueID and a date window via startsAfter/startsBefore. Page through with cursor until nextCursor is empty, and every market under event.odds arrives with its consensus, its per-book open and close, and its result attached. It's one feed and one schema, with no separate archive to stand up.

Derive line-movement and CLV features

Read each book's openOdds/closeOdds and openOverUnder/closeOverUnder out of byBookmaker to compute open-to-close drift and which way the market steamed. The no-vig fairOdds close is your sharpest probability estimate, so a strategy's closing line value, meaning how the price it would have taken compares to the de-vigged close, falls straight out of the same records. Because every row shares the normalized oddID, these features join cleanly across books, sports, and leagues.

Grade and measure realized results

Once an event is finalized, grade the market directly from score: compare it to closeOverUnder for a total, to the spread line for a side, or to the moneyline result, to produce a win/push/loss label. Pair that lagging signal with the leading one (CLV) and you have both edges of the picture, predicted edge and realized ROI, from a single dataset. There's no fuzzy team-name matching between an odds provider and a results provider.

Example request

curl "https://api.sportsgameodds.com/v2/events?leagueID=NBA&finalized=true&includeOpenCloseOdds=true" \
  -H "x-api-key: YOUR_API_KEY"

A trimmed market from the response carries its no-vig consensus, the per-book open and close, and the score it settled against, putting features and label in one object:

{
  "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": {
      "pinnacle": {
        "available": true,
        "odds": "-105",
        "overUnder": "224.5",
        "openOdds": "-110",
        "openOverUnder": "222.5",
        "closeOdds": "-104",
        "closeOverUnder": "224.5"
      }
    }
  }
}

Here Pinnacle's openOverUnder to closeOverUnder move (222.5 to 224.5) is a two-point line-movement feature, the de-vigged fairOverUnder (224.5) is your sharpest implied line, and score (229) settles the Over as a win, your ground-truth label. See the docs and the handling odds guide for the full grading walkthrough.

SportsGameOdds vs building your own odds archive

What you needSportsGameOddsScrape and store odds history yourself
Opening & closing linesOne flag: includeOpenCloseOdds=true, per bookSnapshot and store every poll, per book, forever
No-vig fair oddsBuilt in (fairOdds / fairSpread / fairOverUnder)De-vig yourself, per book, per market
Settled resultsscore on every odd, graded via closeOverUnderSource and reconcile a separate results feed
Normalized IDsOne oddID across books, sports, and leaguesReconcile each book's market and team naming
Cross-book joinsShared oddID lines every book upPer-source string matching and dedupe
Historical depthPro plan and aboveBuild and maintain your own archive from day one
MaintenanceOne feed; we absorb book-side changesRe-fix breakage every time a book changes its feed

Building your own archive is a reasonable path, and it gives you full control over schema and retention. What it costs you is the years of clean, deduped snapshots you'd need before a backtest is even possible, plus the settlement layer to grade them. SportsGameOdds pre-assembles open, close, fair odds, and results so the dataset is ready to query.

Frequently asked questions

Related use cases

Backtest on historical odds

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