Tennis data API.
REST endpoints for ATP/WTA matches, tournaments, players, rankings, and ML predictions, plus an MCP server for Claude/ChatGPT/Gemini. Sports Addon · $5/mo
Quickstart
Three steps to your first request:
- Register at sports.bzzoiro.com/register/ — free account.
- Subscribe to the Sports Addon ($5/mo) to unlock the tennis API.
- Copy your API token from the dashboard and send it as
Authorization: Token YOUR_TOKEN.
Authentication
Pass your token on every request via the Authorization header:
Tokens never expire. Keep them secret. If a token leaks, regenerate it from the dashboard.
Base URL
Pagination
List endpoints use limit + offset query parameters and return:
limit— page size. Default 50, max 200 (rankings: max 500).offset— number of items to skip. Default 0.
Tournaments
Active tournaments — every tier from Grand Slams down to Challengers and ITFs.
Paginated list of tennis tournaments. Active-only by default.
| Parameter | Type | Description |
|---|---|---|
| circuit | string | ATP or WTA (case-insensitive) |
| category | string | grand_slam, masters_1000, atp_500, atp_250, wta_1000, wta_500, wta_250 |
| surface | string | hard, clay, grass, carpet |
| include_inactive | boolean | Include inactive tournaments. Default false. |
| limit / offset | int | Pagination (default 50, max 200) |
Full detail for a single tournament. Cached 5 min.
Players
Player profiles across both tours, with current ranking and biographical data.
Paginated player list. Each player includes their current ranking.
| Parameter | Type | Description |
|---|---|---|
| gender | string | M or F |
| country | string | ISO 3166-1 alpha-2 country code (e.g. ES, US) |
| search | string | Case-insensitive name fragment |
| limit / offset | int | Pagination (default 50, max 200) |
Full profile: name, country, height, weight, plays (right/left), turned-pro year, current ranking. Cached 5 min.
Matches
Tennis matches with set-by-set scores, serve stats, and live snapshots.
Paginated list. With no date filter, defaults to the next 7 days.
Every match includes decimal match-winner odds odds_player1 and
odds_player2 (null when no price is available).
| Parameter | Type | Description |
|---|---|---|
| date_from / date_to | date | YYYY-MM-DD bounds |
| tournament | int / str | Tournament ID or name fragment |
| player | int / str | Player ID or name fragment |
| status | string | scheduled, live, interrupted (rain delay / mid-match pause — partial sets retained), finished, cancelled, postponed, walkover, retired |
| limit / offset | int | Pagination |
Only currently in-progress matches with the live snapshot:
current_set, current_game_p1, current_game_p2,
current_point (e.g. "40-30"), is_serving_p1.
Cached 30 seconds.
Full match details including sets_detail (per-set breakdown),
live state (if in-progress), per-player serve stats: aces, double faults, first/second serve %,
and decimal match-winner odds (odds_player1 / odds_player2).
See also: /{id}/odds/ for per-bookmaker prices and
/{id}/h2h/ for head-to-head records.
Per-bookmaker match-winner odds for a single match. Returns decimal prices from 14+ bookmakers with price movement. Prices are refreshed every 3 hours across all active ATP, WTA, Challenger and WTA 125K events. When multi-bookmaker data is not yet available for a match, falls back to a single consensus price.
Head-to-head record between the two players of a match, plus last 5 finished matches for each player. Returns overall wins, wins by surface (hard/clay/grass), and recent match history.
Predictions
ML predictions calibrated against historical accuracy. XGBoost backbone.
Paginated predictions. Defaults to upcoming.
| Parameter | Type | Description |
|---|---|---|
| upcoming | boolean | Default true. Set false for past predictions. |
| date_from / date_to | date | YYYY-MM-DD bounds |
| limit / offset | int | Pagination |
Each prediction returns:
prob_player1_wins,prob_player2_wins— match winner probabilities (0–100)predicted_winner— 1 or 2confidence— model self-rated confidence (0–100)expected_total_sets,prob_over_2_5_setsexpected_total_games,prob_over_20_5_games,prob_over_21_5_games,prob_over_22_5_gamesprob_player1_wins_first_setactual_winner,was_winner_correct— populated after the match ends
Rankings
ATP & WTA weekly snapshots. Each row carries the previous week's position + points and the player's career best.
Latest snapshot by default. Pass date for a historical snapshot.
| Parameter | Type | Description |
|---|---|---|
| type | string | ATP (default) or WTA |
| date | date | YYYY-MM-DD snapshot date |
| limit / offset | int | Pagination (max 500) |
MCP server
The tennis MCP endpoint exposes 7 typed tools to LLM clients (Claude Desktop, ChatGPT, Cursor, Gemini). Drop the config below into your client and ask it questions in plain English.
📘 Full setup guide: step-by-step instructions for Claude Desktop, Cursor, Gemini CLI, VS Code, and a tools reference at /tennis/mcp-info/ →
Streamable HTTP transport. Auth via the same Authorization: Token header (or ?token= query param).
Available tools:
list_tournaments— filter by circuit/categorylist_players— filter by gender/countrysearch_players— by name fragmentlist_matches— by status, date windowget_match— match details by IDget_predictions— upcoming match predictionsget_rankings— top N ATP or WTA
Claude Desktop config
Static images
Player photos, served as PNG via the BSD image proxy. Public endpoint — no auth required, drop straight into <img src=> tags. Cached up to 1 year on the CDN.
Returns the player headshot. player_id is the id field from any tennis API response.
Returns 404 when the upstream has no image for that player. Sister endpoints exist for the other sports: /img/csgo-team/, /img/csgo-player/, /img/csgo-tournament/, /img/darts-player/, /img/hockey-team/, /img/hockey-league/.
Examples
Today's live matches with set scores
Predictions for an upcoming tournament
Live WebSocket
Tennis matches are available over the same wss://sports.bzzoiro.com/ws/live/ endpoint as football. Add "sport": "tennis" to your subscribe message. Requires the Live WebSocket addon ($3/mo) — separate from the Sports Pack.
Subscribe
Frames you receive
{
"type": "event",
"sport": "tennis",
"home": {"name": "Djokovic, N."},
"away": {"name": "Alcaraz, C."},
"score": {
"sets": [[6,3],[4,6],[2,1]],
"home_sets": 2, "away_sets": 1,
"point": "40-15",
"server": "home"
},
"stats": {
"home": {"aces": 8, "first_serve_pct": 63.4},
"away": { ... }
}
}
{
"type": "score",
"event_id": 36835,
"uts": 1780516577,
"sets": [[6,3],[4,6],[2,1]],
"set": 3,
"game": "2-1",
"point": "40-15",
"server": "home"
}
Polled from upstream every 5 seconds. Only pushed when a new point is registered.
Full example (Python)
See the WebSocket protocol docs for authentication, error codes and the full frame reference.
Need help? Email bzzoiro@proton.me. Bug reports welcome.