Pre-match odds
Bookmaker prices for one match before kickoff, one entry per bookmaker. Every selection shows the first price we saw and the latest one, so you can compare bookmakers or follow how a line moved. Markets run from the result and goals to corners, cards, shots and penalties.
https://api.soccer-data.co/v1/matches/{match_id}/odds
Live Pro or Business plan
- Needs a paid plan (Pro or Business). The Free plan gets 403 PLAN_UPGRADE_REQUIRED.
- Check odds_available on the match before calling. A match without odds returns 404 NOT_FOUND, and postponed or cancelled matches never have any.
- Works for upcoming and finished matches. Older matches mostly have Bet365 prices only, often with opening set to null.
- If the match has odds but none from the bookmakers you asked for, you get 200 with an empty bookmakers list.
- A market only appears when that bookmaker prices it. Shots, throw-ins, goal kicks, tackles and offsides are mostly offered on bigger fixtures, and to_qualify only appears for knockout ties.
- Prices are decimal odds sent as strings, such as "1.380". Convert them yourself if you need fractional or American odds.
The match's id, like match_…. Find one with the ID guide.
One or more bookmakers, comma-separated, such as bet365,pinnacle. Leave it out to get every bookmaker. An unknown slug returns 400 BAD_REQUEST.
bet365paddy-powerbetmgm-ukpinnaclebetfair-exchangeThe match these prices are for.
One entry per bookmaker with prices for this match.
Bookmaker name: Bet365, Paddy Power, BetMGM UK, Pinnacle or Betfair Exchange.
This bookmaker's markets, keyed by market name. Markets it doesn't price are left out. Each selection below is a price object (see {price} fields).
Three-way result markets: match_odds, first_half_result and second_half_result.
Two-way markets: draw_no_bet, to_qualify, to_score_a_penalty and to_miss_a_penalty.
Double chance markets: double_chance and half_time_double_chance.
Yes or no markets: btts, btts_first_half, btts_second_half and a_penalty_in_match.
Which side scores first. none means no goals.
Match over/under markets, keyed by line such as "2.5": total_goals, first_half_total_goals, match_corners, total_cards, match_shots, match_shots_on_target, first_half_match_shots, second_half_match_shots, first_half_match_shots_on_target, second_half_match_shots_on_target, match_throw_ins, first_half_match_throw_ins, second_half_match_throw_ins, match_goal_kicks, first_half_match_goal_kicks, second_half_match_goal_kicks, match_tackles and match_offsides. first_half_total_goals is mostly .5 lines, though some bookmakers add whole and quarter lines.
Team over/under markets, split by side and then keyed by line such as "1.5": team_total_goals, team_corners, team_shots, team_shots_on_target, first_half_team_shots, second_half_team_shots, first_half_team_shots_on_target, second_half_team_shots_on_target, team_throw_ins, first_half_team_throw_ins, second_half_team_throw_ins, team_goal_kicks, first_half_team_goal_kicks, second_half_team_goal_kicks, team_tackles and team_offsides.
Asian handicap price for each side, keyed by that side's handicap, such as "-1.0" or "+0.5".
Three-way handicap, keyed by the home team's handicap such as "-1" or "+2".
Total goals combined with both teams to score, keyed by goals line.
Exact score, keyed as home-away such as "2-1".
Decimal price when the bookmaker first listed this selection. Null when no opening price was recorded.
The latest decimal price. For Betfair Exchange it matches the best back price.
Betfair Exchange only: up to 3 price levels you can back at, best first. An empty list means no unmatched offers right now. Missing for the other bookmakers.
Decimal price at this level.
Money available at this price.
Betfair Exchange only: up to 3 price levels you can lay at, best first. Same rules as available_to_back.
Decimal price at this level.
Money available at this price.
curl "https://api.soccer-data.co/v1/matches/match_yoeml0e6ae37/odds" \ -H "X-Api-Key: $SOCCER_DATA_KEY"
const res = await fetch("https://api.soccer-data.co/v1/matches/match_yoeml0e6ae37/odds", {
headers: { "X-Api-Key": process.env.SOCCER_DATA_KEY },
});
const { data } = await res.json();
import os, requests
res = requests.get(
"https://api.soccer-data.co/v1/matches/match_yoeml0e6ae37/odds",
headers={"X-Api-Key": os.environ["SOCCER_DATA_KEY"]},
)
data = res.json()["data"]
$data = Http::withHeaders(['X-Api-Key' => env('SOCCER_DATA_KEY')])
->get('https://api.soccer-data.co/v1/matches/match_yoeml0e6ae37/odds')
->json('data');
{
"data": {
"match_id": "match_yoeml0e6ae37",
"bookmakers": [
{
"bookmaker": "Bet365",
"markets": {
"match_odds": {
"home": {
"opening": "1.380",
"last_seen": "1.380"
},
"draw": {
"opening": "4.500",
"last_seen": "5.000"
},
"away": {
"opening": "7.500",
"last_seen": "7.500"
}
},
"btts": {
"yes": {
"opening": "2.000",
"last_seen": "2.050"
},
"no": {
"opening": "1.750",
"last_seen": "1.700"
}
},
"total_goals": {
"2.5": {
"over": {
"opening": "1.725",
"last_seen": "1.800"
},
"under": {
"opening": "2.075",
"last_seen": "2.000"
}
}
},
"team_total_goals": {
"home": {
"1.5": {
"over": {
"opening": "1.533",
"last_seen": "1.571"
},
"under": {
"opening": "2.375",
"last_seen": "2.300"
}
}
},
"away": {
"0.5": {
"over": {
"opening": "1.571",
"last_seen": "1.615"
},
"under": {
"opening": "2.300",
"last_seen": "2.200"
}
}
}
},
"asian_handicap": {
"home": {
"-1.0": {
"opening": "1.950",
"last_seen": "1.900"
}
},
"away": {
"+1.0": {
"opening": "1.900",
"last_seen": "1.950"
}
}
},
"first_half_result": {
"home": {
"opening": "1.833",
"last_seen": "1.909"
},
"draw": {
"opening": "2.500",
"last_seen": "2.400"
},
"away": {
"opening": "7.500",
"last_seen": "7.500"
}
},
"correct_score": {
"1-0": {
"opening": "7.500",
"last_seen": "8.000"
},
"2-0": {
"opening": "7.000",
"last_seen": "6.500"
}
}
}
},
{
"bookmaker": "Betfair Exchange",
"markets": {
"match_odds": {
"home": {
"opening": "1.400",
"last_seen": "1.400",
"available_to_back": [
{
"price": 1.4,
"size": 5210.77
},
{
"price": 1.39,
"size": 3120.5
}
],
"available_to_lay": [
{
"price": 1.41,
"size": 2875.12
},
{
"price": 1.42,
"size": 1910.4
}
]
},
"draw": {
"opening": "4.800",
"last_seen": "5.100",
"available_to_back": [
{
"price": 5.1,
"size": 640.25
},
{
"price": 5.0,
"size": 1188.9
}
],
"available_to_lay": [
{
"price": 5.2,
"size": 412.6
}
]
},
"away": {
"opening": "8.000",
"last_seen": "8.200",
"available_to_back": [
{
"price": 8.2,
"size": 301.15
}
],
"available_to_lay": [
{
"price": 8.4,
"size": 255.8
},
{
"price": 8.6,
"size": 190.0
}
]
}
}
}
}
]
}
}
### GET /matches/{match_id}/odds
Pre-match odds
Bookmaker prices for one match before kickoff, one entry per bookmaker. Every selection shows the first price we saw and the latest one, so you can compare bookmakers or follow how a line moved. Markets run from the result and goals to corners, cards, shots and penalties.
Requires the Pro or Business plan.
- Needs a paid plan (Pro or Business). The Free plan gets 403 PLAN_UPGRADE_REQUIRED.
- Check odds_available on the match before calling. A match without odds returns 404 NOT_FOUND, and postponed or cancelled matches never have any.
- Works for upcoming and finished matches. Older matches mostly have Bet365 prices only, often with opening set to null.
- If the match has odds but none from the bookmakers you asked for, you get 200 with an empty bookmakers list.
- A market only appears when that bookmaker prices it. Shots, throw-ins, goal kicks, tackles and offsides are mostly offered on bigger fixtures, and to_qualify only appears for knockout ties.
- Prices are decimal odds sent as strings, such as "1.380". Convert them yourself if you need fractional or American odds.
Query parameters:
- `bookmaker` (string, one of bet365, paddy-power, betmgm-uk, pinnacle, betfair-exchange): One or more bookmakers, comma-separated, such as bet365,pinnacle. Leave it out to get every bookmaker. An unknown slug returns 400 BAD_REQUEST.
Response fields:
- `data.match_id` (string): The match these prices are for.
- `data.bookmakers[]` (array): One entry per bookmaker with prices for this match.
- `data.bookmakers[].bookmaker` (string): Bookmaker name: Bet365, Paddy Power, BetMGM UK, Pinnacle or Betfair Exchange.
- `data.bookmakers[].markets` (object): This bookmaker's markets, keyed by market name. Markets it doesn't price are left out. Each selection below is a price object (see {price} fields).
- `data.bookmakers[].markets.{market}.{home|draw|away}` (object): Three-way result markets: match_odds, first_half_result and second_half_result.
- `data.bookmakers[].markets.{market}.{home|away}` (object): Two-way markets: draw_no_bet, to_qualify, to_score_a_penalty and to_miss_a_penalty.
- `data.bookmakers[].markets.{market}.{home_draw|home_away|draw_away}` (object): Double chance markets: double_chance and half_time_double_chance.
- `data.bookmakers[].markets.{market}.{yes|no}` (object): Yes or no markets: btts, btts_first_half, btts_second_half and a_penalty_in_match.
- `data.bookmakers[].markets.first_team_to_score.{home|away|none}` (object): Which side scores first. none means no goals.
- `data.bookmakers[].markets.{market}.{line}.{over|under}` (object): Match over/under markets, keyed by line such as "2.5": total_goals, first_half_total_goals, match_corners, total_cards, match_shots, match_shots_on_target, first_half_match_shots, second_half_match_shots, first_half_match_shots_on_target, second_half_match_shots_on_target, match_throw_ins, first_half_match_throw_ins, second_half_match_throw_ins, match_goal_kicks, first_half_match_goal_kicks, second_half_match_goal_kicks, match_tackles and match_offsides. first_half_total_goals is mostly .5 lines, though some bookmakers add whole and quarter lines.
- `data.bookmakers[].markets.{market}.{home|away}.{line}.{over|under}` (object): Team over/under markets, split by side and then keyed by line such as "1.5": team_total_goals, team_corners, team_shots, team_shots_on_target, first_half_team_shots, second_half_team_shots, first_half_team_shots_on_target, second_half_team_shots_on_target, team_throw_ins, first_half_team_throw_ins, second_half_team_throw_ins, team_goal_kicks, first_half_team_goal_kicks, second_half_team_goal_kicks, team_tackles and team_offsides.
- `data.bookmakers[].markets.asian_handicap.{home|away}.{line}` (object): Asian handicap price for each side, keyed by that side's handicap, such as "-1.0" or "+0.5".
- `data.bookmakers[].markets.handicap_result.{line}.{home|draw|away}` (object): Three-way handicap, keyed by the home team's handicap such as "-1" or "+2".
- `data.bookmakers[].markets.total_goals_btts.{line}.{over_yes|over_no|under_yes|under_no}` (object): Total goals combined with both teams to score, keyed by goals line.
- `data.bookmakers[].markets.correct_score.{score}` (object): Exact score, keyed as home-away such as "2-1".
- `{price}.opening` (string|null): Decimal price when the bookmaker first listed this selection. Null when no opening price was recorded.
- `{price}.last_seen` (string): The latest decimal price. For Betfair Exchange it matches the best back price.
- `{price}.available_to_back[]` (array): Betfair Exchange only: up to 3 price levels you can back at, best first. An empty list means no unmatched offers right now. Missing for the other bookmakers.
- `{price}.available_to_back[].price` (number): Decimal price at this level.
- `{price}.available_to_back[].size` (number): Money available at this price.
- `{price}.available_to_lay[]` (array): Betfair Exchange only: up to 3 price levels you can lay at, best first. Same rules as available_to_back.
- `{price}.available_to_lay[].price` (number): Decimal price at this level.
- `{price}.available_to_lay[].size` (number): Money available at this price.
Example: curl "https://api.soccer-data.co/v1/matches/match_yoeml0e6ae37/odds" -H "X-Api-Key: $SOCCER_DATA_KEY"