Getting Started

Your First Request

Authenticate, pick the correct path family, then make a first fixtures call. Most integration mistakes are wrong prefixes, player identifiers, pagination names, or date formats โ€” those are covered below so you do not have to guess.

Step 1 โ€” Subscribe on RapidAPI

The Tennis API is distributed exclusively through RapidAPI.

  1. Visit the Tennis API (ATP, WTA, ITF) listing on RapidAPI.
  2. Click Subscribe and select a pricing plan.
  3. Copy your X-RapidAPI-Key from the Security tab or the code snippets panel.
โš ๏ธ
Keep your key secretNever expose your X-RapidAPI-Key in client-side JavaScript or public repositories. Use environment variables or a secrets manager.
โ„น๏ธ
One product covers every family

A subscription to Tennis API - ATP WTA ITF includes core, name-based stats/predictions, and live/odds routes (some live and Socket.IO routes require Ultra or Mega). Keep using host tennis-api-atp-wta-itf.p.rapidapi.com and change only the path after /tennis/v2/.

Step 2 โ€” Base URL & Headers

Every request targets:

Base URL
https://tennis-api-atp-wta-itf.p.rapidapi.com

Include these two headers on every request:

HeaderValue
X-RapidAPI-KeyYOUR_RAPIDAPI_KEYRequired
X-RapidAPI-Hosttennis-api-atp-wta-itf.p.rapidapi.comRequired

Step 3 โ€” URL Structure

There are three path families. They are not interchangeable. Copy the prefix from this table, then append the module path from the reference page.

FamilyPrefixTypical resourcesHow you identify players
Core/tennis/v2/Fixtures, player profile, rankings, tournament seasons โ€” then append {atp|wta}/ and the moduleNumeric ID
Name-based/tennis/v2/ + module (profile, h2h, tournament, calendar, upcomingโ€ฆ)Deep stats, H2H, calendar, draws, predictions.Display name (First%20Last) or numeric ID โ€” never a slug
Live & odds/tennis/v2/extend/api/Live events, odds, point-by-point, WebSocket tokenLive event id, or names + date
Patterns
GET /tennis/v2/{atp|wta}/{module}   core, e.g. /tennis/v2/atp/fixtures
GET /tennis/v2/{module}/โ€ฆ          name-based, e.g. /tennis/v2/profile/Carlos%20Alcaraz
GET /tennis/v2/extend/api/โ€ฆ            live & odds
SegmentValuesDescription
{atp|wta}atp ยท wtaDataset 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.
{module}fixtures ยท player ยท h2h ยท ranking ยท tournamentCore resource module
{params}IDs, dates, namesModule-specific path parameters

ATP, WTA, and ITF

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.

Filter by level with TourRank using ids from GET /ranking. Grand Slam is rank_id 4. Challenger / ITF > $10K is 1.

Player & tournament identifiers

WhereUseDo not use
Core /player/โ€ฆ and fixturesNumeric ID, e.g. 68074A display name returns 400
Name-based /profile/โ€ฆ and most /h2h/โ€ฆ routesURL-encoded display name Carlos%20Alcaraz, or the same numeric IDSlug alcaraz-carlos โ€” HTTP 200 with {"err":"Player not found"}
/searchReturns names to copy into name-based routesSearch does not return numeric IDs โ€” take those from rankings or fixtures

Tournament season IDs (core /tournament/info/{seasonid}) are one year-edition of an event. Name-based tournament routes often use the exact tournament name from the calendar (URL-encoded), not that season ID. Live odds use a separate event id. See FAQ: live IDs.

Step 4 โ€” Make Your First Call

Use a dated fixtures URL so the sample stays the same. Today's list (/atp/fixtures with no date) changes throughout the day.

โ„น๏ธ
How examples are chosen

Request paths are copy-pasteable and URL-encoded. Response bodies are real JSON from settled or dated calls (player profile, a past date, rankings with a snapshot date). Live boards, potential draws, and empty miss cases are labeled when the sample is a snapshot that can change.

Example Request: curl
curl --request GET \
	--url 'https://tennis-api-atp-wta-itf.p.rapidapi.com/tennis/v2/atp/fixtures/2026-09-08?pageNo=1&pageSize=2&filter=PlayerGroup:singles' \
	--header 'X-RapidAPI-Host: tennis-api-atp-wta-itf.p.rapidapi.com' \
	--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY'

Pagination

FamilyQuery parametersHow to continue
CorepageNo, pageSize (1โ€“500, default 10)Increment pageNo while hasNextPage is true
Name-basedpage, limitSame idea. Both styles work on every route: page = pageNo, limit = pageSize

Dates

WhereFormat
Core fixture paths and live event/getYYYY-MM-DD
Dated rankings date queryDD.MM.YYYY (and group is required)
JSON timestamps in responsesISO-8601 strings. For live clocks prefer extend startTimestamp (Unix seconds).

Query Parameters: include and filter

Core fixtures and several player/H2H lists accept optional include and filter query strings. Filters are not top-level keys.

ParameterTypeDescription
includestringComma-separated relations. include=round returns the human-readable tournament round associated with roundId, for example Quarter-Final, Semi-Final or Final. Full lookup: GET /tennis/v2/round. Also tournament, tournament.court.
filterstringSemicolon-separated Key:value pairs. Example: filter=PlayerGroup:singles;TourCountry:USA,FRA
PlayerGroup (inside filter)stringsingles, doubles, or both (default includes doubles).
TourRank / TourCourt / TourCountrystringUsed inside filter with include=tournament. TourRank values are rank_id from GET /ranking (Grand Slam is 4, not 1).
โ„น๏ธ
Filters with includesRank, court, and country fixture filters only take effect when the corresponding relation is requested using include.

Empty results vs errors

What you seeMeaning
HTTP 200, data: []Valid request, no rows for that date/filter/page.
HTTP 200, {"error":"Needs date in query params!"}Dated rankings (and similar) report missing query fields in the body. Add the required params.
HTTP 200, {"err":"Player not found"}Name-based profile name/slug did not match. Use the exact display name.
HTTP 400Bad path/query types (non-integer ID, invalid date, tour_type=itf).
HTTP 403Wrong/missing X-RapidAPI-Host, or the plan does not include that family.
HTTP 404Unknown path or unknown resource ID.
โš ๏ธ
Always read the JSON, not only the statusSeveral advanced routes return HTTP 200 with an error or err field. Treat those as failed lookups.

Data conventions

TopicRule
Completed matchesplayer1 is the winner; player2 is the loser.
Upcoming fixturesplayer1 is the first-listed player. There is no winner yet.
TimestampsJSON dates are ISO-8601. Core fixture paths use YYYY-MM-DD. Dated rankings date is DD.MM.YYYY.
Country codes3-letter codes on player/tournament objects (countryAcr, TourCountry:USA).
PaginationCore: pageNo / pageSize (max 500). Name-based: page / limit. Both styles are accepted everywhere. Continue while hasNextPage is true.
Names in URLsAlways URL-encode spaces (Carlos%20Alcaraz). Prefer numeric IDs on core routes.
Tournament levelsrankId / TourRank come from GET /ranking. Calendar tier is a display label (ATP 250 and ATP 500 both use rank 2).
IncludesRank, court, and country filters only apply when that relation is in include.

Rate Limits

A server-side throttle of 100 requests per minute per IP applies to all endpoints. On breach, the API returns:

HTTP 429
{
    "statusCode": 429,
    "message": "ThrottlerException: Too Many Requests"
}

Your RapidAPI plan may add a daily or monthly quota on top of this throttle.

Error Handling

The API uses standard HTTP status codes to indicate success or failure. Always check the HTTP status code before processing the response body.

Status CodeDescription
200 OKRequest reached the API. Confirm the JSON is data, not an error object.
400 Bad RequestInvalid input parameters (e.g., invalid date format, non-numeric ID, invalid type parameter).
403 ForbiddenWrong host header or plan restriction.
404 Not FoundResource not found (e.g., invalid player ID, tournament ID, or season ID).
429 Too Many RequestsRate limit exceeded. Wait before retrying.
500 Internal Server ErrorUnexpected server error. Retry, then contact support if it persists.

When an error occurs, the response body contains a JSON object with error details:

Error Response
{
   "error": true,
   "statusCode": 400,
   "message": "Invalid date format. Expected YYYY-MM-DD."
}

Next Steps

Now that you can make requests, explore the individual modules: