Understanding the API Workflow
Master the Sports → Leagues → Events → Odds flow
Written By James Mccoy
Last updated About 1 month ago
Overview
Odds-API.io follows a logical, hierarchical structure that makes it easy to navigate from broad categories down to specific betting odds. This guide explains the complete workflow and when to use each endpoint.
The workflow follows this pattern:
ExampleSPORTS → LEAGUES → EVENTS → ODDS
↓ ↓ ↓ ↓
Football Premier Man Utd Bet365: 2.10
League vs Unibet: 2.05
Liverpool SingBet: 2.15The Complete Workflow
Visual Overview
Example┌─────────────────────────────────────────────────────────┐
│ 1. SPORTS │
│ What sports are available? │
│ GET /v3/sports │
│ Returns: Football, Basketball, Tennis, etc. │
└──────────────────┬──────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 2. LEAGUES │
│ What leagues exist in a sport? │
│ GET /v3/leagues?sport=football │
│ Returns: Premier League, La Liga, Bundesliga, etc. │
└──────────────────┬──────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 3. EVENTS │
│ What matches are coming up? │
│ GET /v3/events?sport=football&league=premier-league │
│ Returns: Man Utd vs Liverpool, Chelsea vs Arsenal, etc.│
└──────────────────┬──────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 4. ODDS │
│ What are the betting odds? │
│ GET /v3/odds?eventId=123456&bookmakers=Bet365,Unibet │
│ Returns: Odds from multiple bookmakers │
└─────────────────────────────────────────────────────────┘💡Don’t wan’t to start with code? That’s fine, you can play about easily with out interactive API where it does the requests for you. You just need your API Key which you can get from our website.
Interactive API:
Step 1: Sports
Purpose
Get the complete list of sports available through the API.
When to Use
Starting point for any odds application
Building sport selectors in your UI
Discovering available sports before making other calls
Cache this data - sports list rarely changes
Endpoint
GET https://api.odds-api.io/v3/sportsAuthentication
❌ Not required - This endpoint is public
Request Example
Exampleconst response = await fetch('https://api.odds-api.io/v3/sports');
const sports = await response.json();💡New to this? Copy our documentation into AI. It can help you with your code!
Response Structure
[ { "name": "Football", "slug": "football" }, { "name": "Basketball", "slug": "basketball" }, { "name": "Tennis", "slug": "tennis" }]Response Fields

Available Sports
Odds-API.io covers 10+ major sports:
⚽ Football (Soccer) -
football🏀 Basketball -
basketball🎾 Tennis -
tennis⚾ Baseball -
baseball🏒 Ice Hockey -
ice-hockey🏈 American Football -
american-football🎮 Esports -
esports🏉 Rugby -
rugby🏏 Cricket -
cricket🥊 MMA -
mma
Best Practices
✅ Cache this data for 1+ hours - sports list rarely changes
✅ Use slugs for API calls - not the display names
✅ Build dropdowns from this data - provides consistent naming
Step 2: Leagues
Purpose
Get all leagues/competitions within a specific sport.
When to Use
After selecting a sport from step 1
Building league filters in your application
Discovering what competitions are covered
Finding league slugs for events endpoint
Endpoint
GET https://api.odds-api.io/v3/leaguesAuthentication
✅ Required - Include your API key
Parameters

Request Example
JavaScript
javascript
const apiKey = process.env.ODDS_API_KEY; const response = await fetch( `https://api.odds-api.io/v3/leagues?apiKey=${apiKey}&sport=football` ); const leagues = await response.json();Response Structure
Example[
{
"name": "Premier League",
"slug": "england-premier-league",
"eventCount": 45
},
{
"name": "La Liga",
"slug": "spain-la-liga",
"eventCount": 38
},
{
"name": "Bundesliga",
"slug": "germany-bundesliga",
"eventCount": 34
}
]Response Fields

Popular Leagues by Sport
Football (Soccer)
Premier League -
england-premier-leagueLa Liga -
spain-la-ligaBundesliga -
germany-bundesligaSerie A -
italy-serie-aLigue 1 -
france-ligue-1Champions League -
uefa-champions-league
Basketball
NBA -
usa-nbaNCAA Basketball -
usa-ncaaEuroLeague -
europe-euroleague
American Football
NFL -
usa-nflNCAA Football -
usa-ncaaf
Tennis
ATP Tour -
atpWTA Tour -
wtaGrand Slams - Various
Best Practices
✅ Cache for 1 hour - leagues don't change frequently
✅ Filter by eventCount > 0 - show only active leagues
✅ Sort by popularity - put major leagues first
✅ Use slugs in events calls - not display names
Step 3: Events
Purpose
Get upcoming or live matches/games within a specific sport and league.
When to Use
After selecting sport and league from steps 1 and 2
Listing upcoming matches for users to bet on
Finding live events for in-play betting
Getting event IDs to fetch odds
Endpoint
GET https://api.odds-api.io/v3/eventsAuthentication
✅ Required - Include your API key
Parameters

Request Examples
Get upcoming Premier League matches
Exampleconst apiKey = process.env.ODDS_API_KEY;
const response = await fetch(
`https://api.odds-api.io/v3/events?apiKey=${apiKey}&sport=football&league=england-premier-league&status=pending&limit=10`
);
const events = await response.json();Get all live football matches
Exampleconst response = await fetch(
`https://api.odds-api.io/v3/events?apiKey=${apiKey}&sport=football&status=live`
);
const liveEvents = await response.json();Request Structure
Example[
{
"id": 123456,
"home": "Manchester United",
"away": "Liverpool",
"date": "2025-10-20T15:00:00Z",
"sport": {
"name": "Football",
"slug": "football"
},
"league": {
"name": "Premier League",
"slug": "england-premier-league"
},
"status": "pending"
},
{
"id": 123457,
"home": "Chelsea",
"away": "Arsenal",
"date": "2025-10-20T17:30:00Z",
"sport": {
"name": "Football",
"slug": "football"
},
"league": {
"name": "Premier League",
"slug": "england-premier-league"
},
"status": "pending"
}
]Request Fields

Understanding Event Status
pending - Upcoming events
Event hasn't started yet
Typically best for pre-match odds
More stable odds (less volatility)
live - In-progress events
Event is currently happening
For in-play/live betting
Odds change very rapidly
Consider WebSocket for real-time updates
Best Practices
✅ Always filter by league - reduces response size and improves performance
✅ Use status filter - separate upcoming and live events
✅ Set reasonable limits - don't fetch 100+ events at once
✅ Cache for 5-10 minutes - events don't appear/disappear rapidly
✅ Sort by date - show nearest events first
✅ Handle empty results - leagues have off-seasons
Displaying Events to Users
Exampleevents.forEach(event => {
const eventDate = new Date(event.date);
const timeUntil = eventDate - new Date();
const hoursUntil = Math.floor(timeUntil / (1000 * 60 * 60));
console.log(`${event.home} vs ${event.away}`);
console.log(`${event.league.name}`);
console.log(`Starts in ${hoursUntil} hours`);
console.log(`---`);
});Step 4: Odds
Purpose
Get betting odds from multiple bookmakers for a specific event.
When to Use
After selecting an event from step 3
Comparing odds across bookmakers
Finding best odds for each outcome
Building odds comparison tables
Getting direct bet links to bookmaker sites
Endpoint
GET https://api.odds-api.io/v3/oddsAuthentication
✅ Required - Include your API key
Parameters

Request Example
Exampleconst apiKey = process.env.ODDS_API_KEY;
const eventId = 123456; // From events endpoint
const bookmakers = 'Bet365,Unibet,SingBet,William Hill,Betway';
const response = await fetch(
`https://api.odds-api.io/v3/odds?apiKey=${apiKey}&eventId=${eventId}&bookmakers=${bookmakers}`
);
const oddsData = await response.json();Request Structure
Example{
"id": 123456,
"home": "Manchester United",
"away": "Liverpool",
"date": "2025-10-20T15:00:00Z",
"sport": {
"name": "Football",
"slug": "football"
},
"league": {
"name": "Premier League",
"slug": "england-premier-league"
},
"bookmakers": {
"Bet365": [
{
"name": "ML",
"label": "Match Result",
"odds": [
{
"home": "2.10",
"draw": "3.40",
"away": "3.60",
"href": "https://www.bet365.com/..."
}
],
"updatedAt": "2025-10-18T10:30:00Z"
},
{
"name": "Totals",
"label": "Total Goals",
"odds": [
{
"over": "1.90",
"under": "1.90",
"hdp": "2.5"
}
],
"updatedAt": "2025-10-18T10:30:00Z"
}
],
"Unibet": [
{
"name": "ML",
"label": "Match Result",
"odds": [
{
"home": "2.05",
"draw": "3.50",
"away": "3.65"
}
],
"updatedAt": "2025-10-18T10:29:00Z"
}
]
}
}Response Fields
Top Level:

Bookmaker Object:

Odds Object (varies by market):
For ML (Match Result):
home- Home team oddsdraw- Draw odds (if applicable)away- Away team oddshref- Direct bet link (optional)
For Totals (Over/Under):
over- Over oddsunder- Under oddshdp- Line/handicap (e.g., 2.5 goals)
For Spreads:
home- Home team oddsaway- Away team oddshdp- Spread line (e.g., -1.5)
Market Types Explained
ML (Moneyline / Match Result)
Most common market
Simple win/draw/lose bet
{ "home": "2.10", "draw": "3.40", "away": "3.60" }
Totals (Over/Under)
Total goals/points scored
Bet over or under a line
{ "over": "1.90", "under": "1.90", "hdp": "2.5" }
Spreads (Handicap)
Point/goal handicap betting
Team must win by margin
{ "home": "1.90", "away": "1.90", "hdp": "-1.5" }
Selecting Bookmakers
Popular bookmakers by region:
Global: Bet365, Unibet, SingBet, William Hill, Betway
United States: DraftKings, FanDuel, Caesars, BetMGM
UK: Ladbrokes, Coral, Paddy Power, Sky Bet
Europe: Bwin, 1xBet, 888sport
Pro tip: Start with 5-10 major bookmakers, not all 250+
Best Practices
✅ Select relevant bookmakers - don't fetch all 250+
✅ Cache for 30-60 seconds - pre-match odds change slowly
✅ Cache for 5-10 seconds - live odds change rapidly
✅ Handle missing data - not all bookmakers offer all markets
✅ Use multi-odds endpoint - fetch up to 10 events at once
✅ Check updatedAt - know how fresh the odds are
Comparing Odds Example
Examplefunction findBestOdds(oddsData) {
const bestOdds = {
home: { bookmaker: '', odds: 0 },
draw: { bookmaker: '', odds: 0 },
away: { bookmaker: '', odds: 0 }
};
Object.entries(oddsData.bookmakers).forEach(([bookmaker, markets]) => {
const mlMarket = markets.find(m => m.name === 'ML');
if (mlMarket?.odds[0]) {
const odds = mlMarket.odds[0];
if (parseFloat(odds.home) > bestOdds.home.odds) {
bestOdds.home = { bookmaker, odds: parseFloat(odds.home) };
}
if (odds.draw && parseFloat(odds.draw) > bestOdds.draw.odds) {
bestOdds.draw = { bookmaker, odds: parseFloat(odds.draw) };
}
if (parseFloat(odds.away) > bestOdds.away.odds) {
bestOdds.away = { bookmaker, odds: parseFloat(odds.away) };
}
}
});
return bestOdds;
}
const best = findBestOdds(oddsData);
console.log(`Best Home: ${best.home.odds} at ${best.home.bookmaker}`);
console.log(`Best Draw: ${best.draw.odds} at ${best.draw.bookmaker}`);
console.log(`Best Away: ${best.away.odds} at ${best.away.bookmaker}`);Complete Workflow Example
Here's how to navigate the entire workflow from start to finish:
JavaScript Complete Example
Exampleconst apiKey = process.env.ODDS_API_KEY;
async function completeWorkflow() {
// Step 1: Get sports
console.log('STEP 1: Fetching sports...');
const sportsRes = await fetch('https://api.odds-api.io/v3/sports');
const sports = await sportsRes.json();
const footballSlug = sports.find(s => s.name === 'Football').slug;
console.log(`✓ Found sport: ${footballSlug}\n`);
// Step 2: Get leagues
console.log('STEP 2: Fetching leagues...');
const leaguesRes = await fetch(
`https://api.odds-api.io/v3/leagues?apiKey=${apiKey}&sport=${footballSlug}`
);
const leagues = await leaguesRes.json();
const premierLeague = leagues.find(l => l.name === 'Premier League');
console.log(`✓ Found league: ${premierLeague.name} (${premierLeague.eventCount} events)\n`);
// Step 3: Get events
console.log('STEP 3: Fetching events...');
const eventsRes = await fetch(
`https://api.odds-api.io/v3/events?apiKey=${apiKey}&sport=${footballSlug}&league=${premierLeague.slug}&status=pending&limit=1`
);
const events = await eventsRes.json();
const event = events[0];
console.log(`✓ Found event: ${event.home} vs ${event.away}`);
console.log(` Date: ${new Date(event.date).toLocaleString()}\n`);
// Step 4: Get odds
console.log('STEP 4: Fetching odds...');
const oddsRes = await fetch(
`https://api.odds-api.io/v3/odds?apiKey=${apiKey}&eventId=${event.id}&bookmakers=Bet365,Unibet,Pinnacle`
);
const oddsData = await oddsRes.json();
console.log('✓ Odds from bookmakers:');
Object.entries(oddsData.bookmakers).forEach(([bookmaker, markets]) => {
const ml = markets.find(m => m.name === 'ML')?.odds[0];
if (ml) {
console.log(` ${bookmaker}: Home ${ml.home} | Draw ${ml.draw} | Away ${ml.away}`);
}
});
console.log('\n✅ Complete workflow finished!');
}
completeWorkflow().catch(console.error);Optimization Tips
Efficient Data Flow
❌ Inefficient:
javascript
// Fetching sports every time - wasteful! for (let i = 0; i < 100; i++) { const sports = await fetch('/v3/sports'); // ... use sports }✅ Efficient:
javascript
// Cache sports data - it rarely changes const sports = await fetch('/v3/sports'); // Use cached sports data for all operationsCaching Strategy

Batch Operations
Instead of fetching odds for one event at a time:
❌ Inefficient:
javascript
for (const eventId of [123, 456, 789]) { await fetch(`/v3/odds?eventId=${eventId}`); // 3 requests }✅ Efficient:
javascript
// Use multi-odds endpoint - 1 request for up to 10 events await fetch('/v3/odds/multi?eventIds=123,456,789');When to Use Each Endpoint
Sports Endpoint
✅ Building sport selectors
✅ App initialization
✅ Discovering available sports
❌ Frequent polling (waste of requests)
Leagues Endpoint
✅ After sport selection
✅ Building league filters
✅ Checking league availability
❌ Every page load (cache it!)
Events Endpoint
✅ Listing upcoming matches
✅ Finding live games
✅ Event discovery
✅ Getting event IDs for odds calls
❌ Real-time updates (use WebSocket instead)
Odds Endpoint
✅ Detailed odds comparison
✅ Specific event odds
✅ Finding best odds
✅ Before placing bets
❌ Live odds updates every second (use WebSocket)
Quick Reference
The Flow
Example1. GET /v3/sports
↓ Choose a sport
2. GET /v3/leagues?sport=football
↓ Choose a league
3. GET /v3/events?sport=football&league=premier-league
↓ Choose an event
4. GET /v3/odds?eventId=123456&bookmakers=Bet365,Unibet
↓ Display oddsKey Parameters
sport- Sport slug from /sportsleague- League slug from /leagueseventId- Event ID from /eventsbookmakers- Comma-separated liststatus- "pending" or "live"limit- Max results to return
Need Help?
Questions about the API workflow?
📧 Email: hello@odds-api.io
📖 Full Documentation: Complete API reference
Interactive Documentation
⏱️ Response Time: Usually within 24 hours