WTA API
Welcome to the BALLDONTLIE WTA API, your comprehensive source for WTA Tour data. This API covers women's singles tennis only. Data includes player profiles, tournament information, WTA rankings, match results, and betting odds from the WTA Tour. An API key is required. You can obtain an API key by creating a free account on our website. Read the authentication section to learn how to use the API key.
Take a look at our other APIs.
Join us on discord.
AI-Powered Integration
Using the OpenAPI Specification with AI
Our complete OpenAPI specification allows AI assistants to automatically understand and interact with our API. Simply share the spec URL with your AI assistant and describe what you want to build—the AI will handle the technical implementation.
Getting Started with AI:
- Copy this URL:
https://www.balldontlie.io/openapi.yml - Share it with your preferred AI assistant (ChatGPT, Claude, Gemini, etc.)
- Tell the AI what you want to build (e.g., "Create a dashboard showing WTA rankings")
- The AI will read the OpenAPI spec and write the code for you
Example prompts to try:
- "Using the OpenAPI spec at https://www.balldontlie.io/openapi.yml, show me how to get Iga Swiatek's match history"
- "Read the BALLDONTLIE OpenAPI spec and create a Python script that fetches the current WTA rankings"
- "Help me understand the available WTA Tennis endpoints from this OpenAPI spec: https://www.balldontlie.io/openapi.yml"
This makes it incredibly easy for non-technical users, analysts, and researchers to leverage our tennis data without needing to learn programming from scratch.
Google Sheets Integration
Our Google Sheets integration lets you access all the same data available through our API using simple spreadsheet formulas. Perfect for fantasy sports tracking, betting analysis, and sports research.
Quick Start:
- Get your API key from app.balldontlie.io
- Copy our Google Sheets script
- Paste it into your Google Sheet (Extensions > Apps Script)
- Start using functions in your cells
Example functions:
=BDL_WTA_PLAYERS("Gauff")- Search for players=BDL_WTA_TOURNAMENTS(2026)- Get tournaments=BDL_WTA_RANKINGS(2026)- Get WTA rankings=BDL_WTA_ODDS("2026-01-27")- Get betting odds
For full setup instructions and the complete list of 150+ functions, see our Google Sheets Integration Guide.
Account Tiers
There are three different account tiers which provide you access to different types of data. Visit our website to create an account for free.
Paid tiers do not apply across sports. The tier you purchase for WTA will not automatically be applied to other sports. You can purchase the ALL-ACCESS ($299.99/mo) tier to get access to every endpoint for every sport.
Read the table below to see the breakdown.
| Endpoint | Free | ALL-STAR | GOAT |
|---|---|---|---|
| Players | Yes | Yes | Yes |
| Tournaments | Yes | Yes | Yes |
| Rankings | Yes | Yes | Yes |
| Matches | No | Yes | Yes |
| Head to Head | No | No | Yes |
| Betting Odds | No | No | Yes |
The feature breakdown per tier is shown in the table below.
| Tier | Requests / Min | $USD / mo. |
|---|---|---|
| GOAT | 600 | 39.99 |
| ALL-STAR | 60 | 9.99 |
| Free | 5 | 0 |
Authentication
To authorize, use this code:
curl "api_endpoint_here" -H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/players', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'https://api.balldontlie.io/wta/v1/players',
headers={'Authorization': 'YOUR_API_KEY'}
)
if response.status_code == 200:
data = response.json()
print(data)
else:
print(f'Error: {response.status_code}')
Make sure to replace
YOUR_API_KEYwith your API key.
BALLDONTLIE uses API keys to allow access to the API. You can obtain an API key by creating a free account at our website
We expect the API key to be included in all API requests to the server in a header that looks like the following:
Authorization: YOUR_API_KEY
Pagination
This API uses cursor based pagination rather than limit/offset. Endpoints that support pagination will send back responses with a meta key that looks like what is displayed on the right.
{
"meta": {
"next_cursor": 90,
"per_page": 25
}
}
You can use per_page to specify the maximum number of results. It defaults to 25 and doesn't allow values larger than 100.
You can use next_cursor to get the next page of results. Specify it in the request parameters like this: ?cursor=NEXT_CURSOR.
Errors
The API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 401 | Unauthorized - You either need an API key or your account tier does not have access to the endpoint. |
| 400 | Bad Request -- The request is invalid. The request parameters are probably incorrect. |
| 404 | Not Found -- The specified resource could not be found. |
| 406 | Not Acceptable -- You requested a format that isn't json. |
| 429 | Too Many Requests -- You're rate limited. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Players
Get All Players
curl "https://api.balldontlie.io/wta/v1/players?search=Sabalenka" \
-H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/players?search=Sabalenka', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'https://api.balldontlie.io/wta/v1/players',
headers={'Authorization': 'YOUR_API_KEY'},
params={'search': 'Sabalenka'}
)
if response.status_code == 200:
players = response.json()['data']
for player in players:
print(f"{player['full_name']} - {player['country_code']}")
The above command returns JSON structured like this:
{
"data": [
{
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
}
],
"meta": {
"per_page": 25
}
}
This endpoint retrieves all WTA players with optional search and filtering.
HTTP Request
GET https://api.balldontlie.io/wta/v1/players
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| cursor | integer | Cursor for pagination |
| per_page | integer | Number of results per page (max 100) |
| search | string | Search players by name |
| first_name | string | Filter by first name |
| last_name | string | Filter by last name |
| country | string | Filter by country name |
| country_code | string | Filter by country code (e.g., "POL") |
| player_ids | array | Filter by specific player IDs |
Get Specific Player
curl "https://api.balldontlie.io/wta/v1/players/1" \
-H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/players/1', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
player_id = 1 # Aryna Sabalenka
response = requests.get(
f'https://api.balldontlie.io/wta/v1/players/{player_id}',
headers={'Authorization': 'YOUR_API_KEY'}
)
if response.status_code == 200:
player = response.json()['data']
print(f"{player['full_name']} ({player['country_code']})")
The above command returns JSON structured like this:
{
"data": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
}
}
This endpoint retrieves a specific player.
HTTP Request
GET https://api.balldontlie.io/wta/v1/players/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the player |
Tournaments
Get All Tournaments
curl "https://api.balldontlie.io/wta/v1/tournaments?season=2026&category=Grand%20Slam" \
-H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/tournaments?season=2026&category=Grand%20Slam', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'https://api.balldontlie.io/wta/v1/tournaments',
headers={'Authorization': 'YOUR_API_KEY'},
params={'season': 2026, 'category': 'Grand Slam'}
)
if response.status_code == 200:
tournaments = response.json()['data']
for tournament in tournaments:
print(f"{tournament['name']} - {tournament['surface']} - {tournament['category']}")
The above command returns JSON structured like this:
{
"data": [
{
"id": 7,
"name": "AUSTRALIAN OPEN",
"location": "MELBOURNE, AUSTRALIA",
"surface": "Hard",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-01-18",
"end_date": "2026-02-01",
"prize_money": null,
"prize_currency": "USD",
"draw_size": 128
},
{
"id": 38,
"name": "ROLAND GARROS",
"location": "PARIS, FRANCE",
"surface": "Clay",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-05-24",
"end_date": "2026-06-07",
"prize_money": null,
"prize_currency": "USD",
"draw_size": null
},
{
"id": 50,
"name": "WIMBLEDON",
"location": "WIMBLEDON, GREAT BRITAIN",
"surface": "Grass",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-06-29",
"end_date": "2026-07-12",
"prize_money": null,
"prize_currency": "USD",
"draw_size": null
},
{
"id": 66,
"name": "US OPEN",
"location": "NEW YORK, NY, UNITED STATES",
"surface": "Hard",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-08-30",
"end_date": "2026-09-13",
"prize_money": null,
"prize_currency": "USD",
"draw_size": null
}
],
"meta": {
"per_page": 25
}
}
This endpoint retrieves all WTA tournaments with optional filtering.
HTTP Request
GET https://api.balldontlie.io/wta/v1/tournaments
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| cursor | integer | Cursor for pagination |
| per_page | integer | Number of results per page (max 100) |
| tournament_ids | array | Filter by specific tournament IDs |
| season | integer | Filter by season year |
| surface | string | Filter by surface (Hard, Clay, Grass, Carpet) |
| category | string | Filter by category (Grand Slam, WTA 1000, etc.) |
Get Specific Tournament
curl "https://api.balldontlie.io/wta/v1/tournaments/7?season=2026" \
-H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/tournaments/7?season=2026', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
tournament_id = 7 # Australian Open
response = requests.get(
f'https://api.balldontlie.io/wta/v1/tournaments/{tournament_id}',
headers={'Authorization': 'YOUR_API_KEY'},
params={'season': 2026}
)
if response.status_code == 200:
tournament = response.json()['data']
print(f"{tournament['name']} - {tournament['location']} - {tournament['surface']}")
The above command returns JSON structured like this:
{
"data": {
"id": 7,
"name": "AUSTRALIAN OPEN",
"location": "MELBOURNE, AUSTRALIA",
"surface": "Hard",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-01-18",
"end_date": "2026-02-01",
"prize_money": null,
"prize_currency": "USD",
"draw_size": 128
}
}
This endpoint retrieves a specific tournament.
HTTP Request
GET https://api.balldontlie.io/wta/v1/tournaments/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the tournament |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| season | integer | Get tournament info for a specific year. Defaults to most recent if omitted |
Rankings
Get Rankings
curl "https://api.balldontlie.io/wta/v1/rankings" \
-H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/rankings', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'https://api.balldontlie.io/wta/v1/rankings',
headers={'Authorization': 'YOUR_API_KEY'}
)
if response.status_code == 200:
rankings = response.json()['data']
for ranking in rankings[:10]:
player = ranking['player']
print(f"#{ranking['rank']}: {player['full_name']} - {ranking['points']} pts")
The above command returns JSON structured like this:
{
"data": [
{
"id": 1131,
"player": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"rank": 1,
"points": 10990,
"movement": 0,
"ranking_date": "2026-01-19"
},
{
"id": 1132,
"player": {
"id": 2,
"first_name": "Iga",
"last_name": "Swiatek",
"full_name": "Iga Swiatek",
"country": null,
"country_code": "POL",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"rank": 2,
"points": 8328,
"movement": 0,
"ranking_date": "2026-01-19"
},
{
"id": 1133,
"player": {
"id": 3,
"first_name": "Coco",
"last_name": "Gauff",
"full_name": "Coco Gauff",
"country": null,
"country_code": "USA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"rank": 3,
"points": 6423,
"movement": 0,
"ranking_date": "2026-01-19"
}
],
"meta": {
"next_cursor": 1133,
"per_page": 25
}
}
This endpoint retrieves current WTA rankings.
HTTP Request
GET https://api.balldontlie.io/wta/v1/rankings
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| cursor | integer | Cursor for pagination |
| per_page | integer | Number of results per page (max 100) |
| player_ids | array | Filter rankings for specific player IDs |
| date | string | Get rankings for a specific date (YYYY-MM-DD) |
Matches
Get All Matches
curl "https://api.balldontlie.io/wta/v1/matches?tournament_ids[]=7&season=2026&round=M1" \
-H "Authorization: YOUR_API_KEY"
const params = new URLSearchParams();
params.append('tournament_ids[]', 7); // Australian Open
params.append('season', 2026);
params.append('round', 'M1'); // Round 1
const response = await fetch(`https://api.balldontlie.io/wta/v1/matches?${params}`, {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'https://api.balldontlie.io/wta/v1/matches',
headers={'Authorization': 'YOUR_API_KEY'},
params={'tournament_ids[]': 7, 'season': 2026, 'round': 'M1'} # Australian Open Round 1
)
if response.status_code == 200:
matches = response.json()['data']
for match in matches:
p1 = match['player1']['full_name']
p2 = match['player2']['full_name']
score = match['score'] or 'TBD'
print(f"{p1} vs {p2}: {score}")
The above command returns JSON structured like this:
{
"data": [
{
"id": 45,
"tournament": {
"id": 7,
"name": "AUSTRALIAN OPEN",
"location": "MELBOURNE, AUSTRALIA",
"surface": "Hard",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-01-18",
"end_date": "2026-02-01",
"prize_money": null,
"prize_currency": "USD",
"draw_size": 128
},
"season": 2026,
"round": "M1",
"player1": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player2": {
"id": 180,
"first_name": "Tiantsoa Sarah",
"last_name": "Rakotomanga Rajaonah",
"full_name": "Tiantsoa Sarah Rakotomanga Rajaonah",
"country": null,
"country_code": "FRA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"winner": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"score": "6-4 6-1",
"duration": null,
"number_of_sets": 2,
"match_status": "completed",
"is_live": false
}
],
"meta": {
"per_page": 25
}
}
This endpoint retrieves all matches with optional filtering.
HTTP Request
GET https://api.balldontlie.io/wta/v1/matches
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| cursor | integer | Cursor for pagination |
| per_page | integer | Number of results per page (max 100) |
| tournament_ids | array | Filter matches by tournament IDs |
| player_ids | array | Filter matches involving specific players |
| season | integer | Filter matches by season year |
| round | string | Filter by round (Finals, Semi-Finals, etc.) |
| is_live | boolean | Filter for live matches only |
Get Specific Match
curl "https://api.balldontlie.io/wta/v1/matches/45" \
-H "Authorization: YOUR_API_KEY"
const response = await fetch('https://api.balldontlie.io/wta/v1/matches/45', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
match_id = 45 # Australian Open 2026 Round 1 - Sabalenka
response = requests.get(
f'https://api.balldontlie.io/wta/v1/matches/{match_id}',
headers={'Authorization': 'YOUR_API_KEY'}
)
if response.status_code == 200:
match = response.json()['data']
print(f"{match['player1']['full_name']} vs {match['player2']['full_name']}")
print(f"Score: {match['score']} | Round: {match['round']}")
The above command returns JSON structured like this:
{
"data": {
"id": 45,
"tournament": {
"id": 7,
"name": "AUSTRALIAN OPEN",
"location": "MELBOURNE, AUSTRALIA",
"surface": "Hard",
"category": "Grand Slam",
"season": 2026,
"start_date": "2026-01-18",
"end_date": "2026-02-01",
"prize_money": null,
"prize_currency": "USD",
"draw_size": 128
},
"season": 2026,
"round": "M1",
"player1": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player2": {
"id": 180,
"first_name": "Tiantsoa Sarah",
"last_name": "Rakotomanga Rajaonah",
"full_name": "Tiantsoa Sarah Rakotomanga Rajaonah",
"country": null,
"country_code": "FRA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"winner": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"score": "6-4 6-1",
"duration": null,
"number_of_sets": 2,
"match_status": "completed",
"is_live": false
}
}
This endpoint retrieves a specific match.
HTTP Request
GET https://api.balldontlie.io/wta/v1/matches/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the match |
Head to Head
Get Head to Head Record
curl "https://api.balldontlie.io/wta/v1/head_to_head?player1_id=1&player2_id=2" \
-H "Authorization: YOUR_API_KEY"
// Get Swiatek vs Sabalenka head-to-head
const response = await fetch('https://api.balldontlie.io/wta/v1/head_to_head?player1_id=1&player2_id=2', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
# Get head-to-head record between Swiatek and Sabalenka
response = requests.get(
'https://api.balldontlie.io/wta/v1/head_to_head',
headers={'Authorization': 'YOUR_API_KEY'},
params={'player1_id': 1, 'player2_id': 2} # Swiatek vs Sabalenka
)
if response.status_code == 200:
h2h = response.json()['data']
p1 = h2h['player1']['full_name']
p2 = h2h['player2']['full_name']
print(f"{p1} vs {p2}: {h2h['player1_wins']}-{h2h['player2_wins']}")
The above command returns JSON structured like this:
{
"data": {
"id": 39,
"player1": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player2": {
"id": 2,
"first_name": "Iga",
"last_name": "Swiatek",
"full_name": "Iga Swiatek",
"country": null,
"country_code": "POL",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player1_wins": 5,
"player2_wins": 8
}
}
This endpoint retrieves the head-to-head record between two players.
HTTP Request
GET https://api.balldontlie.io/wta/v1/head_to_head
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| player1_id | integer | Yes | The ID of the first player |
| player2_id | integer | Yes | The ID of the second player |
Match Statistics
Get Match Statistics
curl "https://api.balldontlie.io/wta/v1/match_stats?match_ids[]=1" \
-H "Authorization: YOUR_API_KEY"
const params = new URLSearchParams();
params.append('match_ids[]', 1); // 2026 Australian Open Quarterfinal
const response = await fetch(`https://api.balldontlie.io/wta/v1/match_stats?${params}`, {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'https://api.balldontlie.io/wta/v1/match_stats',
headers={'Authorization': 'YOUR_API_KEY'},
params={'match_ids[]': 1} # 2026 Australian Open Quarterfinal
)
if response.status_code == 200:
stats = response.json()['data']
for stat in stats:
player = stat['player']['full_name']
aces = stat['aces'] or 0
df = stat['double_faults'] or 0
print(f"{player}: Aces {aces}, Double Faults {df}")
The above command returns JSON structured like this:
{
"data": [
{
"id": 384169,
"match": {
"id": 1,
"tournament_id": 7,
"season": 2026,
"round": "Quarterfinals",
"player1_id": 91,
"player2_id": 92,
"winner_id": 91
},
"player": {
"id": 91,
"first_name": "Zeynep",
"last_name": "Sonmez",
"full_name": "Zeynep Sonmez",
"country": null,
"country_code": "TUR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"set_number": 0,
"serve_rating": 117,
"aces": 4,
"double_faults": 2,
"first_serve_pct": 73.85,
"first_serve_points_won_pct": 66.67,
"second_serve_points_won_pct": 47.06,
"break_points_saved_pct": 71.43,
"return_rating": 138,
"first_return_won_pct": 69.7,
"second_return_won_pct": 66.67,
"break_points_converted_pct": 71.43,
"total_service_points_won_pct": 61.54,
"total_return_points_won_pct": 54.76,
"total_points_won_pct": 58.88
},
{
"id": 384170,
"match": {
"id": 1,
"tournament_id": 7,
"season": 2026,
"round": "Quarterfinals",
"player1_id": 91,
"player2_id": 92,
"winner_id": 91
},
"player": {
"id": 92,
"first_name": "Anastasia",
"last_name": "Gasanova",
"full_name": "Anastasia Gasanova",
"country": null,
"country_code": "RSA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"set_number": 0,
"serve_rating": 94,
"aces": 0,
"double_faults": 4,
"first_serve_pct": 78.57,
"first_serve_points_won_pct": 48.48,
"second_serve_points_won_pct": 33.33,
"break_points_saved_pct": 28.57,
"return_rating": 91,
"first_return_won_pct": 52.08,
"second_return_won_pct": 52.94,
"break_points_converted_pct": 28.57,
"total_service_points_won_pct": 45.24,
"total_return_points_won_pct": 38.46,
"total_points_won_pct": 41.12
}
],
"meta": {
"per_page": 25
}
}
This endpoint retrieves detailed match statistics for players.
HTTP Request
GET https://api.balldontlie.io/wta/v1/match_stats
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| cursor | integer | Cursor for pagination |
| per_page | integer | Number of results per page (max 100) |
| match_ids | array | Filter by specific match IDs |
| player_ids | array | Filter statistics for specific players |
| set_number | integer | Filter by set number (0 for full match stats) |
Betting Odds
Get Betting Odds
curl "https://api.balldontlie.io/wta/v1/odds?tournament_ids[]=7&season=2026" \
-H "Authorization: YOUR_API_KEY"
const params = new URLSearchParams();
params.append('tournament_ids[]', 7); // Australian Open
params.append('season', 2026);
const response = await fetch(`https://api.balldontlie.io/wta/v1/odds?${params}`, {
headers: {
'Authorization': 'YOUR_API_KEY'
}
});
const data = await response.json();
console.log(data);
import requests
# Get betting odds for the 2026 Australian Open
response = requests.get(
'https://api.balldontlie.io/wta/v1/odds',
headers={'Authorization': 'YOUR_API_KEY'},
params={'tournament_ids[]': 7, 'season': 2026} # Australian Open 2026
)
if response.status_code == 200:
odds = response.json()['data']
for odd in odds:
p1 = odd['player1']['full_name'] if odd['player1'] else 'TBD'
p2 = odd['player2']['full_name'] if odd['player2'] else 'TBD'
print(f"{odd['vendor']}: {p1} ({odd['player1_odds']}) vs {p2} ({odd['player2_odds']})")
The above command returns JSON structured like this:
{
"data": [
{
"id": 90174375,
"match_id": 45,
"vendor": "draftkings",
"player1": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player2": {
"id": 180,
"first_name": "Tiantsoa Sarah",
"last_name": "Rakotomanga Rajaonah",
"full_name": "Tiantsoa Sarah Rakotomanga Rajaonah",
"country": null,
"country_code": "FRA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player1_odds": -50000,
"player2_odds": 3500,
"updated_at": "2026-01-18T09:10:22.599Z"
},
{
"id": 90174439,
"match_id": 45,
"vendor": "draftkings",
"player1": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player2": {
"id": 180,
"first_name": "Tiantsoa Sarah",
"last_name": "Rakotomanga Rajaonah",
"full_name": "Tiantsoa Sarah Rakotomanga Rajaonah",
"country": null,
"country_code": "FRA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player1_odds": -50000,
"player2_odds": 6900,
"updated_at": "2026-01-18T09:00:38.079Z"
},
{
"id": 90174297,
"match_id": 45,
"vendor": "fanduel",
"player1": {
"id": 1,
"first_name": "Aryna",
"last_name": "Sabalenka",
"full_name": "Aryna Sabalenka",
"country": null,
"country_code": "BLR",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player2": {
"id": 180,
"first_name": "Tiantsoa Sarah",
"last_name": "Rakotomanga Rajaonah",
"full_name": "Tiantsoa Sarah Rakotomanga Rajaonah",
"country": null,
"country_code": "FRA",
"birth_place": null,
"age": null,
"height_cm": null,
"weight_kg": null,
"plays": null,
"turned_pro": null
},
"player1_odds": -50000,
"player2_odds": 10000,
"updated_at": "2026-01-18T09:30:05.437Z"
}
],
"meta": {
"next_cursor": 90174297,
"per_page": 25
}
}
This endpoint retrieves betting odds for WTA matches from various sportsbooks.
Important: At least one of match_ids, tournament_ids, player_ids, or season is required.
HTTP Request
GET https://api.balldontlie.io/wta/v1/odds
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| cursor | integer | Cursor for pagination |
| per_page | integer | Number of results per page (max 100) |
| match_ids | array | Filter odds by match IDs |
| tournament_ids | array | Filter odds by tournament IDs |
| player_ids | array | Filter odds by player IDs |
| season | integer | Filter odds by season year |
Available Vendors
| Vendor | Description |
|---|---|
| draftkings | DraftKings |
| fanduel | FanDuel |
Odds Format
Odds are returned in American format: - Negative odds (e.g., -180) indicate the favorite and show how much you need to bet to win $100 - Positive odds (e.g., +150) indicate the underdog and show how much you win on a $100 bet