Soccer API Tutorials

How Soccer Odds APIs Work (With Real Examples)

Learn how Soccer Odds APIs organise matches, bookmakers, markets, selections and prices, with practical examples for live odds, historical movements and market integration.

A Soccer Odds API connects an application to structured betting-market data. Instead of manually collecting prices from multiple websites, developers can retrieve pre-match odds, live odds, bookmaker markets, historical snapshots, market status and settlement information through one documented interface.

This guide explains how Soccer Odds APIs work with practical examples. It covers fixtures, bookmakers, markets, selections, decimal, fractional and American formats, live price changes, historical odds, market suspension, settlement, normalisation, caching, security and production integration.

Important: The endpoint paths, teams, bookmakers, prices, markets and response fields in this tutorial are illustrative examples. Use the confirmed production API documentation, licensing terms and local legal requirements before publishing or operating a betting-related product.

What Is a Soccer Odds API?

A Soccer Odds API returns machine-readable betting data for soccer fixtures. The data is normally organised around a hierarchy of matches, bookmakers, markets, selections and prices.

Match
  └── Bookmaker
      └── Market
          └── Selection
              ├── Price
              ├── Odds format
              ├── Status
              ├── Live or pre-match
              └── Updated timestamp

For example, one match may have several bookmakers. Each bookmaker may offer markets such as match winner, both teams to score, over or under goals and correct score. Each market contains selections with current prices.

Core Soccer Odds Data Model

Entity Purpose Example
Match The soccer fixture being priced North City vs United Athletic
Bookmaker The source offering the price Example Sportsbook
Market The question being priced Match Winner
Selection One possible market outcome Home, Draw or Away
Price The odds assigned to the selection 1.84
Status Whether the market is available Open, suspended, closed or settled
Timestamp When the price was last updated 2026-08-06T10:30:18Z

Pre-Match vs Live vs Historical Odds

Odds type When it is used Typical application
Pre-Match Odds Before kickoff Match previews and pre-event comparison
Live Odds While the match is in progress In-play sportsbook and trading interfaces
Historical Odds Previously recorded prices Research, analytics and model development
Settlement Data After the market is completed Reconciliation and historical records

How Pre-Match Odds Work

Pre-match odds are published before kickoff. They can change as new information becomes available, including line-ups, injuries, weather, team news and market activity.

Illustrative Request

GET /v1/soccer/matches/match_74021/odds

Authorization: Bearer YOUR_API_KEY
Accept: application/json

Illustrative Pre-Match Response

{
  "data": {
    "match_id": "match_74021",
    "status": "scheduled",
    "starts_at": "2026-08-06T18:00:00Z",
    "bookmakers": [
      {
        "bookmaker_id": "bookmaker_12",
        "name": "Example Sportsbook",
        "markets": [
          {
            "market_id": "market_match_winner",
            "name": "Match Winner",
            "status": "open",
            "is_live": false,
            "outcomes": [
              {
                "selection_id": "home",
                "name": "North City",
                "price": 1.84,
                "price_format": "decimal"
              },
              {
                "selection_id": "draw",
                "name": "Draw",
                "price": 3.45,
                "price_format": "decimal"
              },
              {
                "selection_id": "away",
                "name": "United Athletic",
                "price": 4.20,
                "price_format": "decimal"
              }
            ]
          }
        ]
      }
    ],
    "updated_at": "2026-08-06T10:30:18Z"
  }
}

How Live Soccer Odds Work

Live odds are updated while a match is in progress. Prices may change after goals, cards, penalties, substitutions, VAR decisions and changes in match time or statistics.

A market may be suspended around an important event while the bookmaker recalculates its prices.

Illustrative Live Response

{
  "data": {
    "match_id": "match_74021",
    "match_status": "live",
    "minute": 67,
    "score": {
      "home": 2,
      "away": 1
    },
    "bookmakers": [
      {
        "bookmaker_id": "bookmaker_12",
        "markets": [
          {
            "market_id": "market_match_winner",
            "status": "open",
            "is_live": true,
            "outcomes": [
              {
                "selection_id": "home",
                "price": 1.36
              },
              {
                "selection_id": "draw",
                "price": 4.80
              },
              {
                "selection_id": "away",
                "price": 10.50
              }
            ]
          }
        ]
      }
    ],
    "updated_at": "2026-08-06T19:24:12Z"
  }
}

Why Live Markets Become Suspended

Live markets can be temporarily suspended when an event may significantly change the probability of an outcome.

  • A goal is scored
  • A penalty is awarded
  • A red card is shown
  • A VAR review begins
  • The match reaches a critical stage
  • The data connection becomes uncertain
  • The bookmaker closes the market

Illustrative Suspended Market

{
  "market_id": "market_match_winner",
  "status": "suspended",
  "is_live": true,
  "suspended_at": "2026-08-06T19:24:05Z",
  "reason": "important_match_event"
}
Never display a suspended or closed price as an active selection.

Common Soccer Betting Markets

Match Winner

Home win, draw and away win selections.

Double Chance

Home or draw, away or draw, or either team to win.

Both Teams to Score

Yes or no selections for whether both teams score.

Over and Under Goals

Total-goal lines such as over or under 2.5.

Asian Handicap

Handicap selections using quarter, half and whole-goal lines.

Correct Score

Individual scoreline selections where supported.

First Goalscorer

Player selections for the first goal where line-ups are supported.

Cards and Corners

Team or match totals for supported cards and corner markets.

Half-Time and Full-Time

Combined first-half and final-result selections.

Odds Formats Explained

Decimal Odds

Decimal odds show the total return for each unit staked, including the original stake.

Decimal odds: 2.50
Stake: 10

Total return:
10 × 2.50 = 25

Profit:
25 - 10 = 15

Fractional Odds

Fractional odds show the potential profit relative to the stake.

Fractional odds: 3/2
Stake: 10

Profit:
10 × 3 / 2 = 15

Total return:
15 + 10 = 25

American Odds

Positive American odds show the profit from a stake of 100. Negative American odds show the stake required to win 100.

Positive odds: +150
Stake: 100
Profit: 150

Negative odds: -200
Stake required to win 100: 200

Convert Between Odds Formats

Decimal to Fractional

fractional value = decimal odds - 1

Example:
2.50 - 1 = 1.50
1.50 = 3/2

Decimal to American

If decimal odds are 2.00 or greater:

American = (decimal - 1) × 100

If decimal odds are below 2.00:

American = -100 / (decimal - 1)

JavaScript Format Conversion

function decimalToAmerican(decimalOdds) {
  if (!Number.isFinite(decimalOdds) || decimalOdds <= 1) {
    throw new Error('Decimal odds must be greater than 1.');
  }

  if (decimalOdds >= 2) {
    return Math.round((decimalOdds - 1) * 100);
  }

  return Math.round(-100 / (decimalOdds - 1));
}
Keep the original provider price and format even when the frontend displays a converted value.

Implied Probability

Decimal odds can be converted into a basic implied probability.

Implied probability = 1 / decimal odds

Example:
1 / 2.50 = 0.40

Implied probability:
40%

The combined implied probabilities of all selections may exceed 100% because the prices can include bookmaker margin.

Understanding Bookmaker Margin

Illustrative Match Winner Prices

Home: 2.00
Draw: 3.50
Away: 4.00

Implied Probabilities

Home:
1 / 2.00 = 50.00%

Draw:
1 / 3.50 = 28.57%

Away:
1 / 4.00 = 25.00%

Total:
103.57%

The amount above 100% is commonly used as a simple indication of the market’s built-in margin, though exact pricing interpretation can be more complex.

Why Stable IDs Matter

Bookmakers may use different labels for the same market. Teams and players may also appear with abbreviations or alternative names.

Do not compare:

"Match Result"
"1X2"
"Full Time Result"

using text labels alone.

Instead compare:

market_id = "market_match_winner"

Recommended Stored Identifiers

  • Match ID
  • Competition ID
  • Bookmaker ID
  • Market ID
  • Selection ID
  • Team or player ID where relevant

Normalise Markets Across Bookmakers

An odds comparison tool needs a canonical internal model so equivalent markets can be compared safely.

function normaliseOutcome({
  match,
  bookmaker,
  market,
  outcome,
  updatedAt
}) {
  return {
    matchId: match.id,
    bookmakerId: bookmaker.id,
    marketId: market.id,
    selectionId: outcome.id,
    line: outcome.line ?? null,
    price: Number(outcome.price),
    format: outcome.format ?? 'decimal',
    status: market.status,
    isLive: Boolean(market.is_live),
    updatedAt
  };
}

Example Bookmaker Comparison

Bookmaker Home Draw Away Updated
Example Sportsbook A 1.84 3.45 4.20 10:30:18
Example Sportsbook B 1.88 3.40 4.10 10:30:16
Example Sportsbook C 1.82 3.55 4.25 10:30:20

The best displayed price should be selected only after confirming that the market, selection, settlement rules and timestamp are equivalent.

Historical Odds and Price Movement

Historical odds can show how a selection changed from its opening price to its latest or closing price.

Suggested Snapshot Record

{
  "match_id": "match_74021",
  "bookmaker_id": "bookmaker_12",
  "market_id": "market_match_winner",
  "selection_id": "home",
  "price": 1.84,
  "price_format": "decimal",
  "is_live": false,
  "market_status": "open",
  "captured_at": "2026-08-06T10:30:18Z"
}

Illustrative Price Movement

Time Home Price Market Stage
Opening 2.05 Pre-match
24 hours before kickoff 1.95 Pre-match
One hour before kickoff 1.84 Pre-match
After home goal 1.40 Live
After equaliser 2.10 Live
Confirm that your API licence allows historical storage, display and redistribution before saving long-term odds snapshots.

Request Soccer Odds in JavaScript

const matchId = 'match_74021';

const response = await fetch(
  `/api/soccer/matches/${encodeURIComponent(matchId)}/odds`
);

if (!response.ok) {
  throw new Error(`Odds request failed: ${response.status}`);
}

const payload = await response.json();

for (const bookmaker of payload.data.bookmakers) {
  for (const market of bookmaker.markets) {
    if (market.status !== 'open') {
      continue;
    }

    console.log(bookmaker.name, market.name, market.outcomes);
  }
}

Request Soccer Odds in Python

import requests

match_id = "match_74021"

response = requests.get(
    (
        "https://api.example.com/v1/soccer/"
        f"matches/{match_id}/odds"
    ),
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Accept": "application/json",
    },
    timeout=15,
)

response.raise_for_status()
odds = response.json()

Request Soccer Odds in PHP

<?php

$matchId = 'match_74021';

$url = sprintf(
    'https://api.example.com/v1/soccer/matches/%s/odds',
    rawurlencode($matchId)
);

$ch = curl_init($url);

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
        'Accept: application/json',
    ],
    CURLOPT_TIMEOUT => 15,
]);

$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($body === false) {
    throw new RuntimeException(curl_error($ch));
}

curl_close($ch);

if ($status < 200 || $status >= 300) {
    throw new RuntimeException(
        'Soccer odds API returned HTTP ' . $status
    );
}

$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);

Polling Live Odds

When WebSocket odds streaming is not available, a backend may poll live odds at a controlled interval.

let liveOddsTimer;

function startLiveOddsPolling(matchId) {
  stopLiveOddsPolling();

  liveOddsTimer = setInterval(async () => {
    try {
      await loadLiveOdds(matchId);
    } catch (error) {
      console.error(error);
    }
  }, 15000);
}

function stopLiveOddsPolling() {
  if (liveOddsTimer) {
    clearInterval(liveOddsTimer);
    liveOddsTimer = undefined;
  }
}

Use the confirmed provider rate limits and update guidance rather than copying the example interval directly.

Streaming Live Odds With WebSocket

Illustrative Subscription

const socket = new WebSocket(
  'wss://stream.example.com/v1/soccer'
);

socket.addEventListener('open', () => {
  socket.send(JSON.stringify({
    action: 'authenticate',
    token: 'SHORT_LIVED_ACCESS_TOKEN'
  }));

  socket.send(JSON.stringify({
    action: 'subscribe',
    channel: 'soccer_odds',
    match_ids: ['match_74021']
  }));
});

Illustrative Odds Update Event

{
  "event_id": "odds_event_77192",
  "type": "odds_update",
  "match_id": "match_74021",
  "bookmaker_id": "bookmaker_12",
  "market_id": "market_match_winner",
  "selection_id": "home",
  "old_price": 1.84,
  "new_price": 1.76,
  "status": "open",
  "is_live": true,
  "updated_at": "2026-08-06T19:24:12Z"
}

Handle Duplicate Odds Events

A reconnect may replay events. Store unique event IDs so the same price update is not applied twice.

processed_odds_events

event_id          unique
match_id
bookmaker_id
market_id
selection_id
old_price
new_price
processed_at

Cache Soccer Odds Correctly

Data Suggested cache approach
Bookmakers and market definitions Longer cache with periodic refresh
Upcoming pre-match odds Moderate cache
Live odds Short cache or event-driven update
Suspended markets Refresh according to provider guidance
Settled markets Long cache after final confirmation

Show Price Freshness

Every displayed price should have an update timestamp. A stale price should not be presented as current.

function isPriceStale(updatedAt, maximumAgeMs) {
  const updatedTime = new Date(updatedAt).getTime();

  if (!Number.isFinite(updatedTime)) {
    return true;
  }

  return Date.now() - updatedTime > maximumAgeMs;
}

The allowed age should follow the product requirement and confirmed provider behaviour.

Handle Market Settlement

Settlement data records the final result of a supported betting market.

Illustrative Settlement Response

{
  "market_id": "market_match_winner",
  "status": "settled",
  "settled_at": "2026-08-06T20:00:11Z",
  "outcomes": [
    {
      "selection_id": "home",
      "result": "won"
    },
    {
      "selection_id": "draw",
      "result": "lost"
    },
    {
      "selection_id": "away",
      "result": "lost"
    }
  ]
}

Do not invent settlement rules. Use the provider’s documented market and outcome definitions.

Odds API Security

  • Keep permanent API credentials on your backend
  • Use HTTPS and WSS in production
  • Validate match, bookmaker, market and selection IDs
  • Rate-limit public application endpoints
  • Do not trust prices submitted by the browser
  • Log authentication and subscription failures
  • Rotate exposed credentials
  • Restrict access to authorised users and applications

Common Sportsbook Integration Pattern

Soccer Odds API
       |
       v
Backend ingestion service
       |
       +-- Authentication
       +-- Market normalisation
       +-- Freshness validation
       +-- Duplicate protection
       +-- Historical snapshots
       |
       v
Internal odds store
       |
       +-- Sportsbook interface
       +-- Odds comparison page
       +-- Trading dashboard
       +-- Analytics pipeline
       +-- Affiliate widgets

Common Soccer Odds API Mistakes

Comparing Markets by Name Alone

Use stable market and selection identifiers.

Displaying Suspended Prices as Active

Always check market status before rendering an actionable price.

Ignoring Update Timestamps

Show freshness and avoid presenting stale odds as live.

Mixing Pre-Match and Live Prices

Store and display them as separate market states.

Overwriting Historical Prices

Store timestamped snapshots when your licence permits historical storage.

Assuming Every Bookmaker Uses the Same Rules

Confirm market definitions and settlement terms before comparison.

Exposing the API Key in Frontend Code

Keep permanent private credentials on the server.

Legal and Responsible-Gambling Considerations

Soccer betting products can be subject to licensing, age restrictions, geographic limitations, advertising rules and responsible-gambling requirements.

  • Confirm the laws in every target jurisdiction
  • Obtain qualified legal advice
  • Review provider display and redistribution rights
  • Use approved bookmaker attribution
  • Apply age and geographic controls where required
  • Avoid guaranteed-profit or guaranteed-win claims
  • Provide responsible-gambling information where relevant
Access to odds data does not by itself authorise a company to operate a sportsbook, accept bets or promote gambling services.

Soccer Odds API FAQs

What does a Soccer Odds API provide?

Depending on coverage, it can provide pre-match odds, live odds, bookmaker markets, historical prices, market status and settlement results.

What is the difference between pre-match and live odds?

Pre-match odds are available before kickoff. Live odds update while the match is in progress.

Which odds format should I store?

Store the provider’s original format and value. Many systems also normalise prices to decimal for internal calculations.

Can I compare multiple bookmakers?

Yes, when equivalent markets and selections are matched through stable IDs and the commercial terms permit comparison.

How often do live odds update?

Update timing depends on the provider, competition, bookmaker, market and delivery method. Use documented timestamps and service guidance.

Can I store historical soccer odds?

Only when the provider’s licence and selected plan permit storage and redistribution.

What happens when a market is suspended?

Treat the price as temporarily unavailable and do not present it as an active selection.

Do soccer odds guarantee an outcome?

No. Odds represent market prices and implied assessments, not guaranteed results.

Integrate Soccer Odds Into Your Product

Start with stable match, bookmaker, market and selection IDs. Preserve timestamps, handle suspended markets correctly and use secure server-side API access.

Build Cricket Products With Reliable API Data

Access live scores, fixtures, ball-by-ball updates, statistics, odds, predictions and historical cricket data through one developer-friendly API.

Get API Access
Written By

James

Chat on WhatsApp