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:

Example
SPORTSLEAGUESEVENTSODDS ↓ ↓ ↓ ↓ Football Premier Man Utd Bet365: 2.10 League vs Unibet: 2.05 Liverpool SingBet: 2.15

The 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:

https://api.odds-api.io/v3/docs/index.html

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/sports

Authentication

Not required - This endpoint is public

Request Example

Example
const 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/leagues

Authentication

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-league

  • La Liga - spain-la-liga

  • Bundesliga - germany-bundesliga

  • Serie A - italy-serie-a

  • Ligue 1 - france-ligue-1

  • Champions League - uefa-champions-league

Basketball

  • NBA - usa-nba

  • NCAA Basketball - usa-ncaa

  • EuroLeague - europe-euroleague

American Football

  • NFL - usa-nfl

  • NCAA Football - usa-ncaaf

Tennis

  • ATP Tour - atp

  • WTA Tour - wta

  • Grand 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/events

Authentication

Required - Include your API key

Parameters

Request Examples

Get upcoming Premier League matches

Example
const 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

Example
const 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

Example
events.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/odds

Authentication

Required - Include your API key

Parameters

Request Example

Example
const 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 odds

  • draw - Draw odds (if applicable)

  • away - Away team odds

  • href - Direct bet link (optional)

For Totals (Over/Under):

  • over - Over odds

  • under - Under odds

  • hdp - Line/handicap (e.g., 2.5 goals)

For Spreads:

  • home - Home team odds

  • away - Away team odds

  • hdp - 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

Example
function 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

Example
const 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 operations

Caching 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

Example
1. 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,UnibetDisplay odds

Key Parameters

  • sport - Sport slug from /sports

  • league - League slug from /leagues

  • eventId - Event ID from /events

  • bookmakers - Comma-separated list

  • status - "pending" or "live"

  • limit - Max results to return


Need Help?

Questions about the API workflow?