Odds API quickstart: live lines in under 10 minutes with cURL, Python and JS
You don't need a tutorial series to pull live odds. You need one key and one request.
To fetch live sports odds, get a free key from a live sports odds API, then send one authenticated GET. With propzapi you POST once to /v1/register for a key with 750 free credits and no card, then call /v1/odds with a league filter and your key in an X-API-Key header. Ten minutes from now you'll have live lines printing in your terminal, in cURL, Python or JavaScript.
This is a copy-paste quickstart, nothing more. Every snippet is a working call against the real API. I use propzapi because it's what I build, and because you can start with no signup form and no credit card.
Step 1: get a free key
Send one POST and you have a key. No form, no card, no email. /v1/register mints a key with 750 free credits a month and hands it straight back. Keep it server-side and send it as an X-API-Key header on every request from here on.
curl -X POST https://api.propzapi.com/v1/register
# → { "api_key": "pk_live_…", "plan": "free", "credits": 750 } That's the whole signup. If you'd rather manage keys and billing in a UI, the dashboard does that too, but for getting a line into your terminal, the register call is faster.
Step 2: your first request in cURL
One GET to /v1/odds returns live odds as JSON. Filter to a league, pass your key in the header, and add -i so you can see the X-Credits-Cost header that tells you exactly what the call charged. No SDK required to prove it works.
curl "https://api.propzapi.com/v1/odds?league=NBA&market=h2h" \
-H "X-API-Key: pk_live_…" -i
# -i prints headers too, so you can see X-Credits-Cost The response is a tree of events, each holding the books that price it, each book holding its markets and priced outcomes. Learn this shape once and every endpoint reads the same.
{
"count": 1,
"data": [
{
"event_id": "401766…",
"league": "NBA",
"home_team": "Boston Celtics",
"away_team": "New York Knicks",
"commence_time": "2026-10-21T23:30:00Z",
"status": "upcoming",
"books": [
{ "book": "DraftKings", "markets": [
{ "market": "h2h", "outcome": "Celtics", "price": -145 },
{ "market": "h2h", "outcome": "Knicks", "price": 124 }
]}
]
}
]
} Step 3: Python
Use the official client or raw requests, both work. The Python client is one pip install, mints a key, and reads the credit cost for you. If you'd rather not add a dependency, plain requests against the same URL does the identical thing. Either way you have live odds in a handful of lines.
The quickest path is the client.
pip install propzapi from propzapi import Propzapi, register
key = register()["api_key"] # free key, no card
client = Propzapi(key)
odds = client.odds(league="NBA", market="h2h")
print(len(odds), "events, this call cost", client.last_credits_cost) No dependency? Raw requests is just as short, and calling raise_for_status() means a bad key or an empty balance fails loudly instead of silently.
import requests
r = requests.get(
"https://api.propzapi.com/v1/odds",
params={"league": "NBA", "market": "h2h"},
headers={"X-API-Key": "pk_live_…"},
timeout=15,
)
r.raise_for_status() # fail loud on 401/402/429
data = r.json()["data"]
print(len(data), "events, cost", r.headers["X-Credits-Cost"]) Step 4: JavaScript and Node
Native fetch is all you need, no package to install. In Node 18+, Deno or the browser, register for a key and GET the odds endpoint with your key in the header. Check res.ok so a 401 or 402 throws instead of parsing as data, and read X-Credits-Cost off the response headers.
// native fetch, no dependency (Node 18+, Deno, browser)
const key = (await (await fetch(
"https://api.propzapi.com/v1/register", { method: "POST" }
)).json()).api_key;
const res = await fetch(
"https://api.propzapi.com/v1/odds?league=NBA&market=h2h",
{ headers: { "X-API-Key": key } }
);
if (!res.ok) throw new Error(`propzapi ${res.status}`);
const { count, data } = await res.json();
console.log(count, "events, cost", res.headers.get("X-Credits-Cost")); Step 5: filter by league and market
Three query params narrow the response: league, market, and limit. Ask for one market to keep the call light, or omit it for all game markets. On /v1/odds a market is h2h, spreads, totals or player_props; a value that isn't valid returns a 400 with the allowed options and doesn't cost a credit, so a typo never bills you.
| Param | Values | Notes |
|---|---|---|
league | NBA, NFL, MLB, NHL, EPL, MLS… | The most common filter |
market | h2h, spreads, totals, player_props | Omit for all game markets |
limit | 1 to 100 (default 25) | Bounded, so 0 or negatives are rejected |
Step 6: pull player props in one call
Player props sit on their own endpoint, /v1/props, and come back already grouped per player: each object carries the player, the market, the line, and every book's over and under prices side by side. No string-parsing a name out of an outcome, no pairing two rows yourself. Filter to one market like player_points or player_passing_yards, or leave market off for every prop on the slate. Props are the markets most odds APIs cover thinly, and here they come back as clean JSON in one call.
curl "https://api.propzapi.com/v1/props?league=NBA&market=player_points" \
-H "X-API-Key: pk_live_…" Market names are player_<stat>: player_points, player_rebounds, player_assists for the NBA; player_passing_yards, player_receptions for the NFL; player_strikeouts for MLB. The full props walkthrough lives in the NFL player props model guide.
What to know before you build
Three things save you time later: read the cost header instead of guessing, cache between polls, and let bad requests fail loudly. Every call returns X-Credits-Cost and X-Credits-Remaining, so spend is a number you log, not a mystery. Poll live markets fast and pre-match slow, with a short cache in front. And a 401, 402 or 429 should throw in your code, not parse as empty data.
| Status | Meaning |
|---|---|
400 | Bad parameter (e.g. an unknown market). Free, not charged. |
401 | Missing or invalid key |
402 | Out of credits |
429 | Rate limited |
That's the quickstart. For the full endpoint reference the docs have cURL, Python and JS side by side, the complete odds API guide covers the fundamentals, and if you're wiring this into an assistant there's an MCP server so an agent can pull odds as a tool call.
Frequently asked questions
- How do I get a live sports odds API key?
- Send one POST to /v1/register. No signup form, no card, no email required. You get back a key and 750 free credits a month immediately. Put the key in an X-API-Key header on every request. You can also sign up in the dashboard if you want to manage keys and billing, but for a quickstart the register call is the fastest path.
- What does one odds call cost?
- It is metered by market, and you never have to guess. Every response returns the exact cost of that call in an X-Credits-Cost header, and your remaining balance in X-Credits-Remaining. A single market is the lightest call; all game markets or player props cost more. Read the header instead of tracking a table.
- Which markets can I request?
- On /v1/odds: h2h (moneyline), spreads, totals, or player_props. Leave market off for all game markets together. On /v1/props: one player market like player_points or player_passing_yards. A market that isn't valid returns a 400 with the allowed values, and it doesn't cost a credit, so a typo never bills you.
- Do I need an SDK?
- No. The API is plain REST and JSON, so cURL, Python requests, or native fetch all work with no dependency. There is an official Python client (pip install propzapi) if you want typed methods and the credit cost read for you, but every example here also works with raw HTTP.
- How fresh are the odds?
- Live and pre-match lines, normalized across books. Poll on a short interval for live markets and a longer one pre-match, and cache between pulls so you are not repeating calls. The response tells you each call's cost, so you can tune polling against your credit budget precisely.
Run the first call now
Don't read another paragraph. Paste the register command, copy the key it returns into the cURL call above, and watch live NBA lines print. Then swap league=NBA for your sport and market=h2h for the market you care about. You're building, not reading, and it took under ten minutes.