API Reference
Live Scores, Stats & Odds
Everything happening in a live match โ scores, match stats, point-by-point and odds. All endpoints on this page are REST under /tennis/v2/extend/api/; for push updates see Socket.IO Integration (MEGA).
- Match ID (from upcoming, fixture or H2H rows): start with Live Match by matchId โ every row already has it as
links.live. It returns the current status, score, server and timeline, plus the liveeventIdand ready-to-call statistics and point-by-point links.liveMatchIdon those rows equalsmatchIdon live rows. - eventId: Live Match Score, timeline, match statistics by event ID, the odds routes (recent, best, summary, history, compare, arbitrage, pre-match), and Socket.IO.
- Player names + match date: Detailed Live Match Statistics and Point-by-Point By Players (both take
date_only).
- Score and server โ follow
links.live(Live Match by matchId): status, score, server, timeline and the liveeventId. - Detailed live statistics โ follow
links.detailedStats(Detailed Live Match Statistics): full statistics for the match, live and after the match, with set-by-set breakdowns where available. - Point-by-point โ follow
links.pointByPoint(Point-by-Point By Players), live or after the match. Point-by-Point by IDs and the legacy matchId route are kept for existing integrations.
These links come with the players and date filled in, so you never rebuild names, dates or identifier formats. Where a link is unavailable, use the relevant endpoint's documented lookup parameters. For in-play prices use Recent Odds with inplay=true.
What's included
- Live matches โ all live events, live count, upcoming live-feed events and finding an event by player names and date.
- Live scores & match stats โ live score (set-by-set score, current point, server), match statistics (or by event ID) per set and for the whole match (aces, double faults, first and second serve, break points, return points, points and games in a row, tiebreaks) and the match timeline (game by game).
- Point-by-point โ every point of a match, by IDs or by player names and date.
- Live Odds โ In-Play Prices โ latest odds for all markets (add
inplay=truefor in-play prices only), best odds across bookmakers, last 10 odds movements and the full odds history of a match. - Odds analysis โ pre-match odds, opening and closing pre-match odds, odds summary, bookmaker comparison and arbitrage.
Live lists are singles; doubles stay on core fixtures.
Every REST endpoint on this page is available on all plans (live scores, statistics, point-by-point, timeline, live and pre-match odds, odds history, comparison and arbitrage). Only Socket.IO real-time streaming is MEGA only.
- Core fixture
idโ schedule row from/tennis/v2/{atp|wta}/fixtures. Do not send it to odds. - Live
id(often a large number) โ odds, timeline, and live score on this page. matchIdfrom the live event โ splitplayer1Id-player2Id-tournamentId-roundIdfor point-by-point. Not the liveid.
Bridge names to a live event with /tennis/v2/extend/api/event/get/{player1}/{player2}/{YYYY-MM-DD}. Odds compare and arbitrage take the live id in the path and market_id as a query.
All Available Bookmakers
/tennis/v2/extend/api/bookmakers/allResponse Properties
| Field | Type | Description |
|---|---|---|
results[].id | string | Bookmaker ID (use as bookmakerId; numeric string). |
results[].name | string | Bookmaker display name. |
results[].slug | string | URL/code-friendly bookmaker identifier, e.g. "bet365". |
success | boolean | true when the request succeeded. |
results | array | List of result items documented in the rows below. |
results[] | object | One item of `results`; its fields are listed below. |
All Available Odds Markets
/tennis/v2/extend/api/markets/allResponse Properties
| Field | Type | Description |
|---|---|---|
results[].id | string | Market ID (use as market_id / marketId; numeric string). |
results[].key | string | Short market key/code, e.g. "13_1". |
results[].name | string | Market name, e.g. "Full Time Result". Use this name for odds/by-market?market=โฆ |
success | boolean | true when the request succeeded. |
results | array | List of result items documented in the rows below. |
results[] | object | One item of `results`; its fields are listed below. |
Live Matches
/tennis/v2/extend/api/events/liveResponse Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament ยท LiveEvent.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the live request succeeded. |
results | array | Live matches. Empty when nothing is in play. |
count | integer | Number of events in results. |
id | string | Live event ID for odds, timeline, and live score. Not a core fixture ID. |
matchKey | string | player1Id-player2Id-tournamentId-roundId. Split on - for the point-by-point path. |
matchId | string | Deprecated on this route: same value as matchKey, use matchKey. Planned removal 3 December 2026. |
status | string | Match state, e.g. InPlay, Upcoming, Ended. |
score | string | Set score, e.g. 6-4,3-2. |
points | string | Current game points, e.g. 30-15. |
indicator | string | Who is serving / which side is indicated in the current game. |
tourType | string | atp or wta. |
startTimestamp | integer | Scheduled start as Unix seconds (UTC). |
message | string | Status message, e.g. "Success". |
results[].name | string | Match name, "Player A vs Player B". |
results[].participant1 | string | First player's display name. |
results[].participant2 | string | Second player's display name. |
results[].league | string | Tournament name as shown by the live feed, e.g. "M15 Ann Arbor". |
results[].player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
results[].player1.name | string | First player's name. |
results[].player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
results[].player2.name | string | Second player's name. |
results[].tournament | object | Tournament object (id, name, date, level, surface, country, โฆ). |
results[].tournament.name | string | Tournament name. |
Count Live Events
/tennis/v2/extend/api/events/live/countResponse Properties
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
message | string | Status message, e.g. "Success". |
result | object | Response payload object documented in the rows below. |
result.count | number | Number of items in this response (or matching items, where stated). |
All Upcoming Events
/tennis/v2/extend/api/events/upcoming/{atp|wta}atp. Use wta for the women's dataset.Returns upcoming events with status Not Started. Only page is a query param โ page size is always 50 (limit in the query string is ignored). Path dataset is atp or wta.Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
atp|wta | Yes | string | Dataset to query. atp = men's tennis across all supported levels, including Grand Slams, ATP Tour, Challengers and ITF. wta = women's tennis across all supported levels, including Grand Slams, WTA Tour and ITF. There is no separate itf value. |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
page | No | integer | Page number, starting at 1. Default 1. Page size is fixed at 50. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament.
| Field | Type | Description |
|---|---|---|
success / message | mixed | Request status. |
results | array | Upcoming live-board events. |
results[].id | string | Live event id for odds/timeline routes. |
results[].matchKey | string | player1Id-player2Id-tournamentId-roundId for point-by-point. |
results[].matchId | string | Deprecated on this route: same value as matchKey, use matchKey. Planned removal 3 December 2026. |
pagination | object | page, limit (always 50), total, totalPages, hasNext, hasPrev. Sending limit in the query does not change page size. |
results[].name | string | Match name, "Player A vs Player B". |
results[].participant1 | string | First player's display name. |
results[].participant2 | string | Second player's display name. |
results[].league | string | Tournament name as shown by the live feed, e.g. "M15 Ann Arbor". |
results[].status | string | Event status: InPlay, Not Started or Ended. |
results[].player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
results[].player1.name | string | First player's name. |
results[].player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
results[].player2.name | string | Second player's name. |
results[].tournament | object | Tournament object (id, name, date, level, surface, country, โฆ). |
results[].tournament.name | string | Tournament name. |
results[].tourType | string | Dataset: atp (men) or wta (women). |
results[].startTimestamp | number | Scheduled start as Unix seconds. |
pagination.page | number | Current page. |
pagination.limit | number | Items per page. |
pagination.total | number | Total upcoming events. |
pagination.totalPages | number | Total pages. |
pagination.hasNext | boolean | true when a next page exists. |
pagination.hasPrev | boolean | true when a previous page exists. |
Get Event
/tennis/v2/extend/api/event/get/{player1}/{player2}/{dateOnly} GET
/tennis/v2/extend/api/event/get/{player1}/{player2} Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
player1 | Yes | string | First player display name. E.g: Jannik Sinner |
player2 | Yes | string | Second player display name. E.g: Carlos Alcaraz |
dateOnly | No | string | Target date in YYYY-MM-DD format. Example: 2026-01-01. |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
odds | No | string | Use the odds=yes query parameter to include the latest available odds for the matched event from multiple bookmakers. The response includes the market, bookmaker, player odds, line, and odds update time for each bookmaker. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament ยท Plan-restricted field ยท LiveEvent.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
result | object | Response payload object documented in the rows below. |
result.id | string | Live event ID. |
result.name | string | Name of the matching player or tournament. |
result.participant1 | string | First player's display name. |
result.participant2 | string | Second player's display name. |
result.league | string | Tournament name as shown by the live feed, e.g. "M15 Ann Arbor". |
result.score | string | Set score so far, e.g. "6-4,3-2". |
result.status | string | Event status: InPlay, Not Started or Ended. |
result.points | string | Points in the current game, e.g. "30-15" or "40-A". null when the feed has no point score (before the first point, between sets, or after the match). |
result.indicator | string | Who is serving, as "p1,p2": "1,0" = player 1 serving, "0,1" = player 2 serving. |
result.stats | object | Legacy summary (aces, double faults, first serve, break points), kept for existing integrations. For match statistics use Detailed Live Match Statistics (by players or by event ID): the full statistics for the match and by set. |
result.stats.aces | array | Aces: [participant1, participant2] as strings. |
result.stats.double_faults | array | Double faults: [participant1, participant2] as strings. |
result.stats.win_1st_serve | array | First-serve points won %: [participant1, participant2] as strings. |
result.stats.break_point_conversions | array | Break-point conversion %: [participant1, participant2] as strings. |
result.timeline | array | Timeline events. |
result.timeline[] | object | One item of `result.timeline`; its fields are listed below. |
result.timeline[].id | string | Unique timeline event ID. |
result.timeline[].text | string | Human-readable event text, e.g. "Game 1 - Alexander Zverev - breaks to 30". |
result.player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
result.player1.name | string | First player's name. |
result.player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
result.player2.name | string | Second player's name. |
result.tournament | object | Tournament object (id, name, date, level, surface, country, โฆ). |
result.tournament.name | string | Tournament name. |
result.tourType | string | Dataset: atp (men) or wta (women). |
result.startTimestamp | number | Scheduled start as Unix seconds. |
result.roundId | number | Numeric round ID (see GET /tennis/v2/round): e.g. 4 = First, 5 = Second, 9 = 1/4, 10 = 1/2, 12 = Final; 0โ3 are qualifying rounds. |
result.matchKey | string | Core API bridge: "player1Id-player2Id-tournamentId-roundId" (equals liveMatchId on Upcoming Matches rows). Not the live id. |
result.matchId | string | Deprecated: same value as matchKey, use matchKey. Planned removal 3 December 2026. |
message | string | Status message, e.g. "Success". |
Live Match Score
/tennis/v2/extend/api/event/live-score/get/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Plan-restricted field ยท LiveEvent.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
result | object | Response payload object documented in the rows below. |
result.id | string | Live event ID. |
result.participant1 | string | First player's display name. |
result.participant2 | string | Second player's display name. |
result.indicator | string | Who is serving, as "p1,p2": "1,0" = player 1 serving, "0,1" = player 2 serving. |
result.score | string | Set score so far, e.g. "6-4,3-2". |
result.points | string | Points in the current game, e.g. "30-15" or "40-A". null when the feed has no point score (before the first point, between sets, or after the match). |
result.stats | object | Legacy summary (aces, double faults, first serve, break points), kept for existing integrations. For match statistics use Detailed Live Match Statistics (by players or by event ID): the full statistics for the match and by set. |
result.stats.aces | array | Aces: [participant1, participant2] as strings. |
result.stats.double_faults | array | Double faults: [participant1, participant2] as strings. |
result.stats.win_1st_serve | array | First-serve points won %: [participant1, participant2] as strings. |
result.stats.break_point_conversions | array | Break-point conversion %: [participant1, participant2] as strings. |
result.timeline | array | Timeline events. |
result.timeline[] | object | One item of `result.timeline`; its fields are listed below. |
result.timeline[].id | string | Unique timeline event ID. |
result.timeline[].text | string | Human-readable event text, e.g. "Game 1 - Alexander Zverev - breaks to 30". |
result.status | string | Event status: InPlay, Not Started or Ended. |
message | string | Status message, e.g. "Success". |
Live Match by matchId
Returns data only while the live service holds the match: from shortly before it starts until some weeks after it ends. The example is the 2026 US Open final, Zverev v Shelton (key 24008-87562-21349-12, source=game): a stable key, because completed numeric matchIds are renumbered when the archive reloads. For a match today, take matchId (or links.live) from Upcoming Matches.
/tennis/v2/matches/{matchId}/livePath Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
matchId | Yes | string | From matchId on upcoming or fixtures rows, or a liveMatchId (player1Id-player2Id-tournamentId-roundId), which stays the same from the schedule to the completed match. |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
type | No | string | atp or wta. Optional; speeds up the lookup and avoids ambiguity. |
source | No | string | today (upcoming schedule) or game (completed matches). Optional: upcoming and completed matches are numbered separately, so links from schedule rows pass source=today and links from draws and results for completed matches pass source=game. Without it, an upcoming number that has left the schedule can match a different, archived match. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament ยท LiveEvent.
| Field | Type | Description |
|---|---|---|
matchId | integer | The resolved matchId (upcoming, fixtures or completed). |
liveMatchId | string | "player1Id-player2Id-tournamentId-roundId": the live service's matchId for this match. |
eventId | string | Live event id. Use it with the live odds, statistics and timeline routes and with Socket.IO join-event. |
status | string | Live status from the feed, e.g. Not Started, InPlay, Ended. |
orientation | string | Always as_match: score, points, indicator and stats are in the order of player1 / player2 below (the match record's order), even when the live feed lists the players the other way round. Completed matches list the winner as player1. |
score | string|null | Set scores so far, comma-separated, player1's games first ("6-4,2-2"). null before the first game. |
points | string|null | Points in the current game, player1 first ("30-15"). null when the feed has no point score. |
indicator | string|null | Who is serving: "1,0" = player1, "0,1" = player2. |
startTimestamp | integer|null | Scheduled start, Unix seconds. |
player1 / player2 | object | id and name (core player IDs, usable on every player route). |
tournament | object | id (core tournament ID) and name. |
stats | object|null | Legacy summary kept for existing integrations: each key is [player1, player2] as strings (aces, double_faults, win_1st_serve %, break_point_conversions %). For match statistics use links.detailedStats (Detailed Live Match Statistics), the full statistics for the match and by set. |
timeline | array|null | Game-by-game log, oldest first: id and text. |
links.detailedStats / links.pointByPoint | string | Ready-to-call Detailed Live Match Statistics (full statistics for the match and by set) and Point-by-Point By Players (recommended) for this match, with players and match day filled in. Absent when the day is unknown. |
type | string | Dataset: atp (men) or wta (women). |
player1.id | number | Player 1 ID. |
player1.name | string | Player 1 name. |
player2.id | number | Player 2 ID. |
player2.name | string | Player 2 name. |
tournament.id | number | Tournament season ID. |
tournament.name | string | Tournament name. |
roundId | number | Numeric round ID (see GET /tennis/v2/round): e.g. 4 = First, 5 = Second, 9 = 1/4, 10 = 1/2, 12 = Final; 0โ3 are qualifying rounds. |
stats.aces | array | Aces: [participant1, participant2] as strings. |
stats.double_faults | array | Double faults: [participant1, participant2] as strings. |
stats.win_1st_serve | array | First-serve points won %: [participant1, participant2] as strings. |
stats.break_point_conversions | array | Break-point conversion %: [participant1, participant2] as strings. |
timeline[].id | string | Unique timeline event ID. |
timeline[].text | string | Human-readable event text, e.g. "Game 1 - Alexander Zverev - breaks to 30". |
Point-by-Point By Players
/tennis/v2/extend/api/event/data/point-by-point/{player1}/{player2}Scores follow the player order returned in this responseโnot necessarily the winner first. A server value of 1 means the returned player1 is serving; 2 means player2.
For a game-by-game summary showing who held or broke serve, use Match Timeline (Game by Game).
Coverage: live matches, and completed matches since 2010 where recorded. Some matches have gaps in the source data, so not every match has every point.
Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
player1 | Yes | string | First player display name. E.g: Jannik Sinner |
player2 | Yes | string | Second player display name. E.g: Carlos Alcaraz |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
date_only | No | string | Target date in YYYY-MM-DD format. Example: date_only=2026-01-01. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Point-by-point set and game.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
meta | object | Value returned by the API for this field. |
meta.matchKey | string | player1Id-player2Id-tournamentId-roundId of the match. |
meta.matchId | string | Deprecated: same value as matchKey, use matchKey. Planned removal 3 December 2026. |
meta.player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
meta.player1.id | string | Player 1 ID. |
meta.player1.name | string | Player 1 name. |
meta.player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
meta.player2.id | string | Player 2 ID. |
meta.player2.name | string | Player 2 name. |
meta.orientation | string | Value returned by the API for this field. |
meta.server1 | string | Value returned by the API for this field. |
meta.server2 | string | Value returned by the API for this field. |
meta.status | string | Status string (see the endpoint: Active/Retired for players, InPlay / Not Started / Ended for live events). |
meta.dateOnly | string | Match date (YYYY-MM-DD). |
result | object | Response payload object documented in the rows below. |
result.sets | array | Sets with their games (point-by-point). |
result.sets[] | object | One item of `result.sets`; its fields are listed below. |
result.sets[].games | array | Games of the set in order. |
result.sets[].games[] | object | One item of `result.sets[].games`; its fields are listed below. |
result.sets[].games[].server | number | Who served the game: 1 = player 1, 2 = player 2, 0 = unknown. |
result.sets[].games[].tiebreak | boolean | true when this game is a tiebreak. |
result.sets[].games[].finalScore | string | Games score in the set after this game, e.g. "3-2". |
result.sets[].games[].gameNumber | number | Game number within the set (1-based). |
result.sets[].games[].fifteens_content | string | Point-by-point score of the game, comma-separated, as "player1:player2" after each point (e.g. "15:0, 30:0, 40:15"). "BP" marks a break point; in tiebreaks the serving side is marked with * ("*1:0" = player 1 served). |
result.sets[].setScore | string | Final score of the set, e.g. "6-3" or "7-6"; empty while the set is in progress. |
result.sets[].setNumber | number | Set number (1-based). |
result.score | string | Set score so far, e.g. "6-4,3-2". |
Point-by-Point By Ids
/tennis/v2/extend/api/event/pbp/{player1Id}/{player2Id}/{tournamentId}/{roundId}Find these four IDs in the live eventโs matchKey or the upcoming matchโs liveMatchId, formatted as player1Id-player2Id-tournamentId-roundId. This is different from the live eventId used for odds and timelines.
For a game-by-game summary showing who held or broke serve, use Match Timeline (Game by Game).
Coverage: live matches, and completed matches since 2010 where recorded. Some matches have gaps in the source data, so not every match has every point.
Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
player1Id | Yes | number | First Player ID (โฅ 1). |
player2Id | Yes | integer | Second Player ID (โฅ 1). |
tournamentId | Yes | integer | Tournament ID must be numeric value >= 1 |
roundId | Yes | integer | Round ID Example: roundId=9 |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Point-by-point set and game.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
meta | object | Value returned by the API for this field. |
meta.matchKey | string | player1Id-player2Id-tournamentId-roundId of the match. |
meta.matchId | string | Deprecated: same value as matchKey, use matchKey. Planned removal 3 December 2026. |
meta.player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
meta.player1.id | string | Player 1 ID. |
meta.player1.name | string | Player 1 name. |
meta.player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
meta.player2.id | string | Player 2 ID. |
meta.player2.name | string | Player 2 name. |
meta.orientation | string | Value returned by the API for this field. |
meta.server1 | string | Value returned by the API for this field. |
meta.server2 | string | Value returned by the API for this field. |
meta.status | string | Status string (see the endpoint: Active/Retired for players, InPlay / Not Started / Ended for live events). |
meta.dateOnly | string | Match date (YYYY-MM-DD). |
result | object | Response payload object documented in the rows below. |
result.sets | array | Sets with their games (point-by-point). |
result.sets[] | object | One item of `result.sets`; its fields are listed below. |
result.sets[].games | array | Games of the set in order. |
result.sets[].games[] | object | One item of `result.sets[].games`; its fields are listed below. |
result.sets[].games[].server | number | Who served the game: 1 = player 1, 2 = player 2, 0 = unknown. |
result.sets[].games[].tiebreak | boolean | true when this game is a tiebreak. |
result.sets[].games[].finalScore | string | Games score in the set after this game, e.g. "3-2". |
result.sets[].games[].gameNumber | number | Game number within the set (1-based). |
result.sets[].games[].fifteens_content | string | Point-by-point score of the game, comma-separated, as "player1:player2" after each point (e.g. "15:0, 30:0, 40:15"). "BP" marks a break point; in tiebreaks the serving side is marked with * ("*1:0" = player 1 served). |
result.sets[].setScore | string | Final score of the set, e.g. "6-3" or "7-6"; empty while the set is in progress. |
result.sets[].setNumber | number | Set number (1-based). |
result.score | string | Set score so far, e.g. "6-4,3-2". |
Match Timeline (Game by Game)
/tennis/v2/extend/api/event/timeline/{eventId}For the scoring progression within each game, use Point-by-Point By Players.
Matches without a recorded timeline return an empty result.
Coverage: timelines come from our live data feed (BetsAPI) and depend on how long that feed data is retained.
Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Response Properties
| Field | Type | Description |
|---|---|---|
results | array | Timeline events in chronological order. |
results[].id | string | Unique timeline event ID. |
results[].text | string | Human-readable match event, e.g. a hold, break or tiebreak result ("Game 1 - Alexander Zverev - breaks to 30"). |
success | boolean | true when the request succeeded. |
message | string | Status message, e.g. "Success". |
Detailed Live Match Statistics
Get detailed live match statistics, including set-by-set breakdowns where available (during play some matches return whole-match totals only). Some historical data is also available. For the extensive historical match statistics archive, with records dating back to 2003, use Completed Match Statistics by matchId: /tennis/v2/matches/{matchId}/stats.
/tennis/v2/extend/api/event/data/statistics/:player1/:player2Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
player1 | Yes | string | First player display name. E.g: Jannik Sinner |
player2 | Yes | string | Second player display name. E.g: Carlos Alcaraz |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
date_only | No | string | Target date in YYYY-MM-DD format. Example: date_only=2026-01-01. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Statistics metric.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
player1.name | string | Player 1 name. |
player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
player2.name | string | Player 2 name. |
statistics | object | Match statistics by period, category and metric (see the statistics rows). |
statistics.{period} | object | Statistics for one period: 1ST, 2ND, โฆ = that set; ALL = whole match. |
statistics.{period}.{category}.{metric}.{player} | object | The metric for player1 and player2 (keys player1 / player2; same shape for every metric). |
statistics.{period}.{category}.{metric}.{player}.value | number | Count for the metric (e.g. aces, points won, serves landed). Present on every metric. |
statistics.{period}.{category}.{metric}.{player}.total | number | What value is out of (e.g. serves attempted, points played). Only on ratio metrics. |
statistics.{period}.{category}.{metric}.{player}.percentage | number | value as a percentage of total. Only on ratio metrics. |
statistics.{period}.games | object | Games category. |
statistics.{period}.games.maxGamesInRow | object | Most consecutive games won. |
statistics.{period}.points | object | Points category. |
statistics.{period}.points.maxPointsInRow | object | Most consecutive points won. |
statistics.{period}.points.servicePointsScored | object | Points won on own serve. |
statistics.{period}.points.receiverPointsScored | object | Points won while returning. |
statistics.{period}.return | object | Return category. |
statistics.{period}.return.returnGamesTotal | object | Return games played. |
statistics.{period}.return.breakPointsScored | object | Break points converted (break points won as returner). |
statistics.{period}.return.firstReturnPoints | object | Points won returning first serve: value = won, total = played. |
statistics.{period}.return.secondReturnPoints | object | Points won returning second serve: value = won, total = played. |
statistics.{period}.service | object | Service category. |
statistics.{period}.service.aces | object | Aces. |
statistics.{period}.service.doubleFaults | object | Double faults. |
statistics.{period}.service.breakPointsSaved | object | Break points saved: value = saved, total = faced. |
statistics.{period}.service.serviceGamesTotal | object | Service games played. |
statistics.{period}.service.firstServeAccuracy | object | First serves landed in: value = in, total = attempted (serve accuracy, not points won). |
statistics.{period}.service.secondServeAccuracy | object | Second serves landed in: value = in, total = attempted. |
statistics.{period}.service.firstServePointsAccuracy | object | Points won behind the first serve: value = won, total = first serves in. |
statistics.{period}.service.secondServePointsAccuracy | object | Points won behind the second serve: value = won, total = second serves played. |
statistics.{period}.miscellaneous | object | Other metrics (tiebreaks). |
statistics.{period}.miscellaneous.tiebreaks | object | Tiebreaks won. |
statistics.{period}.games.gamesWon | object | Games won. |
statistics.{period}.games.serviceGamesWon | object | Service games won (held). |
statistics.{period}.points.pointsTotal | object | Total points won. |
dateOnly | string | Match date (YYYY-MM-DD). |
Detailed Live Match Statistics by Event ID
Get detailed live match statistics, including set-by-set breakdowns where available (during play some matches return whole-match totals only). Some historical data is also available. For the extensive historical match statistics archive, with records dating back to 2003, use Completed Match Statistics by matchId: /tennis/v2/matches/{matchId}/stats.
/tennis/v2/extend/api/event/get/statistics/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Statistics metric.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
player1.name | string | Player 1 name. |
player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
player2.name | string | Player 2 name. |
statistics | object | Match statistics by period, category and metric (see the statistics rows). |
statistics.{period} | object | Statistics for one period: 1ST, 2ND, โฆ = that set; ALL = whole match. |
statistics.{period}.{category}.{metric}.{player} | object | The metric for player1 and player2 (keys player1 / player2; same shape for every metric). |
statistics.{period}.{category}.{metric}.{player}.value | number | Count for the metric (e.g. aces, points won, serves landed). Present on every metric. |
statistics.{period}.{category}.{metric}.{player}.total | number | What value is out of (e.g. serves attempted, points played). Only on ratio metrics. |
statistics.{period}.{category}.{metric}.{player}.percentage | number | value as a percentage of total. Only on ratio metrics. |
statistics.{period}.games | object | Games category. |
statistics.{period}.games.maxGamesInRow | object | Most consecutive games won. |
statistics.{period}.points | object | Points category. |
statistics.{period}.points.maxPointsInRow | object | Most consecutive points won. |
statistics.{period}.points.servicePointsScored | object | Points won on own serve. |
statistics.{period}.points.receiverPointsScored | object | Points won while returning. |
statistics.{period}.return | object | Return category. |
statistics.{period}.return.returnGamesTotal | object | Return games played. |
statistics.{period}.return.breakPointsScored | object | Break points converted (break points won as returner). |
statistics.{period}.return.firstReturnPoints | object | Points won returning first serve: value = won, total = played. |
statistics.{period}.return.secondReturnPoints | object | Points won returning second serve: value = won, total = played. |
statistics.{period}.service | object | Service category. |
statistics.{period}.service.aces | object | Aces. |
statistics.{period}.service.doubleFaults | object | Double faults. |
statistics.{period}.service.breakPointsSaved | object | Break points saved: value = saved, total = faced. |
statistics.{period}.service.serviceGamesTotal | object | Service games played. |
statistics.{period}.service.firstServeAccuracy | object | First serves landed in: value = in, total = attempted (serve accuracy, not points won). |
statistics.{period}.service.secondServeAccuracy | object | Second serves landed in: value = in, total = attempted. |
statistics.{period}.service.firstServePointsAccuracy | object | Points won behind the first serve: value = won, total = first serves in. |
statistics.{period}.service.secondServePointsAccuracy | object | Points won behind the second serve: value = won, total = second serves played. |
statistics.{period}.miscellaneous | object | Other metrics (tiebreaks). |
statistics.{period}.miscellaneous.tiebreaks | object | Tiebreaks won. |
statistics.{period}.games.gamesWon | object | Games won. |
statistics.{period}.games.serviceGamesWon | object | Service games won (held). |
statistics.{period}.points.pointsTotal | object | Total points won. |
dateOnly | string | Match date (YYYY-MM-DD). |
Latest Single Bookie Odds
This endpoint is best for getting the latest odds because it supports live odds. When a match is in play, it returns odds only for supported markets: Full Time Result, Over Under, Set Winner, and Asian Handicap. This keeps the market coverage aligned with socket odds updates. Use this endpoint to load the initial odds snapshot, then apply socket updates as they arrive.
/tennis/v2/extend/api/event/odds/latest/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
bookmaker_id | No | string | Return only the selected bookmaker. By default bookmaker is Bet365. |
Live market coverage
When the stored event status is exactly InPlay, only market IDs 1, 2, 3, 23 are eligible.
- Full Time Result
- Over Under
- Set Winner
- Asian Handicap
Only markets with matching stored odds are returned; the endpoint does not create empty entries for missing markets. Other event statuses, including null, do not apply this market restriction.
The event-status rule limits markets. It does not filter quotes by odd_type: the latest stored quote may be pre-match or in-play.
How quotes are selected
- Find the event and filter its odds by the selected bookmaker.
- Apply the supported-market restriction when the event status is
InPlay. - Group quotes by market name and normalized line. A null line becomes an empty string.
- Select the greatest
add_timein each group. Null timestamps rank last; equal timestamps are resolved by the highest row ID.
Both odds come from the same selected row. This returns the latest quote, not the highest price. Different lines may have different update timestamps.
Result keys use market when the line is empty, or market | line when a line is present, for example Over Under | 22.5. Object key order is not significant.
Despite the route name end, this endpoint also works for live events. It does not require a finished event or calculate pre-match closing odds.
Empty results
| Condition | meta | result | HTTP status |
|---|---|---|---|
| Event and eligible odds exist | Event details | Quote object | 200 |
| Event exists without eligible odds | Event details | null | 200 |
| Event does not exist | null | null | 200 |
{
"success": true,
"meta": null,
"result": null
}The supplied controller does not define validation-error responses. Invalid-input handling depends on the route schema and application error handler.
Using the snapshot with socket updates
- Load this endpoint for the event and bookmaker you want to display.
- Use
metafor event details andresultfor the initial odds display. - Apply subsequent socket quotes using the same market-and-line key and the same bookmaker scope.
- Compare quote timestamps before replacing a value, so an older snapshot or update does not overwrite a newer quote.
Market coverage is aligned with live socket updates, but field names may differ. This endpoint uses bookmaker and bookmakerId; the earlier socket payload uses od1Bookmaker, od2Bookmaker, and oddType. Normalize those fields in the client rather than treating the payloads as identical.
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament ยท Odds entry.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
meta | object | Value returned by the API for this field. |
meta.eventId | number | Live event ID (the live feed's own ID, not a core fixture ID). |
meta.matchKey | string | player1Id-player2Id-tournamentId-roundId of the match. |
meta.matchId | string | Deprecated: same value as matchKey, use matchKey. Planned removal 3 December 2026. |
meta.player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
meta.player1.name | string | Player 1 name. |
meta.player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
meta.player2.name | string | Player 2 name. |
meta.dateOnly | string | Match date (YYYY-MM-DD). |
meta.tournament | object | Tournament object (id, name, date, level, surface, country, โฆ). |
meta.tournament.name | string | Tournament name. |
meta.eventStatus | string | Value returned by the API for this field. |
result | object | Response payload object documented in the rows below. |
result.{market} | object | Odds for one market (market names are dynamic keys, e.g. "Full Time Result"). |
result.{market}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{market}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{market}.line | string | Handicap/total line, or null. |
result.{market}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.{market}.bookmaker | string | Bookmaker name. |
result.{market}.bookmakerId | number | Bookmaker ID (see GET /tennis/v2/extend/api/bookmakers/all). |
Best Odds Across Multiple Bookmakers
/tennis/v2/extend/api/event/odds/best/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
How it works
- Reads the event status and odds in a single SQL query using the same database snapshot.
- Selects the odds category and freshness limit based on the event status.
- Selects the latest stored quote per bookmaker for market
1, Full Time Result, with an empty betting line. Timestamp ties are resolved using the higher record ID. - Excludes quotes with missing, non-positive, or future timestamps. For active freshness policies, it also excludes stale quotes.
- Considers only valid decimal prices greater than
1. A quote with one valid participant price can still contribute that price. - Selects the highest eligible price independently for
od1andod2. Equal prices favor the newer quote, then the lower bookmaker ID.
Validation happens after selecting each bookmaker's latest quote. If that quote is rejected, the endpoint does not fall back to an older quote from the same bookmaker.
Match status behavior
| Event status | Odds selected | Freshness policy |
|---|---|---|
| InPlay | Latest stored in-play quotes | 120 seconds |
| Not Started | Latest stored pre-match quotes | 30 minutes |
| Ended | Latest stored in-play quotes | No age limit; marked as historical |
| Other statuses | No comparison returned | Availability remains unknown |
Freshness limits are configurable. The response's meta.maxAgeSeconds reports the applied limit.
Historical results compare each bookmaker's latest stored in-play quote. They are not the highest prices ever recorded during the match and are not guaranteed closing prices. Pre-match odds are not used as a fallback for ended matches.
HTTP status codes
200: Request processed successfully. An existing event with no eligible odds returnsresult: nullwith an explanation.400: Invalid event ID rejected by route validation.404: Event not found.
An empty result does not prove that the endpoint or provider lacks coverage. Check meta.reason and meta.excludedQuotes for the available explanation.
These are stored prices from potentially different update times, not a synchronized market snapshot. Recent prices and an available response do not guarantee that a bookmaker currently accepts bets at those prices.
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Odds entry.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
result | object | Response payload object documented in the rows below. |
result.{market} | object | Odds for one market (market names are dynamic keys, e.g. "Full Time Result"). |
result.{market}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{market}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{market}.line | string | Handicap/total line, or null. |
result.{market}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.{market}.oddType | string | Value returned by the API for this field. |
result.{market}.od1AddTime | number | Value returned by the API for this field. |
result.{market}.od2AddTime | number | Value returned by the API for this field. |
result.{market}.od1Bookmaker | string | Bookmaker offering the best od1. |
result.{market}.od2Bookmaker | string | Bookmaker offering the best od2. |
result.{market}.od1BookmakerId | number | Value returned by the API for this field. |
result.{market}.od2BookmakerId | number | Value returned by the API for this field. |
message | string | Status message, e.g. "Success". |
meta | object | Value returned by the API for this field. |
meta.eventStatus | string | Value returned by the API for this field. |
meta.oddType | string | Value returned by the API for this field. |
meta.historical | boolean | Value returned by the API for this field. |
meta.availability | string | Value returned by the API for this field. |
meta.reason | string | Value returned by the API for this field. |
meta.coverage | string | Value returned by the API for this field. |
meta.freshnessApplied | boolean | Value returned by the API for this field. |
meta.freshnessBasis | string | Value returned by the API for this field. |
meta.maxAgeSeconds | number | Value returned by the API for this field. |
meta.checkedAt | string | Value returned by the API for this field. |
meta.updatedAt | string | When the odds were last updated, as Unix seconds; null when unknown. |
meta.eligibleBookmakerCount | number | Value returned by the API for this field. |
meta.excludedQuotes | array | Value returned by the API for this field. |
meta.excludedQuotes[] | object | One item of `meta.excludedQuotes`; its fields are listed below. |
meta.excludedQuotes[].reason | string | Value returned by the API for this field. |
meta.excludedQuotes[].addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
meta.excludedQuotes[].bookmaker | string | Bookmaker name. |
meta.excludedQuotes[].bookmakerId | number | Bookmaker ID (see GET /tennis/v2/extend/api/bookmakers/all). |
Odds Summary
/tennis/v2/extend/api/event/odds/summary/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Odds entry.
| Field | Type | Description |
|---|---|---|
result | object | Bookmaker โ market โ start (opening), kickoff (at match start) and end (latest) objects (od1, od2, addTime), plus line. |
success | boolean | true when the request succeeded. |
count | number | Number of items in this response (or matching items, where stated). |
result.BWin | object | Value returned by the API for this field. |
result.BWin.{market} | array | Value returned by the API for this field. |
result.BWin.{market}[] | object | One item of `result.BWin.{market}`; its fields are listed below. |
result.BWin.{market}[].{bookmaker} | object | Latest odds from this bookmaker (dynamic key). |
result.BWin.{market}[].{bookmaker}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
result.BWin.{market}[].{bookmaker}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
result.BWin.{market}[].{bookmaker}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.BWin.{market}[].line | string | Handicap/total line, or null. |
result.{bookmaker} | object | Odds from this bookmaker, by market (dynamic key). |
result.{bookmaker}.{market} | array | This bookmaker's odds for the market (dynamic key). |
result.{bookmaker}.{market}[] | object | One item of `result.{bookmaker}.{market}`; its fields are listed below. |
result.{bookmaker}.{market}[].{bookmaker} | object | Latest odds from this bookmaker (dynamic key). |
result.{bookmaker}.{market}[].{bookmaker}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
result.{bookmaker}.{market}[].{bookmaker}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
result.{bookmaker}.{market}[].{bookmaker}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.{bookmaker}.{market}[].line | string | Handicap/total line, or null. |
result.FonBet | object | Value returned by the API for this field. |
result.FonBet.{market} | array | Value returned by the API for this field. |
result.FonBet.{market}[] | object | One item of `result.FonBet.{market}`; its fields are listed below. |
result.FonBet.{market}[].{bookmaker} | object | Latest odds from this bookmaker (dynamic key). |
result.FonBet.{market}[].{bookmaker}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
result.FonBet.{market}[].{bookmaker}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
result.FonBet.{market}[].{bookmaker}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.FonBet.{market}[].line | string | Handicap/total line, or null. |
result.BetFair | object | Value returned by the API for this field. |
result.BetFair.{market} | array | Value returned by the API for this field. |
result.BetFair.{market}[] | object | One item of `result.BetFair.{market}`; its fields are listed below. |
result.BetFair.{market}[].{bookmaker} | object | Latest odds from this bookmaker (dynamic key). |
result.BetFair.{market}[].{bookmaker}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
result.BetFair.{market}[].{bookmaker}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
result.BetFair.{market}[].{bookmaker}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.BetFair.{market}[].line | string | Handicap/total line, or null. |
result.BetFair.{market}[].kickoff | null | Odds at the scheduled match start. |
message | string | Status message, e.g. "Success". |
meta | object | Value returned by the API for this field. |
meta.eventId | string | Live event ID (the live feed's own ID, not a core fixture ID). |
meta.eventStatus | string | Value returned by the API for this field. |
meta.startTimestamp | number | Scheduled start as Unix seconds. |
meta.kickoffCutoff | number | Value returned by the API for this field. |
meta.kickoffBasis | string | Value returned by the API for this field. |
meta.checkedAt | string | Value returned by the API for this field. |
Odds History
/tennis/v2/extend/api/event/odds/history/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
market_ids | No | string | Market โ Optional comma-separated market IDs to filter the results. For example: 1,2,3,4. If omitted, odds from all available markets are returned. E.g market_ids=1,2,3,4 You can see available market list |
bookmaker_ids | No | string | Bookmaker โ Optional comma-separated bookmaker IDs to filter the results. For example: 1,2,3,4. If omitted, odds from all available bookmakers are returned. E.g bookmaker_ids=1,2,3,4 |
sincetime | No | number | Non-negative integer Unix timestamp in seconds. Returns only records whose addTime is greater than this value. |
How it works
- Validates the event ID and any supplied query parameters.
- Applies Bet365 and Full Time Result as defaults when their respective filters are omitted.
- Looks up the event and retrieves matching odds in a single SQL query.
- If
sincetimeis supplied, includes only records whereadd_time > sincetime. Records exactly at the cutoff are excluded. - Groups records by the stored bookmaker name and market name.
- Orders each market array by
addTimedescending, with missing timestamps last. Equal timestamps are ordered by record ID descending.
This endpoint returns all matching stored updates, not just the latest quote or the best price. It applies no freshness limit or match-status restriction, so ended matches are included.
Response structure
result is grouped as result[bookmakerName][marketName]. Each market array contains:
od1andod2: Stored prices for the market's two outcomes, returned as strings. Missing or blank prices are represented by"-".oddType:prefor pre-match odds orinplayfor in-play odds.line: Betting line, such as22.5, or an empty string when no line is provided.addTime: Stored quote timestamp in Unix seconds, ornullif missing.
Updates for different betting lines remain in the same market array. Use line to distinguish them.
count is the total number of returned odds records across all bookmakers and markets. Requested bookmakers or markets without matching records are omitted.
Metadata
eventId: Requested event ID.sincetime: Applied cutoff timestamp, ornullwhen no time filter was requested.bookmakerIds: Applied bookmaker IDs, including defaults.marketIds: Applied market IDs, including defaults.order:addTime DESC NULLS LAST, id DESC.
HTTP status codes
200: Request processed successfully. If no records match, returnscount: 0andresult: {}.400: Invalid event ID or query parameters.404: Event not found.
The timestamp filter uses the quote's addTime, not its database arrival time. For repeated polling, allow an overlapping time window and handle repeated records: a strict timestamp cutoff can miss updates that arrive late or share the cutoff second.
Recent Odds
/tennis/v2/extend/api/event/recent-odds/get/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
inplay | No | boolean | Optional. true returns in-play prices only (oddType: inplay); false or omitted returns all prices, in-play and pre-match, as before. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Odds entry.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
result | object | Response payload object documented in the rows below. |
result.{market} | object | Odds for one market (market names are dynamic keys, e.g. "Full Time Result"). |
result.{market}.{bookmaker} | object | Latest odds from this bookmaker (bookmaker names are dynamic keys). |
result.{market}.{bookmaker}.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
result.{market}.{bookmaker}.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
result.{market}.{bookmaker}.line | string | Handicap or total line for the market (string); empty or null when not applicable. |
result.{market}.{bookmaker}.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.{market}.{bookmaker}.oddType | string | Value returned by the API for this field. |
Latest Odds Quotes
/tennis/v2/extend/api/odds/summary/movements/last-10/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
inplay | No | boolean | Optional. true returns in-play prices only (oddType: inplay); false or omitted returns all prices, in-play and pre-match, as before. |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Odds entry.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
result | object | Response payload object documented in the rows below. |
result.{bookmaker} | object | Odds from this bookmaker, by market (dynamic key). |
result.{bookmaker}.{market} | array | This bookmaker's odds for the market (dynamic key). |
result.{bookmaker}.{market}[] | object | One item of `result.{bookmaker}.{market}`; its fields are listed below. |
result.{bookmaker}.{market}[].od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{bookmaker}.{market}[].od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{bookmaker}.{market}[].line | string | Handicap/total line, or null. |
result.{bookmaker}.{market}[].addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.{bookmaker}.{market}[].oddType | string | Value returned by the API for this field. |
Odds Compare
/tennis/v2/extend/api/odds/compare/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
market_id | No | string | Market โ Optional market ID to filter the results. E.g market_id=1. You can see available market list |
How it works
- InPlay: Returns in-play odds updated within the configured live freshness limit.
- Not Started: Returns pre-match odds updated within the configured pre-match freshness limit.
- Ended: Returns an empty result with This match has ended.
- Other statuses: Returns an empty result indicating that current odds availability is unconfirmed.
Response
Each result contains the bookmaker, market, line, participant odds (od1 and od2), odds type, update timestamp (addTime, Unix seconds), and quote age (ageSeconds).
Metadata includes:
eventStatusandoddType: Match status and selected odds category.availability:available,partial,unknown, ornot_applicable.reason: Explanation of the response state.checkedAt: Time freshness was evaluated.updatedAt: Newest accepted quote timestamp, ornull.maxAgeSeconds: Applied freshness limit.excludedQuotes: Quotes excluded because their timestamps were stale or invalid.
count represents returned quote rows. A bookmaker may appear multiple times for different lines. Compare prices only within the same market and line.
HTTP status codes
200: Request processed successfully, including empty results.400: Missing or invalid parameters.404: Event not found.
Recent stored odds do not guarantee that a bookmaker currently accepts bets at those prices. An empty result does not establish that provider coverage is unavailable.
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Odds entry.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
count | number | Number of items in this response (or matching items, where stated). |
results | array | List of result items documented in the rows below. |
results[] | object | One item of `results`; its fields are listed below. |
results[].bookmakerId | number | Bookmaker ID (see GET /tennis/v2/extend/api/bookmakers/all). |
results[].bookmaker | string | Bookmaker name. |
results[].market | string | Market name, e.g. "Full Time Result". |
results[].line | string | Handicap or total line for the market (string); empty or null when not applicable. |
results[].od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
results[].od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
results[].oddType | string | Value returned by the API for this field. |
results[].addTime | string | When the bookmaker published these odds, as Unix seconds (string). |
results[].ageSeconds | number | Value returned by the API for this field. |
message | string | Status message, e.g. "Success". |
meta | object | Value returned by the API for this field. |
meta.eventStatus | string | Value returned by the API for this field. |
meta.oddType | string | Value returned by the API for this field. |
meta.availability | string | Value returned by the API for this field. |
meta.reason | string | Value returned by the API for this field. |
meta.coverage | string | Value returned by the API for this field. |
meta.freshnessBasis | string | Value returned by the API for this field. |
meta.maxAgeSeconds | number | Value returned by the API for this field. |
meta.checkedAt | string | Value returned by the API for this field. |
meta.updatedAt | string | When the odds were last updated, as Unix seconds; null when unknown. |
meta.excludedQuotes | array | Value returned by the API for this field. |
meta.excludedQuotes[] | object | One item of `meta.excludedQuotes`; its fields are listed below. |
meta.excludedQuotes[].bookmakerId | number | Bookmaker ID (see GET /tennis/v2/extend/api/bookmakers/all). |
meta.excludedQuotes[].bookmaker | string | Bookmaker name. |
meta.excludedQuotes[].line | string | Handicap or total line for the market (string); empty or null when not applicable. |
meta.excludedQuotes[].addTime | string | When the bookmaker published these odds, as Unix seconds (string). |
meta.excludedQuotes[].ageSeconds | number | Value returned by the API for this field. |
meta.excludedQuotes[].reason | string | Value returned by the API for this field. |
Pre-Match Odds
/tennis/v2/extend/api/odds/pre-match/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
market_ids | No | string | Market โ Optional comma-separated market IDs to filter the results. For example: 1,2,3,4. If omitted, odds from all available markets are returned. E.g market_ids=1,2,3,4 You can see available market list |
bookmaker_ids | No | string | Bookmaker โ Optional comma-separated bookmaker IDs to filter the results. For example: 1,2,3,4. If omitted, odds from all available bookmakers are returned. E.g bookmaker_ids=1,2,3,4 |
timestamp | No | string | Timestamp โ Optional timestamp to filter the results. For example: 1791000296. If omitted, odds from all available timestamps are returned. E.g timestamp=1791000296 |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament ยท Odds entry.
| Field | Type | Description |
|---|---|---|
id | string | Numeric ID of this item (see the parent object: match, player, tournament, live event, โฆ). |
success | boolean | true when the request succeeded. |
player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
player1.name | string | Player 1 name. |
player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
player2.name | string | Player 2 name. |
roundId | number | Numeric round ID (see GET /tennis/v2/round): e.g. 4 = First, 5 = Second, 9 = 1/4, 10 = 1/2, 12 = Final; 0โ3 are qualifying rounds. |
tournament | object | Tournament object (id, name, date, level, surface, country, โฆ). |
tournament.name | string | Tournament name. |
startTimestamp | number | Scheduled start as Unix seconds. |
result | object | Response payload object documented in the rows below. |
result.{market} | array | Odds for one market (market names are dynamic keys, e.g. "Full Time Result"). |
result.{market}[] | object | One item of `result.{market}`; its fields are listed below. |
result.{market}[].marketId | number | Odds market ID (see GET /tennis/v2/extend/api/markets/all). |
result.{market}[].bookmaker | string | Bookmaker name. |
result.{market}[].od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{market}[].od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. On the best-odds routes this is the best price across bookmakers. |
result.{market}[].oddType | string | Value returned by the API for this field. |
result.{market}[].addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.{market}[].line | string | Handicap/total line, or null. |
Open/Close Pre-Match Odds
/tennis/v2/extend/api/odds/pre-match/open-close/{eventId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Response Properties
Shared objects in this response (defined once in Reusable response schemas): Player ยท Tournament ยท Odds entry.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request succeeded. |
id | string | Numeric ID of this item (see the parent object: match, player, tournament, live event, โฆ). |
player1 | object | Player 1 (first-listed player). On completed archive rows (results, match history, H2H) player1 is the winner; live-service responses (point-by-point, statistics) keep the live feed's order, so map sides by name or ID there. |
player1.name | string | Player 1 name. |
player2 | object | Player 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order. |
player2.name | string | Player 2 name. |
tournament | object | Tournament object (id, name, date, level, surface, country, โฆ). |
tournament.name | string | Tournament name. |
roundId | number | Numeric round ID (see GET /tennis/v2/round): e.g. 4 = First, 5 = Second, 9 = 1/4, 10 = 1/2, 12 = Final; 0โ3 are qualifying rounds. |
startTimestamp | number | Scheduled start as Unix seconds. |
results | array | List of result items documented in the rows below. |
results[] | object | One item of `results`; its fields are listed below. |
results[].marketId | number | Odds market ID (see GET /tennis/v2/extend/api/markets/all). |
results[].market | string | Market name, e.g. "Full Time Result". |
results[].bookmakers | array | Value returned by the API for this field. |
results[].bookmakers[] | object | One item of `results[].bookmakers`; its fields are listed below. |
results[].bookmakers[].bookmakerId | number | Bookmaker ID (see GET /tennis/v2/extend/api/bookmakers/all). |
results[].bookmakers[].bookmaker | string | Bookmaker name. |
results[].bookmakers[].opening | object | Value returned by the API for this field. |
results[].bookmakers[].opening.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
results[].bookmakers[].opening.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
results[].bookmakers[].opening.line | string | Handicap or total line for the market (string); empty or null when not applicable. |
results[].bookmakers[].opening.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
results[].bookmakers[].closing | object | Value returned by the API for this field. |
results[].bookmakers[].closing.od1 | string | Decimal odds for outcome 1 (player 1 / over), as a string. |
results[].bookmakers[].closing.od2 | string | Decimal odds for outcome 2 (player 2 / under), as a string. |
results[].bookmakers[].closing.line | string | Handicap or total line for the market (string); empty or null when not applicable. |
results[].bookmakers[].closing.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
Arbitrage Opportunities
The best price for each outcome is the latest stored quote from each bookmaker, so the two sides can come from different times (quoteAgeSeconds, quoteGapSeconds). Only In Play and Not Started events are evaluated: for an ended or inactive event the result has margin and profitPercentage null and reason: "EVENT_NOT_ACTIVE". Check each bookmaker's current price before acting on it.
/tennis/v2/extend/api/odds/arbitrage/{eventId}?market_id={marketId}Path Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
eventId | Yes | integer | Live event ID from GET /events/live (results[].id). Not a core fixture id. Example: 3815731 |
Query Parameter
| Parameter | Required | Type | Description |
|---|---|---|---|
market_id | No | string | Market โ Optional market ID to filter the results. E.g market_id=1. You can see available market list |
Response Properties
| Field | Type | Description |
|---|---|---|
success | boolean | Indicates whether the request was successful. |
result | object | Contains the calculated arbitrage analysis. |
result.arbitrage | boolean | true when the best prices across bookmakers form an arbitrage, i.e. margin < 1. |
result.margin | number | Sum of implied probabilities of the best prices: 1/outcome1.odds + 1/outcome2.odds. Below 1 = arbitrage; 1 or more = no arbitrage. null when the event is not evaluated (see reason). |
result.profitPercentage | number | Return on total stake for equal payouts, in percent: (1 / margin โ 1) ร 100. Positive only when arbitrage is true; negative when there is no arbitrage (e.g. margin 1.0174 โ โ1.71). null when the event is not evaluated (see reason). Not a guaranteed return: only if both prices are still available. |
result.bestOdds | object | The highest available odds selected for each outcome. |
result.bestOdds.outcome1 | object | Best available odds for the first outcome. |
result.bestOdds.outcome1.bookmakerId | number | Unique identifier of the bookmaker offering the best odds for outcome 1. |
result.bestOdds.outcome1.bookmaker | string | Name of the bookmaker offering the best odds for outcome 1. |
result.bestOdds.outcome1.odds | number | Highest available decimal odds for outcome 1. |
result.bestOdds.outcome2 | object | Best available odds for the second outcome. |
result.bestOdds.outcome2.bookmakerId | number | Unique identifier of the bookmaker offering the best odds for outcome 2. |
result.bestOdds.outcome2.bookmaker | string | Name of the bookmaker offering the best odds for outcome 2. |
result.bestOdds.outcome2.odds | number | Highest available decimal odds for outcome 2. |
result.bookmakersChecked | number | Total number of bookmakers included in the arbitrage calculation. |
result.reason | string | null | Why the event was not evaluated, e.g. EVENT_NOT_ACTIVE for an ended or inactive event (only In Play and Not Started events are evaluated). null when evaluated. |
result.eventStatus / eventState / matchType | string | The event's status (InPlay, Not Started, Ended, โฆ) and whether the prices compared are in-play or pre-match. |
result.snapshotAt / evaluatedAt | number | Unix seconds: when the compared quotes were taken, and when the result was calculated. |
result.quoteAgeSeconds / quoteGapSeconds | number | Age of the older selected quote, and the time between the two selected quotes (they can come from different moments). |
result.line | string | Handicap or total line for the market (string); empty or null when not applicable. |
result.bestOdds.outcome1.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.bestOdds.outcome2.addTime | number | When the bookmaker published these odds, as Unix seconds (string). |
result.marketId | number | Odds market ID (see GET /tennis/v2/extend/api/markets/all). |
result.mode | string | Value returned by the API for this field. |
result.historical | boolean | Value returned by the API for this field. |
result.startTimestamp | number | Scheduled start as Unix seconds. |