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.
- Visit the Tennis API (ATP, WTA, ITF) listing on RapidAPI.
- Click Subscribe and select a pricing plan.
- Copy your
X-RapidAPI-Keyfrom the Security tab or the code snippets panel.
X-RapidAPI-Key in client-side JavaScript or public repositories. Use environment variables or a secrets manager.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:
https://tennis-api-atp-wta-itf.p.rapidapi.comInclude these two headers on every request:
| Header | Value | |
|---|---|---|
X-RapidAPI-Key | YOUR_RAPIDAPI_KEY | Required |
X-RapidAPI-Host | tennis-api-atp-wta-itf.p.rapidapi.com | Required |
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.
| Family | Prefix | Typical resources | How you identify players |
|---|---|---|---|
| Core | /tennis/v2/ | Fixtures, player profile, rankings, tournament seasons โ then append {atp|wta}/ and the module | Numeric 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 token | Live event id, or names + date |
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| Segment | Values | Description |
|---|---|---|
{atp|wta} | atp ยท wta | 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. |
{module} | fixtures ยท player ยท h2h ยท ranking ยท tournament | Core resource module |
{params} | IDs, dates, names | Module-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
| Where | Use | Do not use |
|---|---|---|
Core /player/โฆ and fixtures | Numeric ID, e.g. 68074 | A display name returns 400 |
Name-based /profile/โฆ and most /h2h/โฆ routes | URL-encoded display name Carlos%20Alcaraz, or the same numeric ID | Slug alcaraz-carlos โ HTTP 200 with {"err":"Player not found"} |
/search | Returns names to copy into name-based routes | Search 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.
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.
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
| Family | Query parameters | How to continue |
|---|---|---|
| Core | pageNo, pageSize (1โ500, default 10) | Increment pageNo while hasNextPage is true |
| Name-based | page, limit | Same idea. Both styles work on every route: page = pageNo, limit = pageSize |
Dates
| Where | Format |
|---|---|
Core fixture paths and live event/get | YYYY-MM-DD |
Dated rankings date query | DD.MM.YYYY (and group is required) |
| JSON timestamps in responses | ISO-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.
| Parameter | Type | Description |
|---|---|---|
include | string | Comma-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. |
filter | string | Semicolon-separated Key:value pairs. Example: filter=PlayerGroup:singles;TourCountry:USA,FRA |
PlayerGroup (inside filter) | string | singles, doubles, or both (default includes doubles). |
TourRank / TourCourt / TourCountry | string | Used inside filter with include=tournament. TourRank values are rank_id from GET /ranking (Grand Slam is 4, not 1). |
include.Empty results vs errors
| What you see | Meaning |
|---|---|
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 400 | Bad path/query types (non-integer ID, invalid date, tour_type=itf). |
| HTTP 403 | Wrong/missing X-RapidAPI-Host, or the plan does not include that family. |
| HTTP 404 | Unknown path or unknown resource ID. |
200 with an error or err field. Treat those as failed lookups.Data conventions
| Topic | Rule |
|---|---|
| Completed matches | player1 is the winner; player2 is the loser. |
| Upcoming fixtures | player1 is the first-listed player. There is no winner yet. |
| Timestamps | JSON dates are ISO-8601. Core fixture paths use YYYY-MM-DD. Dated rankings date is DD.MM.YYYY. |
| Country codes | 3-letter codes on player/tournament objects (countryAcr, TourCountry:USA). |
| Pagination | Core: pageNo / pageSize (max 500). Name-based: page / limit. Both styles are accepted everywhere. Continue while hasNextPage is true. |
| Names in URLs | Always URL-encode spaces (Carlos%20Alcaraz). Prefer numeric IDs on core routes. |
| Tournament levels | rankId / TourRank come from GET /ranking. Calendar tier is a display label (ATP 250 and ATP 500 both use rank 2). |
| Includes | Rank, 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:
{
"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 Code | Description |
|---|---|
200 OK | Request reached the API. Confirm the JSON is data, not an error object. |
400 Bad Request | Invalid input parameters (e.g., invalid date format, non-numeric ID, invalid type parameter). |
403 Forbidden | Wrong host header or plan restriction. |
404 Not Found | Resource not found (e.g., invalid player ID, tournament ID, or season ID). |
429 Too Many Requests | Rate limit exceeded. Wait before retrying. |
500 Internal Server Error | Unexpected server error. Retry, then contact support if it persists. |
When an error occurs, the response body contains a JSON object with error details:
{
"error": true,
"statusCode": 400,
"message": "Invalid date format. Expected YYYY-MM-DD."
}Next Steps
Now that you can make requests, explore the individual modules:
- ATP / WTA / ITF coverage and data conventions
- FAQ & Troubleshooting โ 403s, IDs, dates, live IDs, empty lists
- Fixtures โ match schedule, filters, date-range queries
- Players โ core numeric-ID profiles and advanced name-based stats
- Head-to-Head โ rivalry records and per-match stats
- Rankings โ current lists and historical snapshots
- Tournaments โ season IDs, results, draws
- Calendar โ year calendar with level names
- Live Event And Odds โ live board, odds, point-by-point
- Socket.IO โ Mega push updates
- Miscellaneous โ countries, courts, rounds, search