How to Get Sports Odds Data: Five Options, Compared
The realistic ways to get sports odds data, from copying lines by hand to scraping, free and paid APIs and exchange APIs, with their trade-offs. Then a step-by-step walk-through from API key to a CSV of odds.
Anyone building a model, an app or a spreadsheet around betting lines eventually asks how to get sports odds data that is accurate, current and in a shape code can use. There are five realistic routes: copying lines by hand, scraping sportsbook sites, free odds APIs, paid odds APIs, and the APIs that exchanges and prediction markets publish for their own markets. Each fits a different job.
This guide compares the five, then walks step by step from an API key to a CSV file of odds using PreciseAPI. It is about sourcing data, not about what to bet.
Start with what you need
Before choosing a source, write down six things. They settle how to get sports odds data for your project more than any feature list does:
- Leagues and books. Which sports, and which sportsbooks, exchanges or DFS apps your users or model care about. A sharp reference book such as Pinnacle matters for modeling even if nobody bets there.
- Markets. Main lines (moneyline, spread, total), player props, alternate lines, period markets, futures.
- Freshness. A daily snapshot for research, a refresh every minute for a pre-game page, or every move as it happens for in-play.
- History. Whether you need opening lines and line movement, or only the current price.
- Volume. How many requests per day your refresh plan implies.
- Use. A personal spreadsheet and a public commercial product have very different licensing needs.
Five sports odds data sources
1. Copy them by hand
Open the books' apps and type prices into a sheet. It costs nothing, and for a handful of games a week it is perfectly adequate. It stops working the moment you need more than a few dozen prices, any kind of history, or numbers that are current when you look at them. Manual entry is also where transcription errors creep into otherwise careful models.
2. Scrape sportsbook sites
Write code that reads prices from sportsbook websites. Scraping looks free, but it brings bot detection, frequent breakage when sites change, terms-of-service questions, geo-restricted boards, and the hardest part: matching the same game, player and market across books that label them differently. Our comparison of odds scraping vs odds API goes through each of those costs and the narrow cases where a scraper still makes sense.
3. Free odds APIs
Several providers offer free tiers or trials. They are shaped for evaluation: small monthly quotas, one-time credits, delayed data, restricted books or markets, or a time limit. A free tier is the right way to test a schema and write parsers, and rarely enough to run a product. Our guide to the free odds API landscape lists the common limits and what PreciseAPI's free Sandbox includes.
4. Paid odds APIs
A paid API collects prices from many books, normalizes them into one schema and sells access by plan. You trade a subscription for not running collection, matching and monitoring yourself. Providers differ a lot on books, leagues, delivery (REST polling, WebSocket streaming, webhooks), history and price, so compare them against your list from the first section. Our post on how to choose a sports odds API has a checklist, and the comparison pages set PreciseAPI next to other providers with sources.
5. Exchange and prediction market APIs
Exchanges and prediction markets such as Kalshi and Polymarket publish APIs for their own markets. They are a good source for exactly one venue each, with real liquidity behind the prices. Each has its own schema, its own ids and its own price format, usually contract prices rather than odds, so combining several of them with sportsbook lines brings back the matching problem. The prediction market odds API page shows how PreciseAPI puts 7 exchanges and prediction markets next to sportsbook prices on the same event ids, and the Kalshi and Polymarket post explains the conversion from contract prices to odds.
The options side by side
| Source | Cost | Books | Freshness | Effort to maintain |
|---|---|---|---|---|
| By hand | Your time | Whatever you open | When you look | High per price |
| Scraping | Engineering, proxies, servers | One at a time | As fast as you avoid blocks | High and ongoing |
| Free API | Free | Often restricted | Often limited | Low |
| Paid API | Subscription | The provider's list | Up to real-time | Low |
| Exchange APIs | Usually free to read | One venue each | Real-time | Medium per venue |
For a one-off question, the first row is fine. For anything that has to run every day, the question of how to get sports odds data usually comes down to rows four and five: a paid API for breadth across books, and an exchange's own API only when you need that one venue's order book in depth.
How to get sports odds data with PreciseAPI, step by step
This is the shortest path from nothing to a file of odds. The odds API tutorial in the docs covers the same steps with copy-paste samples in several languages.
Step 1: Get a key
API keys come with the paid plans: Edge, Sharp or Syndicate. The free Sandbox is a dashboard chat with 50 credits for questions about pre-game lines, useful for checking that the books and leagues you need are covered, but it has no API access. Once you're on a plan, copy a key from the dashboard and keep it in an environment variable, never in code or a browser:
export PRECISEAPI_KEY="pa_live_your_key_here"
Step 2: Check the connection and cache reference data
/v1/status, /v1/leagues, /v1/sportsbooks and /v1/markets cost 0 credits. Call them once, cache the results, and use them to look up league ids (nba, nfl, soccer), source ids (pinnacle, draftkings, kalshi) and market keys.
curl "https://api.preciseapi.com/v1/sportsbooks" -H "Authorization: Bearer $PRECISEAPI_KEY"
Step 3: Find events
/v1/events lists upcoming and live games for a league, 1 credit per request. Each event has an id that never changes, including when the game goes in-play.
curl "https://api.preciseapi.com/v1/events?league=nba&limit=5" -H "Authorization: Bearer $PRECISEAPI_KEY"
{
"data": [
{
"id": "evt_1iazqk4srnb",
"league": "nba",
"sport": "basketball",
"start_time": "2026-11-12T00:00:00.000Z",
"status": "scheduled",
"home": { "id": "nba_phx", "name": "Phoenix Suns", "abbr": "PHX" },
"away": { "id": "nba_sas", "name": "San Antonio Spurs", "abbr": "SAS" },
"score": null,
"clock": null
}
],
"meta": { "request_id": "req_…", "count": 1, "credits_used": 1 }
}
Step 4: Pull odds
/v1/odds returns every game in the league with each book's markets, 2 credits per request however many books and games come back. Filter with books= and markets=, and use format=decimal or format=probability if you don't want American odds.
curl "https://api.preciseapi.com/v1/odds?league=nba&markets=moneyline,spread,total&books=pinnacle,draftkings,fanduel" \
-H "Authorization: Bearer $PRECISEAPI_KEY"
Each event carries a bookmakers array; each bookmaker has markets with a key, period, line for spreads and totals, updated_at, suspended, and outcomes with name, side, point and price. The data model documents every field.
Step 5: Add props, history or best lines
/v1/props(3 credits) returns player props from sportsbooks and DFS apps, 25 events per request. The player props API page has examples./v1/history(3 credits) returns the opening price, the current price and every move in between for a main market./v1/best-lines(3 credits) returns the best price per outcome and the books offering it.
Step 6: Save an odds data download to CSV
There's no download button for the feed, but an odds data download is a few lines of Python. This writes one row per outcome per book, with the selection id so you can compare books later:
import csv
import os
import requests
res = requests.get(
"https://api.preciseapi.com/v1/odds",
headers={"Authorization": f"Bearer {os.environ['PRECISEAPI_KEY']}"},
params={"league": "nba,nhl", "markets": "moneyline,spread,total", "books": "pinnacle,draftkings,fanduel,betmgm"},
timeout=15,
)
res.raise_for_status()
body = res.json()
with open("odds.csv", "w", newline="") as f:
w = csv.writer(f)
w.writerow(["event_id", "league", "start_time", "away", "home", "book", "market", "period",
"selection_id", "outcome", "point", "price", "updated_at"])
for ev in body["data"]:
for book in ev["bookmakers"]:
for m in book["markets"]:
for o in m["outcomes"]:
w.writerow([ev["id"], ev["league"], ev["start_time"], ev["away"]["name"], ev["home"]["name"],
book["id"], m["key"], m["period"], o["id"], o["name"], o.get("point", ""),
o["price"], m["updated_at"]])
print(body["meta"]["count"], "events,", body["meta"]["credits_used"], "credits")
Run it on a schedule with cron or Task Scheduler and append a timestamp column, and you have a growing dataset. If you'd rather work in a spreadsheet directly, the Excel and Google Sheets guide shows Power Query and Apps Script versions.
How to get a betting odds API plan that fits your budget
Knowing how to get a betting odds API key is the easy part; picking the plan is about volume and whether you need games in progress. A request costs the same regardless of how many books or games it returns, so the budget depends only on how often you call:
| Refresh plan | Credits per 30 days |
|---|---|
/v1/odds once an hour | 1,440 |
/v1/odds every 5 minutes | 17,280 |
/v1/odds every minute | 86,400 |
/v1/odds every 30 seconds | 172,800 |
Edge ($49.99 a month) includes 150,000 credits, 300 requests a minute, props, futures and line history, with pre-game odds only. Sharp ($199.99) has unlimited credits, still pre-game. Syndicate ($249.99) adds live in-play odds and the WebSocket stream, which replaces polling altogether. The odds API pricing page has the full table.
Common mistakes when sourcing odds
- One request per game.
/v1/oddscovers a whole league, andleague=accepts several leagues, so one call replaces dozens. - Ignoring timestamps. Use
updated_atto drop stale quotes, and skip markets wheresuspendedis true. - Comparing different bets. A spread of -3 and -3.5 are different bets. Group by selection id, which includes the number.
- Keys in the browser. Proxy requests through your own server; a key in front-end code is a key anyone can copy.
- Paying for reference data. Leagues, sportsbooks and markets are free endpoints. Cache them daily.
Frequently asked questions
What is the easiest way to get sports odds data?
For a few games, copying lines by hand. For anything ongoing, an odds API: one HTTP request returns many books' prices in a consistent format, without building scrapers or matching games across sites yourself.
Can I download historical odds data?
PreciseAPI's /v1/history returns the opening price, current price and every recorded move for main full-game markets, on every paid plan. Save the responses, or your own scheduled /v1/odds snapshots, to build a dataset over time.
Is there a free way to get sports odds data?
Copying lines by hand, exchange APIs for single venues, and free API tiers for evaluation. PreciseAPI's free Sandbox is a chat with 50 credits for questions about pre-game lines; API keys start on the Edge plan.
What format does odds data come in?
PreciseAPI returns JSON. Prices default to American odds and can be requested as decimal odds or implied probability with the format parameter. Converting the JSON to CSV takes a few lines of code, as shown above.
Which sportsbooks can I get odds from?
PreciseAPI covers 36 sources: 23 sportsbooks, 7 exchanges and prediction markets, and 6 DFS pick'em apps across 17 leagues. The free /v1/sportsbooks endpoint lists them with the leagues each one is pricing.