Tennis API documentation
48 REST endpoints and a live WebSocket, documented from the API's own specification with real responses.
Matches
Live scoreboards, completed results, upcoming fixtures, the full match archive and per-match stats. (12 endpoints)
Players
Profiles, search, career statistics, match logs and recent form. (7 endpoints)
Rankings
Weekly ATP and WTA singles rankings, point-in-time history and movers. (7 endpoints)
Tournaments
The tournament catalogue, season calendar, editions, draws and schedules. (9 endpoints)
Head-to-head
Rivalry records with surface, Grand Slam and finals splits, and multi-player matrices. (3 endpoints)
Leaderboards
Season leaderboards built from match statistics. (9 endpoints)
Coverage
What the dataset covers, by tour, level and year. (1 endpoint)
Live WebSockets
Stream live tennis point-by-point updates over a WebSocket: connection URL, authentication, subscribe to all matches or one match, POINT_UPDATE and MATCH_FINISHED events.
IDs
How player, match and tournament ids are formed in the Tennis API, and how live, upcoming and archived matches keep one stable id.
Coverage & updates
What the Tennis API covers (ATP, WTA, Challenger, ITF, juniors, history back to 1968) and how often each part of the data updates.
The Tennis API is a REST API over HTTPS that returns JSON. Live scores also stream over a WebSocket. Every endpoint below is documented from the API's own OpenAPI document, and every example response is real output captured from the production API.
Base URL
https://api.citoapi.com/api/v1/tennisAuthentication
Send your API key in the x-api-key header (Authorization: Bearer <key> also works). Get a free key at citoapi.com/dashboard/keys. Keys are secret: call the API from your server, not from a browser.
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.citoapi.com/api/v1/tennis/matches/live"Response format
Every response carries success: true or false. List endpoints return items with total, page, page_size and total_pages; single resources return their fields at the top level next to success.
{
"success": true,
"items": [ { "id": "s365_2026_4764920", "tournament_name": "Wimbledon", "round": "F", "score": "6-7 7-6 6-3 6-4", "winner_id": "atp_206173" } ],
"total": 31,
"page": 1,
"page_size": 2,
"total_pages": 16
}Pagination
List endpoints take page (from 1) and page_size. Each endpoint's maximum page_size is listed in its parameter table.
Conditional requests
Responses carry an ETag. Send it back in If-None-Match and an unchanged resource answers 304 Not Modified with no body, which is the cheapest way to poll.
Errors
Errors return success: false and an error object with a stable code, a message that says what to fix, and details for validation problems.
{
"success": false,
"error": {
"code": "VALIDATION",
"message": "date: Field required",
"status": 422,
"details": [ { "type": "missing", "loc": ["query", "date"], "msg": "Field required" } ]
}
}| HTTP | error.code | Meaning |
|---|---|---|
| 401 | MISSING_API_KEY / invalid key | No key, or a key that is not valid. |
| 403 | GAME_NOT_INCLUDED | A Starter key chose another sport; tennis is not on this key. |
| 403 | HISTORY_WINDOW_EXCEEDED | The record is older than your plan's history window (Free 30 days, Starter 90 days). The message names the window. |
| 404 | NOT_FOUND | No resource with that id. |
| 422 | VALIDATION | A parameter is missing or invalid; details names it. |
| 429 | RATE_LIMIT | Too many calls. Retry-After and X-RateLimit-* headers say when to retry. |
| 503 | TENNIS_UPSTREAM_UNAVAILABLE | The data service is briefly unavailable. Safe to retry. |
Plans and limits
Limits are enforced by the API exactly as listed. The archive back to 1968 and real-time scores need Pro or Scale.
| Plan | Calls / month | Calls / minute | History | Live scores | WebSockets |
|---|---|---|---|---|---|
| Free | 500 | 10 | Last 30 days | 60-second delay | No |
| Starter ($15, tennis) | 10,000 | 30 | Last 90 days | 60-second delay | No |
| Pro ($59) | 250,000 | 100 | Full archive (1968-) | Real time | +$15/mo add-on |
| Scale ($100) | 1,000,000 | 400 | Full archive (1968-) | Real time | Included |