Get Your First Odds in 5 Minutes
A complete, copy-paste tutorial to fetch live odds
Step 1: Get Your API Key
- Sign up at sportsgameodds.com/pricing
- Check your email for your API key
- Copy your API key - you’ll need it in the next step
Step 2: Make A Request
- Copy one of the examples below into a file
- Replace
YOUR_API_KEYwith your actual API key - Run it!
https://api.sportsgameodds.com/v2/events?apiKey=YOUR_API_KEY&leagueID=NBA,NFL,MLB&oddsAvailable=truecurl -X GET "https://api.sportsgameodds.com/v2/events?apiKey=YOUR_API_KEY&leagueID=NBA,NFL,MLB&oddsAvailable=true"(async () => {
const response = await fetch("https://api.sportsgameodds.com/v2/events?apiKey=YOUR_API_KEY&leagueID=NBA,NFL,MLB&oddsAvailable=true");
const output = await response.json();
console.log(JSON.stringify(output.data, null, 2));
})();import requests
import json
response = requests.get(
'https://api.sportsgameodds.com/v2/events',
params={'leagueID': 'NBA,NFL,MLB', 'oddsAvailable': 'true', 'apiKey': 'YOUR_API_KEY'}
)
output = response.json()
print(json.dumps(output['data'], indent=2))require 'net/http'
require 'json'
uri = URI('https://api.sportsgameodds.com/v2/events')
uri.query = URI.encode_www_form({
leagueID: 'NFL,NBA,MLB',
oddsAvailable: 'true',
apiKey: 'YOUR_API_KEY'
})
response = Net::HTTP.get_response(uri)
output = JSON.parse(response.body)
puts JSON.pretty_generate(output['data'])<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.sportsgameodds.com/v2/events?leagueID=NFL,NBA,MLB&oddsAvailable=true&apiKey=YOUR_API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
$output = json_decode($response, true);
print_r($output['data']);
?>import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class SportsGameOddsAPI {
public static void main(String[] args) throws Exception {
String url = "https://api.sportsgameodds.com/v2/events?" +
"leagueID=NFL,NBA,MLB" +
"&oddsAvailable=true" +
"&apiKey=YOUR_API_KEY";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}If you don't want to write code, paste the "Browser URL" example into your browser
Step 3: See Live Odds
You’ll get a response like this:
{
"nextCursor": "n.1763687700000.4lronEc61vA9pcyqoRIa",
"success": true,
"data": [
{
"eventID": "4lronEc61vA9pcyqoRIa",
"sportID": "FOOTBALL",
"leagueID": "NFL",
"type": "match",
"teams": {
"home": {
"teamID": "HOUSTON_TEXANS_NFL",
"names": {
"long": "Houston Texans",
"medium": "Texans",
"short": "HOU"
}
//.. more team details
},
"away": {
"teamID": "BUFFALO_BILLS_NFL",
"names": {
"long": "Buffalo Bills",
"medium": "Bills",
"short": "BUF"
}
//... more team details
}
},
"status": {
"started": false,
"completed": false,
"cancelled": false,
"ended": false,
"live": false,
"delayed": false,
"currentPeriodID": "",
"previousPeriodID": "",
"displayShort": "",
"displayLong": "Upcoming",
"inBreak": false,
"hardStart": true,
"periods": {
"started": [],
"ended": []
},
"oddsPresent": true,
"oddsAvailable": true,
"finalized": false,
"startsAt": "2025-11-21T01:15:00.000Z",
"previousStartsAt": []
},
"info": {
"seasonWeek": "NFL 25/26"
},
"odds": {
"passing_yards-JOSH_ALLEN_1_NFL-game-ou-over": {
"oddID": "passing_yards-JOSH_ALLEN_1_NFL-game-ou-over",
"opposingOddID": "passing_yards-JOSH_ALLEN_1_NFL-game-ou-under",
"statID": "passing_yards",
"statEntityID": "JOSH_ALLEN_1_NFL",
"periodID": "game",
"betTypeID": "ou",
"sideID": "over",
"playerID": "JOSH_ALLEN_1_NFL",
"started": false,
"ended": false,
"cancelled": false,
"bookOddsAvailable": true,
"fairOddsAvailable": true,
"fairOdds": "+100",
"bookOdds": "-114",
"fairOverUnder": "231",
"bookOverUnder": "224.5",
"openFairOdds": "+100",
"openBookOdds": "-114",
"openFairOverUnder": "231",
"openBookOverUnder": "224.5",
"scoringSupported": true,
"byBookmaker": {
"betmgm": {
"odds": "-118",
"overUnder": "224.5",
"lastUpdatedAt": "2025-11-19T21:12:36.000Z",
"available": true,
"deeplink": "https://sports.nj.betmgm.com/en/sports?options=18503696-1407860184--325476953"
},
"prizepicks": {
"odds": "+100",
"overUnder": "224.5",
"lastUpdatedAt": "2025-11-19T21:09:53.000Z",
"available": true,
"deeplink": "https://app.prizepicks.com/?projections=7878799-o-224.5"
}
//... more bookmakers
},
"marketName": "Josh Allen Passing Yards Over/Under"
}
//... more odds markets
},
"links": {
"bookmakers": {
"espnbet": "https://espnbet.com/sport/football/organization/united-states/competition/nfl/event/2c83a542-357e-4e78-8efe-58129cb8cd37",
"draftkings": "https://sportsbook.draftkings.com/event/32225621",
"nordicbet": "https://www.nordicbet.com/en/sportsbook/american-football/nfl/nfl/houston-texans-buffalo-bills"
// ...more deeplinks
}
},
"players": {
"JOSH_ALLEN_1_NFL": {
"playerID": "JOSH_ALLEN_1_NFL",
"teamID": "BUFFALO_BILLS_NFL",
"firstName": "Josh",
"lastName": "Allen",
"name": "Josh Allen",
"nickname": "J.Allen"
}
// ... more players
}
}
//... more events
]
}Understand the Response
Let’s break down what you just got:
Event Details:
eventID- Unique identifier for this gameteams.home.name- Home team: Los Angeles Lakersteams.away.name- Away team: Boston CelticsstartTime- When the game starts (UTC)
Odds Data: Each odd is keyed by oddID which follows this pattern:
{statID}-{statEntityID}-{periodID}-{betTypeID}-{sideID}Note: The oddID does NOT include bookmakerID. Each oddID contains odds from ALL available bookmakers nested under the byBookmaker object.
Example: points-home-game-sp-home means:
points- Stat being bet on (team points/score)home- Entity (home team)game- For the full game (not just a quarter/half)sp- This is a point spread bet (betTypeID)home- Side of the bet (home team)
The odds show:
- Each oddID contains odds from multiple bookmakers under
byBookmaker - Lakers -5.5 @ -110 from DraftKings, -5.5 @ -112 from FanDuel
- Celtics +5.5 @ -110 from DraftKings, +5.5 @ -108 from FanDuel
- Lakers moneyline -220 from DraftKings, -225 from FanDuel
- All odds values (spread, odds) are strings, not numbers
Done!
Congratulations! You just fetched live odds from the SportsGameOdds API.
Next Steps
Now that you’ve made your first successful call, explore what else you can do:
🚀 Build Something Real
Start with these complete, working examples:
- Live Odds Tracker - Track line movement in real-time
- Arbitrage Calculator - Find guaranteed profit opportunities
- Odds Comparison Dashboard - Compare odds across bookmakers
- Player Props Analyzer - Analyze player prop bets
- Parlay Builder - Build parlay bet calculators
📖 Learn the Basics
- Understanding Odds Data - Deep dive into the oddID structure
- Sports Betting Glossary - Learn all the terminology
- Setup - More about how to get started with the API
- Rate Limiting - Understand request limits
🛠️ Use Our SDK
Instead of raw HTTP requests, use our official SDKs with built-in pagination, retries, and type safety:
# TypeScript/JavaScript
npm install sports-odds-api
yarn add sports-odds-api
pnpm add sports-odds-api
# Python
pip install sports-odds-api
poetry add sports-odds-api
# Ruby
gem install sports-odds-api
bundle add sports-odds-api
# Go
go get github.com/SportsGameOdds/sports-odds-api-go🔍 Explore All Endpoints
- API Reference - Interactive documentation for all endpoints
- Data Explorer - Browse available leagues, bookmakers, and markets
Common Next Questions
How do I get odds from multiple bookmakers?
By default, the API returns odds from all available bookmakers. Each bookmaker appears in the oddID:
// Filter to specific bookmaker
fetch("/v2/events?leagueID=NBA&bookmakerID=draftkings");
// Or get all and filter in code
Object.entries(event.odds).forEach(([oddID, odd]) => {
if (odd.bookmakerID === "draftkings") {
console.log("DraftKings odds:", odd);
}
});How do I get live scores?
Scores are included automatically in the same response for live games:
const response = await fetch("/v2/events?leagueID=NBA&live=true", { headers: { "x-api-key": API_KEY } });
const data = await response.json();
data.data.forEach((event) => {
console.log(`${event.teams.away.name}: ${event.scores.away}`);
console.log(`${event.teams.home.name}: ${event.scores.home}`);
});No separate API needed - odds, scores, and stats all in one response!
How do I get historical data?
Use the startsAfter and startsBefore parameters:
// Get all NBA games from December 2024
fetch("/v2/events?leagueID=NBA&startsAfter=2024-12-01&startsBefore=2024-12-31");Historical data from 2024+ is included in all plans. Extended historical data (2020+) available on Pro/AllStar plans.
How often should I poll for live odds?
Recommended intervals:
- Pre-match: Every 5-15 minutes (odds change slowly)
- Live: Every 30-60 seconds (good balance)
- Critical moments: Use real-time streaming (AllStar plan)
Polling faster than 30 seconds wastes rate limits without meaningful updates.
What counts as an “object” in pricing?
An object = 1 event (game). Each event includes ALL odds markets and ALL bookmakers by default.
Key difference from other APIs: You pay per event, not per market or per bookmaker.
Example:
- 1 NBA game with 100 odds markets across 20 bookmakers = 1 object
- 10 NBA games = 10 objects
- Same 10 games polled twice = 20 objects (charged per request)
This makes SportsGameOdds 60-80% cheaper than competitors who charge per market or per bookmaker.
Learn more: Rate Limiting →
Ready to build something amazing? Pick a recipe and start coding! 🚀
