API Reference

Upcoming Matches

Build tennis schedules and match previews with upcoming fixtures, player and tournament details, pre-match odds and predictions where available. Find men’s and women’s singles and doubles matches, with filters for date, tournament, player, surface and competition level.

Go deeper into every matchup. Use the players’ IDs from an upcoming match to explore Head-to-Head Stats & Analysis: previous meetings, surface records, detailed serve and return statistics, and performance against other opponents. Explore Results & Historical Data for past results and individual match analysis, with statistics, point-by-point data and historical odds where available.

As the match progresses, follow its available links to live scores, detailed statistics, point-by-point data and completed results.

Plan access

Scheduled matches, factual match/H2H data and available pre-match odds are available on all plans. Model win probabilities require ULTRA or MEGA. Written prediction analysis requires MEGA. Request allowances vary by plan. On FREE / PRO, modelPrediction is returned as a plan_restricted object.

Follow this match

Every upcoming row links onward, so you never match records by names, tournament and date: links.live → Live Match by matchId (score, server, timeline, the live eventId and links to full statistics and point-by-point); once played, the same liveMatchId gives completed-match statistics and point-by-point. liveMatchId on upcoming rows equals matchId on live rows.

Bookmaker vs model prediction

predictionSummary is the bookmaker-implied view (legacy key kept for compatibility). SportsAPI365 model win probabilities are exposed separately as modelPrediction when available. Do not mix the two.

All Upcoming Matches

Odds by plan

Available on all plans, including full-market odds, preMatchOdds and predictionSummary (these two are opt-in: add include=preMatchOdds,predictionSummary). Only the SportsAPI365 modelPrediction (win probabilities) requires ULTRA or MEGA; on FREE / PRO it is a plan_restricted object. On ULTRA / MEGA it shows available: false for matches the model has not scored (doubles, and matches without a scheduled start time).

GET/tennis/v2/upcoming/matches
Returns all upcoming scheduled matches across both men's and women's tennis. player1.odd / player2.odd are Marathonbet's match-winner prices (oddBookmaker: Marathonbet); the odds object is Pinnacle's.

Query Parameter

ParameterRequiredTypeDescription
dateNostring
Lower bound, not a single day: returns upcoming matches that start after this date/time (plus matches with no time set yet). Default: now. YYYY-MM-DD or an ISO-8601 date-time; an invalid date returns 400. For one day use dateOnly. Example: date=2026-09-15.
dateOnlyNostring
One UTC day, YYYY-MM-DD: matches scheduled that day (matches with no time set are left out). Not with date, autoPost or dateFrom/dateTo (400). Example: dateOnly=2026-10-27.
dateFromNostring
With dateTo: an inclusive range of UTC days, YYYY-MM-DD (equal days allowed; a reversed range is a 400). Matches with no time set are left out. Example: dateFrom=2026-10-26&dateTo=2026-10-28.
dateToNostring
Last UTC day of the range (inclusive); requires dateFrom.
groupNostring
singles or doubles. Omitted: both.
tournamentIdNostring
Tournament edition id(s), comma-separated (from tournament.id on rows, or /upcoming/filters?include=options). With tournament (name), both must match. Example: tournamentId=21360.
playerIdNostring
One player id: matches where that player is on either side, including a doubles pair that contains the player. On /upcoming/matches (both tours) the id is looked up in both tours, so prefer the per-tour route. Example: playerId=84377.
opponentIdNostring
With playerId only: the match between these two (either order). Example: playerId=84377&opponentId=31446.
surfaceIdNostring
Surface (court) id(s), comma-separated, e.g. 1 Hard, 2 Clay, 3 I.hard; see /upcoming/filters?include=options. Example: surfaceId=1,3.
countryNostring
Tournament country code(s), comma-separated — where the tournament is played, not player nationality. Example: country=SUI,AUT.
rankNostring
Tournament level: an id or a name exactly as /upcoming/filters lists them (case-insensitive), several comma-separated. ATP 250 and 500 are not separate levels: both are 2 (Main tour). An unknown level is a 400 that lists the valid ones. Example: rank=Main tour or rank=2,3.
playerRankNostring
Current ranking of either player. A number N = either player ranked 1 to N; a band min-max = either player ranked in that band. Unranked players never match. Example: playerRank=50 or playerRank=51-100.
sortByNostring
h2h orders by head-to-head interest; startTime orders by scheduled time, earliest first, unscheduled last. Omitted: tournament level, then time (as before). Example: sortBy=startTime.
autoPostNoboolean
Default false. true returns only matches scheduled to start within the next 5 hours (and ignores date). Not with dateOnly/dateFrom.
tournamentNostring
Filter by tournament name. Example: Monte-Carlo Rolex Masters - Monte-Carlo
includeAllNoboolean
Include Challenger/ITF and full history where supported. Example: includeAll=true
includeNostring
Additive only. Comma-separated: preMatchOdds, predictionSummary, all (both of those), plus two opt-in extras that all does not add: fixtureDetails (round and level names, tournament.courtId, tournament.countryDetails, startTime, doubles members) and metadata (odds totalUnit, the bookmaker behind preMatchOdds / predictionSummary, h2hSummary.scope, startTimeSource, and available: false with a reason when a summary has no data). Default already includes matchId and h2hSummary. Example: include=all,fixtureDetails,metadata.
pageNointeger
Page number, starting at 1. pageNo is accepted as an alias on every route. Example: page=1
limitNointeger
Results per page. pageSize is accepted as an alias on every route. Default varies by endpoint. Example: limit=10
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/matches?page=1&limit=2&include=all' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

Shared objects in this response (defined once in Reusable response schemas): Player · Tournament · Plan-restricted field.

FieldTypeDescription
totalintegerTotal matches matching the filter.
matchesarrayPage of upcoming matches.
page / pageNo / pageSize / limit / hasNextPage / totalPagesmixedPagination (advanced family uses page + limit; pageNo/pageSize are also returned).
matches[].id / matchIdintegerMatch ID for this upcoming row. Use with GET /tennis/v2/matches/{matchId} and /prediction, /odds, /stats, /live.
matches[].liveMatchIdstringThis match's key in the live service and Socket.IO: "player1Id-player2Id-tournamentId-roundId". Equals matchId on live rows and event-update.
matches[].links.match / links.livestringReady-to-call paths: the match detail route, and the live route that returns the live score, statistics, timeline and live eventId once the match is in the live feed ({} before).
matches[].tournamentobjectid, name, date, rankId, country, court.
matches[].datestringExpected start, ISO-8601 UTC: the live service's time when it has the match (it gives each match its own time), otherwise the OnCourt schedule's (which often gives every match on a court the session start). The same time is used for sorting, the date filters, and match detail. null when not scheduled. A match that follows another can still move during the day.
matches[].player1 / player2objectid, name, odd, oddBookmaker, countryAcr, seed, image. player1 is first-listed, not predicted winner.
matches[].player1.odd / player2.oddnumber | string | nullThe schedule's match-winner price for that player. It is Marathonbet's price, while the row's odds object is Pinnacle's (odds.bookmaker), so the two prices differ.
matches[].player1.oddBookmaker / player2.oddBookmakerstringBookmaker of odd: always Marathonbet. Present only when odd is set.
matches[].oddsobjectPinnacle's pre-match markets when present (odds.bookmaker): k1, k2 match winner; total with ktb (over) / ktm (under) — Pinnacle's total is in sets (e.g. 2.5), not games. With include=metadata, odds.totalUnit says so. All plans; preMatchOdds repeats the match-winner prices.
matches[].h2hstringCareer H2H as player1Wins-player2Wins string, e.g. 4-1.
matches[].h2hSummaryobjectAdditive factual H2H: matchCount, player1Wins, player2Wins (always present on upcoming lists). Tour-level meetings by default; includeAll=true counts all levels. With include=metadata, scope says which: main_tour or all_levels. 0-0 means they have not met in that scope.
matches[].preMatchOddsobjectAdditive. Only when include=preMatchOdds (or include=all): player1, player2 (match-winner odds) and updatedAt, which is always null because the odds source has no update time (freshness unknown). The prices are Pinnacle's when Pinnacle has them, otherwise the schedule's Marathonbet prices; with include=metadata, bookmaker names which, and a row with no prices gets {available: false, reason: "not_available"}.
matches[].round / startTimeobject / stringinclude=fixtureDetails: round {id, name} (roundId is kept) and startTime, the same UTC instant as date (null when not scheduled).
matches[].tournament.rank / courtId / court.id / countryDetailsobject / integerinclude=fixtureDetails: level {id, name} (rankId is kept), surface id (also court.id beside court.name), and the tournament country {name, acronym} (country keeps the code).
matches[].player1.members / player2.membersarrayinclude=fixtureDetails, doubles only: the two players [{id, name}]; id is null when the name does not identify one player.
matches[].startTimeSource / startTimeUpdatedAtstring / nullinclude=metadata: where date comes from — live (the live service's expected time) or schedule (the OnCourt schedule) — and when that source last changed it (null: not recorded).
matches[].predictionSummaryobjectAdditive when include=predictionSummary|all. Bookmaker-implied view (source=oddsImplied): predictedWinnerId, bookmakerOdds, player1ImpliedProbability, player2ImpliedProbability, normalized.
matches[].modelPredictionobjectAlways present. ULTRA/MEGA: SportsAPI365 model view (available, source, predictedWinnerId, player1WinProbability, player2WinProbability). FREE/PRO: plan_restricted stub with message "Upgrade Plan to see this" (field kept visible; not null). Separate from predictionSummary.
matches[].linksobjectReady-made URLs for this match's detail routes.
matches[].tournament.idnumberTournament season ID.
matches[].tournament.namestringTournament name.
matches[].tournament.datestringTournament start date (ISO-8601 UTC).
matches[].tournament.rankIdnumberTournament level ID (TourRank, see GET /tennis/v2/ranking): 0 ITF $10K, 1 Challenger/ITF > $10K, 2 Main tour, 3 Masters, 4 Grand Slam, 5 Davis/Fed Cup, 7 Tour finals, …
matches[].tournament.countrystringCountry of the tournament: three-letter code, or { name, acronym }.
matches[].tournament.courtobjectCourt surface of the tournament: { id, name } (some routes return only { name }), e.g. { "name": "Hard" }.
matches[].tournament.court.namestringCourt surface name, e.g. Hard, Clay, Grass, I.hard.
matches[].courtstringCourt surface of the match as a name, e.g. "Hard".
matches[].roundIdnumberNumeric 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.
matches[].ranknumberTournament level ID of the match (TourRank).
matches[].typestringDataset: atp or wta.
matches[].odds.id_b_onumberArchive bookmaker ID: 1 = Marathonbet, 2 = Pinnacle. Archive IDs are their own namespace (live-service bookmaker IDs differ).
matches[].odds.bookmakerstringBookmaker name.
matches[].odds.id1_onumberPlayer whose price is k1. The archive may list the pair in the other order than the match row: map prices by id1_o / id2_o, not by position.
matches[].odds.id2_onumberPlayer whose price is k2.
matches[].odds.totalnumberGames-total line that ktb (over) and ktm (under) refer to, or null.
matches[].odds.k1numberMatch-winner odds for player 1 (decimal).
matches[].odds.k2numberMatch-winner odds for player 2 (decimal).
matches[].odds.ktbnumberOver odds for the games-total line in total, or null.
matches[].odds.ktmnumberUnder odds for the games-total line in total, or null.
matches[].player1.namestringPlayer 1 name.
matches[].player1.countryAcrstringPlayer 1 country code.
matches[].player1.seedstringTournament seed as a string, or null when unseeded.
matches[].player1.imagestringPlayer photo path on this API (append to the base URL).
matches[].player1.image_p_namestringPlayer photo path keyed by player name (alternative to image).
matches[].player1.idnumberPlayer 1 ID.
matches[].player2.idnumberPlayer 2 ID.
matches[].player2.namestringPlayer 2 name.
matches[].player2.countryAcrstringPlayer 2 country code.
matches[].player2.seedstringTournament seed as a string, or null when unseeded.
matches[].player2.imagestringPlayer photo path on this API (append to the base URL).
matches[].player2.image_p_namestringPlayer photo path keyed by player name (alternative to image).
matches[].h2hSummary.matchCountnumberCareer meetings between the two players.
matches[].h2hSummary.player1WinsnumberCareer head-to-head wins of player 1.
matches[].h2hSummary.player2WinsnumberCareer head-to-head wins of player 2.
matches[].preMatchOdds.player1numberMatch-winner odds for player 1 (decimal).
matches[].preMatchOdds.player2numberMatch-winner odds for player 2 (decimal).
matches[].predictionSummary.availablebooleantrue when both headline odds exist and a favourite can be derived.
matches[].predictionSummary.sourcestringAlways "oddsImplied": derived from bookmaker odds.
matches[].predictionSummary.predictedWinnerIdnumberPlayer ID of the predicted winner.
matches[].predictionSummary.bookmakerOddsobjectHeadline bookmaker odds used for the implied probabilities: player1, player2.
matches[].predictionSummary.bookmakerOdds.player1numberBookmaker match-winner odds for player 1.
matches[].predictionSummary.bookmakerOdds.player2numberBookmaker match-winner odds for player 2.
matches[].predictionSummary.player1ImpliedProbabilitynumberImplied win probability for player 1 in percent (normalised).
matches[].predictionSummary.player2ImpliedProbabilitynumberImplied win probability for player 2 in percent (normalised).
matches[].predictionSummary.normalizedbooleantrue when the implied probabilities were normalised to sum to 100 (bookmaker margin removed).
matches[].modelPrediction.availablebooleantrue when model probabilities are present; false when not yet available or plan-restricted.
matches[].modelPrediction.sourcestringAlways "sportsapi365" (proprietary model).
matches[].modelPrediction.predictedWinnerIdnumberPlayer ID of the predicted winner.
matches[].modelPrediction.player1WinProbabilitynumberModel win probability for player 1 in percent; null when not available.
matches[].modelPrediction.player2WinProbabilitynumberModel win probability for player 2 in percent; null when not available.

Upcoming Matches by Tour

Odds by plan

Available on all plans, including full-market odds, preMatchOdds and predictionSummary (these two are opt-in: add include=preMatchOdds,predictionSummary). Only the SportsAPI365 modelPrediction (win probabilities) requires ULTRA or MEGA; on FREE / PRO it is a plan_restricted object. On ULTRA / MEGA it shows available: false for matches the model has not scored (doubles, and matches without a scheduled start time).

GET/tennis/v2/upcoming/matches/{atp|wta}
This example uses atp. Use wta for the women's dataset.Returns all upcoming scheduled matches by tour type. player1.odd / player2.odd are Marathonbet’s match-winner prices (oddBookmaker: Marathonbet); the odds object is Pinnacle’s.

Path Parameter

ParameterRequiredTypeDescription
atp|wtaYesstring
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

ParameterRequiredTypeDescription
dateNostring
Lower bound, not a single day: returns upcoming matches that start after this date/time (plus matches with no time set yet). Default: now. YYYY-MM-DD or an ISO-8601 date-time; an invalid date returns 400. For one day use dateOnly. Example: date=2026-09-15.
dateOnlyNostring
One UTC day, YYYY-MM-DD: matches scheduled that day (matches with no time set are left out). Not with date, autoPost or dateFrom/dateTo (400). Example: dateOnly=2026-10-27.
dateFromNostring
With dateTo: an inclusive range of UTC days, YYYY-MM-DD (equal days allowed; a reversed range is a 400). Matches with no time set are left out. Example: dateFrom=2026-10-26&dateTo=2026-10-28.
dateToNostring
Last UTC day of the range (inclusive); requires dateFrom.
groupNostring
singles or doubles. Omitted: both.
tournamentIdNostring
Tournament edition id(s), comma-separated (from tournament.id on rows, or /upcoming/filters?include=options). With tournament (name), both must match. Example: tournamentId=21360.
playerIdNostring
One player id: matches where that player is on either side, including a doubles pair that contains the player. On /upcoming/matches (both tours) the id is looked up in both tours, so prefer the per-tour route. Example: playerId=84377.
opponentIdNostring
With playerId only: the match between these two (either order). Example: playerId=84377&opponentId=31446.
surfaceIdNostring
Surface (court) id(s), comma-separated, e.g. 1 Hard, 2 Clay, 3 I.hard; see /upcoming/filters?include=options. Example: surfaceId=1,3.
countryNostring
Tournament country code(s), comma-separated — where the tournament is played, not player nationality. Example: country=SUI,AUT.
rankNostring
Tournament level: an id or a name exactly as /upcoming/filters lists them (case-insensitive), several comma-separated. ATP 250 and 500 are not separate levels: both are 2 (Main tour). An unknown level is a 400 that lists the valid ones. Example: rank=Main tour or rank=2,3.
playerRankNostring
Current ranking of either player. A number N = either player ranked 1 to N; a band min-max = either player ranked in that band. Unranked players never match. Example: playerRank=50 or playerRank=51-100.
sortByNostring
h2h orders by head-to-head interest; startTime orders by scheduled time, earliest first, unscheduled last. Omitted: tournament level, then time (as before). Example: sortBy=startTime.
autoPostNoboolean
Default false. true returns only matches scheduled to start within the next 5 hours (and ignores date). Not with dateOnly/dateFrom.
tournamentNostring
Filter by tournament name. Example: Monte-Carlo Rolex Masters - Monte-Carlo
includeAllNoboolean
Include Challenger/ITF and full history where supported. Example: includeAll=true
includeNostring
Additive only. Comma-separated: preMatchOdds, predictionSummary, all (both of those), plus two opt-in extras that all does not add: fixtureDetails (round and level names, tournament.courtId, tournament.countryDetails, startTime, doubles members) and metadata (odds totalUnit, the bookmaker behind preMatchOdds / predictionSummary, h2hSummary.scope, startTimeSource, and available: false with a reason when a summary has no data). Default already includes matchId and h2hSummary. Example: include=all,fixtureDetails,metadata.
pageNointeger
Page number, starting at 1. pageNo is accepted as an alias on every route. Example: page=1
limitNointeger
Results per page. pageSize is accepted as an alias on every route. Default varies by endpoint. Example: limit=10
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/matches/atp?include=all' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

Shared objects in this response (defined once in Reusable response schemas): Player · Tournament · Plan-restricted field.

FieldTypeDescription
totalintegerTotal matches matching the filter.
matchesarrayPage of upcoming matches.
page / pageNo / pageSize / limit / hasNextPage / totalPagesmixedPagination (advanced family uses page + limit; pageNo/pageSize are also returned).
matches[].id / matchIdintegerMatch ID for this upcoming row. Use with GET /tennis/v2/matches/{matchId} and /prediction, /odds, /stats, /live.
matches[].liveMatchIdstringThis match's key in the live service and Socket.IO: "player1Id-player2Id-tournamentId-roundId". Equals matchId on live rows and event-update.
matches[].links.match / links.livestringReady-to-call paths: the match detail route, and the live route that returns the live score, statistics, timeline and live eventId once the match is in the live feed ({} before).
matches[].tournamentobjectid, name, date, rankId, country, court.
matches[].datestringExpected start, ISO-8601 UTC: the live service's time when it has the match (it gives each match its own time), otherwise the OnCourt schedule's (which often gives every match on a court the session start). The same time is used for sorting, the date filters, and match detail. null when not scheduled. A match that follows another can still move during the day.
matches[].player1 / player2objectid, name, odd, oddBookmaker, countryAcr, seed, image. player1 is first-listed, not predicted winner.
matches[].player1.odd / player2.oddnumber | string | nullThe schedule's match-winner price for that player. It is Marathonbet's price, while the row's odds object is Pinnacle's (odds.bookmaker), so the two prices differ.
matches[].player1.oddBookmaker / player2.oddBookmakerstringBookmaker of odd: always Marathonbet. Present only when odd is set.
matches[].oddsobjectPinnacle's pre-match markets when present (odds.bookmaker): k1, k2 match winner; total with ktb (over) / ktm (under) — Pinnacle's total is in sets (e.g. 2.5), not games. With include=metadata, odds.totalUnit says so. All plans; preMatchOdds repeats the match-winner prices.
matches[].h2hstringCareer H2H as player1Wins-player2Wins string, e.g. 4-1.
matches[].h2hSummaryobjectAdditive factual H2H: matchCount, player1Wins, player2Wins (always present on upcoming lists). Tour-level meetings by default; includeAll=true counts all levels. With include=metadata, scope says which: main_tour or all_levels. 0-0 means they have not met in that scope.
matches[].preMatchOddsobjectAdditive. Only when include=preMatchOdds (or include=all): player1, player2 (match-winner odds) and updatedAt, which is always null because the odds source has no update time (freshness unknown). The prices are Pinnacle's when Pinnacle has them, otherwise the schedule's Marathonbet prices; with include=metadata, bookmaker names which, and a row with no prices gets {available: false, reason: "not_available"}.
matches[].round / startTimeobject / stringinclude=fixtureDetails: round {id, name} (roundId is kept) and startTime, the same UTC instant as date (null when not scheduled).
matches[].tournament.rank / courtId / court.id / countryDetailsobject / integerinclude=fixtureDetails: level {id, name} (rankId is kept), surface id (also court.id beside court.name), and the tournament country {name, acronym} (country keeps the code).
matches[].player1.members / player2.membersarrayinclude=fixtureDetails, doubles only: the two players [{id, name}]; id is null when the name does not identify one player.
matches[].startTimeSource / startTimeUpdatedAtstring / nullinclude=metadata: where date comes from — live (the live service's expected time) or schedule (the OnCourt schedule) — and when that source last changed it (null: not recorded).
matches[].predictionSummaryobjectAdditive when include=predictionSummary|all. Bookmaker-implied view (source=oddsImplied): predictedWinnerId, bookmakerOdds, player1ImpliedProbability, player2ImpliedProbability, normalized.
matches[].modelPredictionobjectAlways present. ULTRA/MEGA: SportsAPI365 model view (available, source, predictedWinnerId, player1WinProbability, player2WinProbability). FREE/PRO: plan_restricted stub with message "Upgrade Plan to see this" (field kept visible; not null). Separate from predictionSummary.
matches[].linksobjectReady-made URLs for this match's detail routes.
matches[].tournament.idnumberTournament season ID.
matches[].tournament.namestringTournament name.
matches[].tournament.datestringTournament start date (ISO-8601 UTC).
matches[].tournament.rankIdnumberTournament level ID (TourRank, see GET /tennis/v2/ranking): 0 ITF $10K, 1 Challenger/ITF > $10K, 2 Main tour, 3 Masters, 4 Grand Slam, 5 Davis/Fed Cup, 7 Tour finals, …
matches[].tournament.countrystringCountry of the tournament: three-letter code, or { name, acronym }.
matches[].tournament.courtobjectCourt surface of the tournament: { id, name } (some routes return only { name }), e.g. { "name": "Hard" }.
matches[].tournament.court.namestringCourt surface name, e.g. Hard, Clay, Grass, I.hard.
matches[].courtstringCourt surface of the match as a name, e.g. "Hard".
matches[].roundIdnumberNumeric 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.
matches[].ranknumberTournament level ID of the match (TourRank).
matches[].typestringDataset: atp or wta.
matches[].odds.id_b_onumberArchive bookmaker ID: 1 = Marathonbet, 2 = Pinnacle. Archive IDs are their own namespace (live-service bookmaker IDs differ).
matches[].odds.bookmakerstringBookmaker name.
matches[].odds.id1_onumberPlayer whose price is k1. The archive may list the pair in the other order than the match row: map prices by id1_o / id2_o, not by position.
matches[].odds.id2_onumberPlayer whose price is k2.
matches[].odds.totalnumberGames-total line that ktb (over) and ktm (under) refer to, or null.
matches[].odds.k1numberMatch-winner odds for player 1 (decimal).
matches[].odds.k2numberMatch-winner odds for player 2 (decimal).
matches[].odds.ktbnumberOver odds for the games-total line in total, or null.
matches[].odds.ktmnumberUnder odds for the games-total line in total, or null.
matches[].player1.namestringPlayer 1 name.
matches[].player1.countryAcrstringPlayer 1 country code.
matches[].player1.seedstringTournament seed as a string, or null when unseeded.
matches[].player1.imagestringPlayer photo path on this API (append to the base URL).
matches[].player1.image_p_namestringPlayer photo path keyed by player name (alternative to image).
matches[].player1.idnumberPlayer 1 ID.
matches[].player2.idnumberPlayer 2 ID.
matches[].player2.namestringPlayer 2 name.
matches[].player2.countryAcrstringPlayer 2 country code.
matches[].player2.seedstringTournament seed as a string, or null when unseeded.
matches[].player2.imagestringPlayer photo path on this API (append to the base URL).
matches[].player2.image_p_namestringPlayer photo path keyed by player name (alternative to image).
matches[].h2hSummary.matchCountnumberCareer meetings between the two players.
matches[].h2hSummary.player1WinsnumberCareer head-to-head wins of player 1.
matches[].h2hSummary.player2WinsnumberCareer head-to-head wins of player 2.
matches[].preMatchOdds.player1numberMatch-winner odds for player 1 (decimal).
matches[].preMatchOdds.player2numberMatch-winner odds for player 2 (decimal).
matches[].predictionSummary.availablebooleantrue when both headline odds exist and a favourite can be derived.
matches[].predictionSummary.sourcestringAlways "oddsImplied": derived from bookmaker odds.
matches[].predictionSummary.predictedWinnerIdnumberPlayer ID of the predicted winner.
matches[].predictionSummary.bookmakerOddsobjectHeadline bookmaker odds used for the implied probabilities: player1, player2.
matches[].predictionSummary.bookmakerOdds.player1numberBookmaker match-winner odds for player 1.
matches[].predictionSummary.bookmakerOdds.player2numberBookmaker match-winner odds for player 2.
matches[].predictionSummary.player1ImpliedProbabilitynumberImplied win probability for player 1 in percent (normalised).
matches[].predictionSummary.player2ImpliedProbabilitynumberImplied win probability for player 2 in percent (normalised).
matches[].predictionSummary.normalizedbooleantrue when the implied probabilities were normalised to sum to 100 (bookmaker margin removed).
matches[].modelPrediction.availablebooleantrue when model probabilities are present; false when not yet available or plan-restricted.
matches[].modelPrediction.sourcestringAlways "sportsapi365" (proprietary model).
matches[].modelPrediction.predictedWinnerIdnumberPlayer ID of the predicted winner.
matches[].modelPrediction.player1WinProbabilitynumberModel win probability for player 1 in percent; null when not available.
matches[].modelPrediction.player2WinProbabilitynumberModel win probability for player 2 in percent; null when not available.

Match by matchId (detail aliases)

Bridge from discovery → detail

Take matchId from upcoming, fixtures or results rows. The response's links are ready-to-call paths for this match: each one is a documented endpoint below (or, for point-by-point, the live PBP route).

Upcoming → live in one call: every upcoming row has links.live (/tennis/v2/matches/{matchId}/live). It returns the live score, statistics, timeline and the live eventId for the live odds routes and Socket.IO. liveMatchId on the same row equals matchId on live rows, so live data can also be matched without a call.

Live → final result: once the match is completed it moves to results with a new matchId. /tennis/v2/matches/{liveMatchId}?type=atp|wta finds the same match at every stage (schedule, then completed), so keep liveMatchId to follow a fixture to its result.

GET/tennis/v2/matches/{matchId}
Resolves an upcoming (today) or completed match id and returns player and tournament context, its liveMatchId and links to its detail routes. links.prediction is present only for upcoming matches; links.live returns the live state; links.pointByPoint goes to the live service's Point-by-Point By Players route for these players on the match day (present when the match has a date; GET /matches/{matchId}/point-by-point returns the same data under result, or granularity none with a reason when there is none). A bye has isBye: true and bye: true on its empty side. A slot still waiting for its players (the feed's 'Unknown Player' placeholder, with no bye result) has awaitingParticipants: true and tbd: true on that player. Neither returns links or a liveMatchId. An upcoming matchId stays the same while the match is on the schedule (it changes only if a slot's players change, e.g. a qualifier is filled in). The completed match in results has its own matchId: to follow a match from the schedule to its final result, pass its liveMatchId as the matchId (player1Id-player2Id-tournamentId-roundId, players in either order). Completed matchIds are not permanent: they are renumbered when the results archive is reloaded (a recent result's id usually changes within about a day, and an old id can later belong to a different match), so store the liveMatchId, not the completed matchId. Unknown query parameters return 400. Pass type and source (as given in links from other rows) so the right match is selected.

Path Parameter

ParameterRequiredTypeDescription
matchIdYesstring
From upcoming matchId / fixtures matchId / results matchId, or a liveMatchId (player1Id-player2Id-tournamentId-roundId), which stays the same from the schedule to the completed match.

Query Parameter

ParameterRequiredTypeDescription
typeNostring
atp or wta. Optional; speeds up the lookup and avoids ambiguity: the same number can be a men's and a women's match.
sourceNostring
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.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/matches/24008-87562-21349-12?type=atp&source=game' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

Shared objects in this response (defined once in Reusable response schemas): Player.

FieldTypeDescription
matchIdintegerResolved match ID from the upcoming schedule or completed results.
sourcestringtoday = still on the upcoming schedule; game = completed archive.
typestringatp or wta.
date / startTimeSourcestringUpcoming match: expected start, the same time as on the upcoming list (live = the live service's time, schedule = the OnCourt schedule's). Completed match: the recorded date, without startTimeSource.
player1 / player2objectid and name.
liveMatchIdstringThis match's key in the live service and Socket.IO: "player1Id-player2Id-tournamentId-roundId" (matchId on live rows and event-update). Absent for a bye.
linksobjectReady-to-call paths: prediction (upcoming matches only, MEGA), odds, stats, live, detailedStats (Detailed Live Match Statistics, the full statistics by set) and pointByPoint (Point-by-Point By Players, the recommended point-by-point route) — the last two by player names and match day, absent without a date. Completed matches are linked by their composite key (player1Id-player2Id-tournamentId-roundId), which survives archive reloads. Empty ({}) for a bye, which has no opponent.
resultstringScore string, e.g. "6-3 6-4"; empty string until the match is played.
roundIdnumberNumeric 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.
tournamentIdnumberNumeric tournament season ID (one edition of an event).
player1.idnumberPlayer 1 ID.
player1.namestringPlayer 1 name.
player2.idnumberPlayer 2 ID.
player2.namestringPlayer 2 name.
links.oddsstringURL of the archived pre-match odds for this match (both bookmakers); present when oddsAvailable is true.
links.statsstringURL of the completed-match statistics route (all plans).
links.livestringURL of the match's live route: live score, statistics, timeline and the live eventId ({} until the match is in the live feed).
links.pointByPointstringURL of the live Point-by-Point By Players route for these players on the match day; absent when the match has no date.

Match Prediction by matchId

MEGA plan only

MEGA required. FREE, PRO and ULTRA receive HTTP 403 with error: "plan_restricted".

Time-bound example

Only for upcoming matches: a completed matchId returns 400. The example (matchId 550970, Medvedev v Atmane, Almaty quarterfinal on 2026-10-23) stops working once that match is played. For a current matchId, call Upcoming Matches and take matchId. Same response as Match Prediction & Analysis Paragraph.

GET/tennis/v2/matches/{matchId}/prediction
The Match Prediction & Analysis Paragraph for this match, found by matchId instead of player names.

Path Parameter

ParameterRequiredTypeDescription
matchIdYesstring
From matchId on upcoming, fixtures or results rows, or a liveMatchId (player1Id-player2Id-tournamentId-roundId), which stays the same from the schedule to the completed match.

Query Parameter

ParameterRequiredTypeDescription
typeNostring
atp or wta. Optional; speeds up the lookup and avoids ambiguity.
sourceNostring
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.
includeAllNoboolean
Optional. true counts lower-level meetings (Challengers, ITF, qualifying) in the H2H and history the paragraph describes; the default uses main-tour matches only. Example: includeAll=true.
onlyImpNoboolean
Optional. true returns only the high-signal prediction bullets. Example: onlyImp=true.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/matches/550970/prediction?type=atp&source=today' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
paragraphstringMatch Prediction & Analysis Paragraph as an HTML list (<ul><li>…</li></ul>). Render as HTML or strip the tags.

Match Odds by matchId

Map prices by player ID, not by position

k1 is the price of the player in id1_o, k2 of the player in id2_o. That order can differ from the match row: completed matches list the winner as player1. Example, match 64511042: the match row has player1 Thiago Seyboth Wild (36858), player2 Francisco Comesana (61971); the Marathonbet row has id1_o 61971 with k1 2.08 and id2_o 36858 with k21.65, so Seyboth Wild's price is 1.65 and Comesana's 2.08.

prices = { [Number(o.id1_o)]: o.k1, [Number(o.id2_o)]: o.k2 }
player1Price = prices[match.player1.id]

Handicap (f1/kf1, f2/kf2) and correct-score fields follow the same id1_o/id2_o sides.

GET/tennis/v2/matches/{matchId}/odds
Full pre-match odds rows (all markets) for this match, upcoming or completed. Same fields as Pre-Match Odds (All Markets). k1 is the price of the player in id1_o and k2 of the player in id2_o, which can be the reverse of the match row's player order (completed matches list the winner first): map prices by player ID, not by position. Each row names its bookmaker; totalUnit and handicapUnit give the unit of total and f1/f2: games for Marathonbet, sets for Pinnacle.
Pre-match odds from more bookmakers

This endpoint provides stored pre-match odds from Pinnacle and Marathonbet. For pre-match prices from up to 10 bookmakers, use Pre-Match Odds in the Live Scores, Stats & Odds section: GET /tennis/v2/extend/api/odds/pre-match/{eventId}

Although listed in the Live section, this endpoint provides pre-match prices before play begins. It uses the live service’s eventId, not the upcoming matchId. Bookmaker and market availability varies by match.

Path Parameter

ParameterRequiredTypeDescription
matchIdYesstring
From matchId on upcoming, fixtures or results rows, or a liveMatchId (player1Id-player2Id-tournamentId-roundId), which stays the same from the schedule to the completed match.

Query Parameter

ParameterRequiredTypeDescription
typeNostring
atp or wta. Optional; speeds up the lookup and avoids ambiguity.
sourceNostring
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.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/matches/47275-68074-20348-12/odds?type=atp&source=game' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
odds[].id_b_ostringBookmaker ID as a numeric string: "1" = Marathonbet, "2" = Pinnacle.
odds[].id1_o / id2_ostringPlayer 1 / player 2 IDs for this odds row (numeric strings).
odds[].id_t_ostringTournament season ID (numeric string).
odds[].id_r_ointegerRound ID.
odds[].k1 / k2numberMatch-winner (moneyline) odds: k1 is the price of the player in id1_o, k2 of the player in id2_o. This order can differ from the match row (completed matches list the winner as player1), so map prices by ID, never by position: { [id1_o]: k1, [id2_o]: k2 }. Compare IDs as numbers (id1_o/id2_o are numeric strings). Handicap (f1/kf1, f2/kf2) and correct-score fields follow the same id1_o/id2_o sides.
odds[].bookmakerstringBookmaker name for id_b_o: Marathonbet or Pinnacle.
odds[].totalnumber | nullTotal line that ktb/ktm refer to, in totalUnit: games on Marathonbet (e.g. 22.5), sets on Pinnacle (2.5). null when the market is not offered.
odds[].totalUnitstringUnit of total: games (Marathonbet) or sets (Pinnacle). Present only when total is set. Compare totals only when the units match.
odds[].ktb / ktmnumber | nullOver (ktb) and under (ktm) odds for that total line; null when not offered.
odds[].f1 / f2number | nullHandicap for player 1 / player 2, in handicapUnit: games on Marathonbet (e.g. -6), sets on Pinnacle (-1.5). null when not offered.
odds[].handicapUnitstringUnit of f1/f2: games (Marathonbet) or sets (Pinnacle). Present only when f1 is set.
odds[].kf1 / kf2number | nullOdds for the corresponding handicap; null when not offered.
odds[].k20 / k21 / k12 / k02number | nullCorrect set score 2–0, 2–1, 1–2, 0–2 odds (best of three). null in a best-of-five match, where these scores cannot happen, and for bookmakers that do not offer correct-score markets (Pinnacle).
odds[].k30 / k31 / k32 / k23 / k13 / k03number | nullCorrect set score 3–0 … 0–3 odds (best of five). null in a best-of-three match, where these scores cannot happen, and for bookmakers that do not offer correct-score markets (Pinnacle).
oddsarrayOdds object documented in the rows below.
odds[]objectOne item of `odds`; its fields are listed below.

Pre-Match Odds (All Markets)

Odds field names are legacy abbreviations

Keys such as k1, ktb, and f1 are not renamed (existing clients depend on them). Meanings are listed in the response properties below. total is the over/under line — in games for Marathonbet and in sets for Pinnacle (totalUnit says which); ktb = over, ktm = under.

GET/tennis/v2/upcoming/matchodds/{atp|wta}
This example uses atp. Use wta for the women's dataset.Returns bookmaker odds for one upcoming matchup (moneyline, game totals, handicaps, set scores when offered). Each row names its bookmaker; totalUnit and handicapUnit give the unit of total and f1/f2: games for Marathonbet, sets for Pinnacle.
Pre-match odds from more bookmakers

This endpoint provides stored pre-match odds from Pinnacle and Marathonbet. For pre-match prices from up to 10 bookmakers, use Pre-Match Odds in the Live Scores, Stats & Odds section: GET /tennis/v2/extend/api/odds/pre-match/{eventId}

Although listed in the Live section, this endpoint provides pre-match prices before play begins. It uses the live service’s eventId, not the upcoming matchId. Bookmaker and market availability varies by match.

Path Parameter

ParameterRequiredTypeDescription
atp|wtaYesstring
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

ParameterRequiredTypeDescription
player1IdYesstring
First player: numeric ID or display name. Example player1Id=40434 or player1Id=Jannik Sinner
player2IdNostring
Second player: numeric ID or display name. Example player2Id=68074 or player2Id=Carlos Alcaraz
tournamentIdYesinteger
Filter by tournament id. Example: tournamentId=21331
roundIdYesinteger
Filter by round ID. Example: roundId=9
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/matchodds/atp?tournamentId=21352&roundId=12&player1Id=22807&player2Id=29372' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
oddsarrayOne object per bookmaker row (typically Marathonbet then Pinnacle).
odds[].id_b_ostringBookmaker ID as a numeric string: "1" = Marathonbet, "2" = Pinnacle.
odds[].id1_o / id2_ostringPlayer 1 / player 2 IDs for this odds row (numeric strings).
odds[].id_t_ostringTournament season ID (numeric string).
odds[].id_r_ointegerRound ID.
odds[].k1 / k2numberMatch-winner (moneyline) odds: k1 is the price of the player in id1_o, k2 of the player in id2_o. This order can differ from the match row (completed matches list the winner as player1), so map prices by ID, never by position: { [id1_o]: k1, [id2_o]: k2 }. Compare IDs as numbers (id1_o/id2_o are numeric strings). Handicap (f1/kf1, f2/kf2) and correct-score fields follow the same id1_o/id2_o sides.
odds[].bookmakerstringBookmaker name for id_b_o: Marathonbet or Pinnacle.
odds[].totalnumber | nullTotal line that ktb/ktm refer to, in totalUnit: games on Marathonbet (e.g. 22.5), sets on Pinnacle (2.5). null when the market is not offered.
odds[].totalUnitstringUnit of total: games (Marathonbet) or sets (Pinnacle). Present only when total is set. Compare totals only when the units match.
odds[].ktb / ktmnumber | nullOver (ktb) and under (ktm) odds for that total line; null when not offered.
odds[].f1 / f2number | nullHandicap for player 1 / player 2, in handicapUnit: games on Marathonbet (e.g. -6), sets on Pinnacle (-1.5). null when not offered.
odds[].handicapUnitstringUnit of f1/f2: games (Marathonbet) or sets (Pinnacle). Present only when f1 is set.
odds[].kf1 / kf2number | nullOdds for the corresponding handicap; null when not offered.
odds[].k20 / k21 / k12 / k02number | nullCorrect set score 2–0, 2–1, 1–2, 0–2 odds (best of three). null in a best-of-five match, where these scores cannot happen, and for bookmakers that do not offer correct-score markets (Pinnacle).
odds[].k30 / k31 / k32 / k23 / k13 / k03number | nullCorrect set score 3–0 … 0–3 odds (best of five). null in a best-of-three match, where these scores cannot happen, and for bookmakers that do not offer correct-score markets (Pinnacle).

Top Matches Today

Odds by plan

Available on all plans, including full-market odds, preMatchOdds and predictionSummary (these two are opt-in: add include=preMatchOdds,predictionSummary). Only the SportsAPI365 modelPrediction (win probabilities) requires ULTRA or MEGA; on FREE / PRO it is a plan_restricted object. On ULTRA / MEGA it shows available: false for matches the model has not scored (doubles, and matches without a scheduled start time).

GET/tennis/v2/upcoming/top-tennis-matches-today/{atp|wta}
This example uses atp. Use wta for the women's dataset.Returns today’s most significant singles matches (those with a prior H2H). modelPrediction (win probabilities) is ULTRA / MEGA; every other field is on all plans

Path Parameter

ParameterRequiredTypeDescription
atp|wtaYesstring
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.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/top-tennis-matches-today/atp' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

Shared objects in this response (defined once in Reusable response schemas): Player · Tournament · Plan-restricted field.

FieldTypeDescription
[]objectOne item of the response; its fields are listed below.
[].idnumberNumeric ID of this item (see the parent object: match, player, tournament, live event, …).
[].matchIdnumberMatch ID (same value as id on core match rows).
[].liveMatchIdstringKey of this match in the live service and Socket.IO: "player1Id-player2Id-tournamentId-roundId". Equals matchKey (and the deprecated matchId) on live rows and event-update.
[].linksobjectReady-made URLs for this match's detail routes.
[].links.matchstringURL of the match detail route (/tennis/v2/matches/{matchId}); source=game marks a completed match.
[].links.livestringURL of the match's live route: live score, statistics, timeline and the live eventId ({} until the match is in the live feed).
[].tournamentobjectTournament object (id, name, date, level, surface, country, …).
[].tournament.idnumberTournament season ID.
[].tournament.namestringTournament name.
[].tournament.datestringTournament start date (ISO-8601 UTC).
[].tournament.rankIdnumberTournament level ID (TourRank, see GET /tennis/v2/ranking): 0 ITF $10K, 1 Challenger/ITF > $10K, 2 Main tour, 3 Masters, 4 Grand Slam, 5 Davis/Fed Cup, 7 Tour finals, …
[].tournament.countrystringCountry of the tournament: three-letter code, or { name, acronym }.
[].tournament.courtobjectCourt surface of the tournament: { id, name } (some routes return only { name }), e.g. { "name": "Hard" }.
[].tournament.court.namestringCourt surface name, e.g. Hard, Clay, Grass, I.hard.
[].courtstringCourt surface name, e.g. "Hard".
[].roundIdnumberNumeric 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.
[].ranknumberTournament level ID (TourRank).
[].datestringDate/time as ISO-8601 UTC. On match rows this is the scheduled or played start; on tournaments, the start date.
[].typestringDataset: atp (men) or wta (women).
[].oddsobjectOdds object documented in the rows below.
[].odds.id_b_onumberArchive bookmaker ID: 1 = Marathonbet, 2 = Pinnacle. Archive IDs are their own namespace (live-service bookmaker IDs differ).
[].odds.totalnumberGames-total line that ktb (over) and ktm (under) refer to, or null.
[].odds.k1numberMatch-winner odds for player 1 (decimal).
[].odds.k2numberMatch-winner odds for player 2 (decimal).
[].odds.ktbnumberOver odds for the games-total line in total, or null.
[].odds.ktmnumberUnder odds for the games-total line in total, or null.
[].player1objectPlayer 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.namestringPlayer 1 name.
[].player1.oddstringPre-match match-winner odds for this player (decimal), as a string; null when not available.
[].player1.countryAcrstringPlayer 1 country code.
[].player1.seedstringTournament seed as a string, or null when unseeded.
[].player1.imagestringPlayer photo path on this API (append to the base URL).
[].player1.image_p_namestringPlayer photo path keyed by player name (alternative to image).
[].player1.idnumberPlayer 1 ID.
[].player2objectPlayer 2 (second-listed player). On completed archive rows player2 is the loser; live-service responses keep the live feed's order.
[].player2.idnumberPlayer 2 ID.
[].player2.namestringPlayer 2 name.
[].player2.oddstringPre-match match-winner odds for this player (decimal), as a string; null when not available.
[].player2.countryAcrstringPlayer 2 country code.
[].player2.imagestringPlayer photo path on this API (append to the base URL).
[].player2.image_p_namestringPlayer photo path keyed by player name (alternative to image).
[].h2hstringCareer head-to-head as "player1Wins-player2Wins", e.g. "4-1".
[].h2hSummaryobjectFactual career head-to-head: matchCount, player1Wins, player2Wins.
[].h2hSummary.matchCountnumberCareer meetings between the two players.
[].h2hSummary.player1WinsnumberCareer head-to-head wins of player 1.
[].h2hSummary.player2WinsnumberCareer head-to-head wins of player 2.
[].modelPredictionobjectSportsAPI365 model win probabilities (ULTRA / MEGA). On FREE / PRO this field is a plan_restricted object (available: false, error, message, requiredPlan: "ULTRA", upgradeUrl).
[].modelPrediction.availablebooleantrue when model probabilities are present; false when not yet available or plan-restricted.
[].modelPrediction.sourcestringAlways "sportsapi365" (proprietary model).
[].modelPrediction.predictedWinnerIdnumberPlayer ID of the predicted winner.
[].modelPrediction.player1WinProbabilitynumberModel win probability for player 1 in percent; null when not available.
[].modelPrediction.player2WinProbabilitynumberModel win probability for player 2 in percent; null when not available.

Match Prediction & Analysis Paragraph

Time-bound example

Returns data only while the two players have a match on the schedule (today or upcoming); afterwards the response is {}. The example (Medvedev v Atmane, Almaty quarterfinal on 2026-10-23) stops working once that match is played. For a current pair, take two players from Upcoming Matches.

MEGA plan only

The Match Prediction & Analysis Paragraph endpoint is available exclusively to MEGA plan subscribers and is not included with PRO or ULTRA plans. Restricted calls return HTTP 403 with error: plan_restricted.

GET/tennis/v2/upcoming/match-prediction/{atp|wta}/{player1}/{player2}
This example uses atp. Use wta for the women's dataset.Returns the Match Prediction & Analysis Paragraph for this matchup: the H2H Stats Prediction Insights narrative as an HTML list (<ul><li>…</li></ul>, one insight per item) — render it as HTML or strip the tags for plain text. MEGA only. Optional onlyImp=true keeps the high-signal insights.

Path Parameter

ParameterRequiredTypeDescription
atp|wtaYesstring
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.
player1Yesstring
First player display name. E.g: Jannik Sinner
player2Yesstring
Second player display name. E.g: Carlos Alcaraz

Query Parameter

ParameterRequiredTypeDescription
includeAllNoboolean
Include Challenger/ITF and full history where supported. Example: includeAll=true
onlyImpNoboolean
When true, returns only the high-signal prediction bullets. Example: onlyImp=true.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/match-prediction/atp/Daniil%20Medvedev/Terence%20Atmane' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
paragraphstring (HTML)H2H Stats Prediction Insights narrative as an HTML list: <ul> with one <li> per insight (H2H record, career-best year, recent form, surface, pressure points, opponent quality). Render as HTML, or strip the tags for plain text.

H2H Prediction Analysis by Player Names

MEGA plan only

This written matchup analysis is part of the Match Prediction & Analysis Paragraph, available exclusively to MEGA plan subscribers. It is not included with FREE, PRO or ULTRA plans. FREE, PRO and ULTRA receive HTTP 403 with error: "plan_restricted".

Time-bound example

Analysis exists only for matches on the schedule (today or upcoming); for other pairs result is null. The example pair and date_only go out of date once that match is played. For a current pair and date, take two players and the date of a row from Upcoming Matches.

GET/tennis/v2/aggregate/head-to-head/prediction/raw
Returns the written prediction analysis for an upcoming match between two players: second serve and return patterns, performance under pressure, surface strength, deciding sets and event insights, as plain text in titled sections separated by blank lines. Pass both player names; the order does not matter. date_only (YYYY-MM-DD) is optional and selects the match date. When no analysis exists for the matchup, result is null.

Query Parameter

ParameterRequiredTypeDescription
player1Yesstring
First player display name. E.g: Jannik Sinner
player2Yesstring
Second player display name. E.g: Carlos Alcaraz
date_onlyNostring
Target date in YYYY-MM-DD format. Example: 2026-01-01.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/aggregate/head-to-head/prediction/raw?player1=Carlos%20Alcaraz&player2=Alex%20Michelsen&date_only=2026-09-30' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
successbooleanfalse when a required parameter is missing (player1 and player2 are both required).
resultobject | nullPrediction analysis for the matchup, or null when none is available for these players / date.
result.player1stringFirst player as stored for the match (may be either of the names you sent).
result.player2stringSecond player as stored for the match.
result.datestring (ISO-8601 UTC)Scheduled start of the match the analysis is for.
result.predictionstringPlain-text analysis in titled sections (e.g. Second Serve & Return Patterns, Under Pressure & Performance Record, Surface Strength & Player Level, Match Opportunities & Deciding Sets, Event Insights), separated by blank lines.
result.lastUpdatedAtstring (Unix seconds)When the analysis was last generated.

H2H Model Prediction (Win Probabilities) by Player Names

ULTRA+

SportsAPI365 model win probabilities require the ULTRA or MEGA plan. FREE / PRO receive HTTP 403 (plan_restricted).

Time-bound example

Returns a prediction only while the two players have a match on the schedule (today or upcoming); afterwards result is null. The example pair and date_only go out of date once that match is played. For a current pair and date, take two players and the date of a row from Upcoming Matches.

GET/tennis/v2/aggregate/head-to-head/model/prediction
Returns the SportsAPI365 model prediction for an upcoming match between two players: the predicted winner (name and player ID) and each player's win probability in percent. Pass both players by full display name (e.g. player1=Alexander Zverev), not numeric IDs: IDs are not matched and return result null. date_only (YYYY-MM-DD) is optional and selects the match date. player1 / player2 in the response follow the scheduled match order, which may differ from the order you sent, so read the probabilities by name or by predictedWinnerId. When no prediction exists for the matchup, result.prediction (or result) is null.

Query Parameter

ParameterRequiredTypeDescription
player1Yesstring
First player display name. E.g: Jannik Sinner
player2Yesstring
Second player display name. E.g: Carlos Alcaraz
date_onlyNostring
Target date in YYYY-MM-DD format. Example: 2026-01-01.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/aggregate/head-to-head/model/prediction?player1=Mitchell%20Krueger&player2=Stefan%20Kozlov&date_only=2026-10-01' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
successbooleanfalse when a required parameter is missing (player1 and player2 are both required).
resultobject | nullnull when the matchup is not found.
result.predictionobject | nullModel prediction for the matchup, or null when none is available yet for these players / date.
result.prediction.sourcestringAlways sportsapi365 (proprietary model, not bookmaker-implied).
result.prediction.player1 / player2stringPlayers in scheduled match order (may differ from the order you sent).
result.prediction.availablebooleantrue when probabilities are present.
result.prediction.predictedWinnerstringName of the player the model favours.
result.prediction.predictedWinnerIdintegerPlayer ID of the favoured player (same IDs as the rest of the API).
result.prediction.player1WinProbability / player2WinProbabilitynumberWin probability in percent for result.prediction.player1 / player2; the two add up to 100.

Upcoming Filters by Tour

GET/tennis/v2/upcoming/filters/{atp|wta}
This example uses atp. Use wta for the women's dataset.Returns the tournament levels for one tour on the upcoming schedule: an array of {rankId, name}. Use rankId (or name) as rank on the upcoming lists. Add include=options for every value the list filters accept: levels, tournaments (tournamentId, with type, rankId, surfaceId, country), surfaces (surfaceId) and tournament countries (country), each with its id or code.

Path Parameter

ParameterRequiredTypeDescription
atp|wtaYesstring
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

ParameterRequiredTypeDescription
includeNostring
Optional. options returns an object instead of the level array: levels, tournaments, surfaces and countries, the values the upcoming list filters accept. Omitted: the level array, as before. Example: include=options.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/filters/atp' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
[]objectOne item of the response; its fields are listed below.
[].rankIdnumberTournament level ID (TourRank, see GET /tennis/v2/ranking): 0 ITF $10K, 1 Challenger/ITF > $10K, 2 Main tour, 3 Masters, 4 Grand Slam, 5 Davis/Fed Cup, 7 Tour finals, …
[].namestringDisplay name.

All Upcoming Filters

GET/tennis/v2/upcoming/filters
Returns the tournament levels for both tours on the upcoming schedule: an array of {rankId, name}. Use rankId (or name) as rank on the upcoming lists. Add include=options for every value the list filters accept: levels, tournaments (tournamentId, with type, rankId, surfaceId, country), surfaces (surfaceId) and tournament countries (country), each with its id or code.

Query Parameter

ParameterRequiredTypeDescription
includeNostring
Optional. options returns an object instead of the level array: levels, tournaments, surfaces and countries, the values the upcoming list filters accept. Omitted: the level array, as before. Example: include=options.
Example Request: CURL
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/upcoming/filters' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Response Properties

FieldTypeDescription
[]objectOne item of the response; its fields are listed below.
[].rankIdnumberTournament level ID (TourRank, see GET /tennis/v2/ranking): 0 ITF $10K, 1 Challenger/ITF > $10K, 2 Main tour, 3 Masters, 4 Grand Slam, 5 Davis/Fed Cup, 7 Tour finals, …
[].namestringDisplay name.