Historical sports betting data is a record of past prices: which book offered what odds on which market, and when. It's what you test a model against, measure closing line value with, and study line movement from. A results table alone isn't enough, because a model is only useful if it beats the prices that were really on offer at the time.
The value of an odds archive depends almost entirely on its timestamps and its honesty about gaps. Before you trust one, you need to know when each price was observed, which book it came from, whether the "opening" and "closing" labels mean what you think, and what's missing. This guide covers those checks, then says exactly what ZippyOddsAPI's history endpoint holds and what it doesn't.
What historical odds are used for
- Backtesting a model. Compare your model's probability with the price you could have bet before the game. This needs pre-game prices with reliable times.
- Closing line value. Compare the price you took with the last price before the start. This needs a closing price you trust.
- Studying line movement. How a market moved from first price to close, and how fast books copied each other.
- Choosing a fair reference. Testing which book's no-vig price best predicted results, so you know whose line to trust.
Each use needs something different from the data, so check the archive against the use, not in general.
What to check in any archive
Timestamps
Every price should carry the time it was observed. Ask what that time means: when the book changed the price, when a collector read it, or when it was written to the database? These can be minutes apart, and in a fast market minutes matter.
Also ask how often prices were read. An archive that sampled every hour can't tell you what was available ten minutes before the start.
Opening versus closing
"Opening line" is often the first price the archive saw, not the first price the book posted. If collection started late, the "open" is really a mid-market price. "Closing line" is just as slippery: is it the last price before the scheduled start, the last before the actual start, or the last the archive happened to read? For closing line value you want the last pre-game price, read close to the start.
Which book
Different books are useful for different things. A sharp book's prices make a good fair reference. A retail book's prices tell you what was actually available to bet. A consensus of several books smooths out one book's mistakes. Make sure the archive names the book for each price, rather than blending them into one number you can't trace.
Survivorship and gaps
Check what's missing. Archives often drop markets that were taken down, games that were postponed, and books that stopped being collected. A backtest on what survived can look better than reality, because the awkward cases are gone. Ask how voids, suspensions and line changes are recorded.
The line itself
A spread or total price only means something with its line. A -110 at 224.5 and a -110 at 225.5 are different bets. Make sure every point records the line, and that a line move doesn't overwrite the old line's history.
Historical Pinnacle odds
Pinnacle is widely used as a sharp reference, so historical pinnacle odds are a common request for testing models and measuring closing line value. The checks above apply with extra force. Ask how often the source read Pinnacle, how old each copy could be when it was read, and whether the closing price was taken near the start or just at the last read.
Pinnacle's own terms decide what may be done with its prices. Read them, and be wary of any archive of pinnacle historical odds that can't say where its data came from or when each point was observed.
What ZippyOddsAPI's history holds
ZippyOddsAPI's /v1/history endpoint returns one market's prices over time. Its documented limits:
- 30 days. Points are kept for 30 days. It is not a multi-season archive.
- Main full-game markets only. Only full-game moneyline, spread and total markets have history. Anything else returns
404 history_not_found. - A point per change. A point is stored each time the market changes, not on a fixed clock.
- One line per market. The line is part of the market's id. If a total moves from 224.5 to 225.5, the older line is a different
market_idwith its own history. - 3 credits a request. History is available on any plan.
You ask for it by market_id, or by event_id and book with an optional market (moneyline by default) and period (full game by default):
curl -s "https://zippyoddsapi.com/v1/history?event_id=evt_0h7k2m9q4x1tzb&book=prophetx&market=total" \
-H "Authorization: Bearer $ZIPPYODDS_KEY"
The answer has open, current and points. Each carries a time t, the line and the prices for each side, and points holds every stored point in time order. With event_id and book, you get that book's market that changed most recently.
Two cautions from the checks above. open is the first point stored for that market, so treat it as the first observation, not proof of the book's first posted price. And a book only has history for the time it was actually feeding: the coverage page shows which books are feeding now, and a book on the list is not a promise of prices.
If you need more than 30 days, store it yourself. Poll /v1/history or the current odds on a schedule and keep every point with its observed time. Our guide to a sports betting database covers a schema for that.
Results are a separate job
Odds history tells you the prices. It doesn't settle the bets. You need results from a source you trust, settled the way each market settles: overtime included or not, voids, pushes. ZippyOddsAPI's documentation notes that its /v1/scores endpoint lists games in progress and has no finished games to return, so final results have to come from elsewhere.
Putting it to use
With prices and results joined, you can test a model properly. Our guide to the sports betting model covers calibration, closing line value and out-of-sample testing, and our overview of sports betting data covers the other kinds of data a model can use. The API docs give every history field and how to ask the operator for a key.