← Back to Odds API

Quickstart Guide

Get your API key and make your first request in under 5 minutes.

1. Get Your API Key

Sign up for a free API key on the Odds API landing page. You'll receive a key starting with odds_ — save it immediately as it's only shown once.

The free tier includes 500 requests/month at 1 request/second, no credit card required.

# Example: create an API key via curl
curl -X POST https://api.oddstatus.com/api/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'

# Response:
{
  "key": "odds_a1b2c3d4e5f6...",
  "id": 1,
  "prefix": "odds_a1b",
  "tier": "free",
  "monthlyLimit": 500,
  "perMinuteLimit": 1,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "message": "Save your API key securely. It will not be shown again."
}

2. Authentication

All data endpoints require authentication via a Bearer token in theAuthorization header:

Authorization: Bearer odds_your_api_key_here

Key management endpoints (/api/v1/keys) do not require authentication — they identify you by email.

3. List Available Sports

curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/sports"

# Response:
{
  "sports": [
    { "key": "americanfootball_nfl", "name": "NFL" },
    { "key": "basketball_nba", "name": "NBA" },
    { "key": "baseball_mlb", "name": "MLB" },
    { "key": "icehockey_nhl", "name": "NHL" },
    { "key": "soccer_epl", "name": "English Premier League" },
    { "key": "soccer_la_liga", "name": "La Liga" },
    ...
  ]
}

4. Get Upcoming Matches

# All upcoming matches (default limit 25)
curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/matches"

# Filter by sport
curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/matches?sport=americanfootball_nfl&limit=10"

# Filter by date
curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/matches?date=2025-01-15&status=pregame"

# Response:
{
  "matches": [
    {
      "id": 123,
      "title": "Kansas City Chiefs vs Buffalo Bills",
      "sport": "americanfootball_nfl",
      "sportName": "NFL",
      "competition": "NFL",
      "startTime": "2025-01-15T01:20:00Z",
      "status": "pregame",
      "participants": [
        { "role": "home", "name": "Kansas City Chiefs", "shortName": "KC" },
        { "role": "away", "name": "Buffalo Bills", "shortName": "BUF" }
      ]
    }
    ...
  ],
  "total": 42,
  "limit": 25,
  "offset": 0
}

Query Parameters

ParamTypeDefaultDescription
sportstringFilter by sport key (e.g. americanfootball_nfl)
datestringupcomingDate filter YYYY-MM-DD. Omit for upcoming events.
statusenumOne of: pregame, in_progress, finished, postponed, cancelled
limitnumber25Results per page (1–100)
offsetnumber0Pagination offset

5. Get Odds

# Odds across events (with filters)
curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/odds?sport=americanfootball_nfl&market=h2h&limit=10"

# Response:
{
  "odds": [
    {
      "eventId": 123,
      "eventTitle": "Kansas City Chiefs vs Buffalo Bills",
      "startTime": "2025-01-15T01:20:00Z",
      "sport": "americanfootball_nfl",
      "marketType": "h2h",
      "marketLabel": "Moneyline",
      "bookmaker": "draftkings",
      "bookmakerName": "DraftKings",
      "outcome": "Kansas City Chiefs",
      "decimalPrice": 1.91,
      "americanPrice": -110,
      "point": null,
      "fetchedAt": "2025-01-15T00:30:00Z"
    },
    ...
  ],
  "total": 42,
  "limit": 10,
  "offset": 0
}

Query Parameters

ParamTypeDefaultDescription
sportstringSport key filter
bookmakerstringBookmaker key filter (e.g. draftkings)
eventIdnumberGet odds for a specific event
marketenumallOne of: h2h, spreads, totals, all
limitnumber25Results per page (1–100)
offsetnumber0Pagination offset

6. Get Single Event

curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/events/123"

# Response includes event details, participants, and all odds:
{
  "id": 123,
  "title": "Kansas City Chiefs vs Buffalo Bills",
  "sport": "americanfootball_nfl",
  "sportName": "NFL",
  "competition": "NFL",
  "startTime": "2025-01-15T01:20:00Z",
  "status": "pregame",
  "participants": [
    { "role": "home", "name": "Kansas City Chiefs", "shortName": "KC" },
    { "role": "away", "name": "Buffalo Bills", "shortName": "BUF" }
  ],
  "odds": [
    {
      "marketType": "h2h",
      "marketLabel": "Moneyline",
      "bookmaker": "draftkings",
      "bookmakerName": "DraftKings",
      "outcome": "Kansas City Chiefs",
      "decimalPrice": 1.91,
      "americanPrice": -110,
      "point": null,
      "fetchedAt": "2025-01-15T00:30:00Z"
    },
    ...
  ]
}

7. Response Format

All endpoints return JSON. Common patterns:

  • Pagination: Responses include total, limit, and offset fields for paginating through results.
  • Odds format: Both decimalPrice (decimal odds, e.g. 1.91) and americanPrice (American odds, e.g. -110) are always included.
  • Timestamps: All timestamps are ISO 8601 UTC strings.
  • Null values: Fields like point may be null when not applicable (e.g. moneyline odds don't have a point/line).

8. Error Handling

The API uses standard HTTP status codes:

CodeMeaningAction
200SuccessProcess the response normally
400Bad RequestCheck query parameters for invalid values
401UnauthorizedVerify your API key is correct and active
404Not FoundThe requested resource doesn't exist
429Rate LimitedWait and retry. Check Retry-After header
500Server ErrorRetry with exponential backoff

Error responses include a JSON body:

// Example: rate limit exceeded
{
  "error": "Rate limit exceeded",
  "retryAfter": 32,
  "limits": {
    "monthly": 500,
    "monthlyRemaining": 0,
    "perMinute": 1,
    "perMinuteRemaining": 0
  }
}

// Example: invalid API key
{
  "error": "Invalid or revoked API key"
}

9. Rate Limits

Every response includes rate limit headers:

X-RateLimit-Limit-Monthly: 500
X-RateLimit-Remaining-Monthly: 487
X-RateLimit-Limit-Minute: 1
X-RateLimit-Remaining-Minute: 0
TierMonthly LimitPer-Minute Limit
Free500 requests/month1 request/second
Pro50,000 requests/month10 requests/second
Business500,000 requests/month50 requests/second

When you exceed your rate limit, the API returns a 429 status with aRetry-After header indicating how many seconds to wait.

10. SDK Examples

Python

import requests

API_KEY = "odds_your_api_key"
BASE_URL = "https://api.oddstatus.com/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# List all sports
sports = requests.get(f"{BASE_URL}/sports", headers=HEADERS).json()
for s in sports["sports"]:
    print(f"{s['key']}: {s['name']}")

# Get upcoming NFL matches
matches = requests.get(
    f"{BASE_URL}/matches",
    headers=HEADERS,
    params={"sport": "americanfootball_nfl", "limit": 10}
).json()

for m in matches["matches"]:
    print(f"{m['title']} — {m['startTime']}")

# Get odds for a specific event
event = requests.get(
    f"{BASE_URL}/events/{matches['matches'][0]['id']}",
    headers=HEADERS
).json()

for o in event["odds"]:
    print(f"  {o['bookmakerName']} {o['outcome']}: {o['decimalPrice']} ({o['americanPrice']})")

JavaScript / Node.js

const API_KEY = "odds_your_api_key";
const BASE_URL = "https://api.oddstatus.com/api/v1";
const headers = { Authorization: `Bearer ${API_KEY}` };

// Fetch NFL odds
const res = await fetch(
  `${BASE_URL}/odds?sport=americanfootball_nfl&market=h2h&limit=10`,
  { headers }
);
const data = await res.json();

for (const o of data.odds) {
  console.log(`${o.bookmakerName} ${o.outcome}: ${o.decimalPrice} (${o.americanPrice})`);
}

cURL

# Get your API key
curl -X POST https://api.oddstatus.com/api/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'

# List sports
curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/sports"

# Get odds for an event
curl -H "Authorization: Bearer odds_your_api_key" \
  "https://api.oddstatus.com/api/v1/events/123"