Tennis Stats API
Pricing
from $10.00 / 1,000 player profiles
Tennis Stats API
ATP and WTA player stats as structured tables: bio, rankings, Elo, results, head-to-head. One cent per player or head-to-head, a twentieth of a cent per ranking row.
Pricing
from $10.00 / 1,000 player profiles
Rating
0.0
(0)
Developer
Asgard Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
Tennis Stats API – ATP & WTA rankings, Elo, results, head-to-head
Give it player names. Get each player's profile from Tennis Abstract: country, birth date, height, playing hand and backhand, current and peak ranking, Elo rating and rank, plus stat tables: recent results with score, surface, round and serve stats, season records, career and last-52-weeks splits by surface, year-end rankings, most frequent opponents, and the Match Charting Project serve, return, rally and tactics tables when you ask for them.
Two more modes: the full ATP or WTA rankings and Elo tables, and a head-to-head between any two players.
Static pages, no login, no browser. Runs through Apify Proxy, nothing to set up. ATP and WTA.
Tennis stats data per player, ranking and head-to-head
- players – one record per player:
player(Tennis Abstract slug),fullName,tour,country,birthDate,heightCm,hand,backhand,active,currentRank,peakRank,peakRankFirst,peakRankLast,eloRating,eloRank, ids,photo,tables(each with the site's headers and rows; results rows carrymatch,opponentandopponentKey). - rankings / elo – one record per row:
tour,rank,player,country,birthdate,playerKey, or the Elo columns (elo,helo,celo,gelo,peak_elo…). - h2h –
summary(meetings, wins, losses, tiebreaks, surface stats) andrecentMatches.foundis false when the two never met.
Use cases
- Tennis apps and bots.
- Betting models.
- Fantasy tools.
- Journalism and research datasets.
Input
| Field | Default | Meaning |
|---|---|---|
mode | players | players, rankings, elo or h2h. |
players | – | Names or Tennis Abstract slugs. Accents are fine ("Novak Đoković"). A unique last name works ("Alcaraz"); an ambiguous one is reported with the candidates. The same player written twice counts once. |
tour | auto | auto reads the tour from the rankings; atp or wta to force it. |
tables | 7 defaults | Table ids: recent-results, tour-years, chall-years, recent-finals, year-end-rankings, recent-events, career-splits, last52-splits, winners-errors, serve-speed, pbp-points, pbp-games, pbp-stats, mcp-serve, mcp-return, mcp-rally, mcp-tactics, head-to-heads. |
tours, limit | atp + wta, all rows | Rankings and Elo modes. |
pairs | – | "Carlos Alcaraz vs Jannik Sinner". |
timeoutSecs | 120 | Time budget per player. |
concurrency | 3 | Players in parallel. |
Output example
{ "player": "CarlosAlcaraz", "fullName": "Carlos Alcaraz", "tour": "ATP", "country": "ESP", "birthDate": "2003-05-05", "heightCm": 183, "hand": "right", "backhand": "two-handed","currentRank": 3, "peakRank": 1, "peakRankFirst": "2022-09-12", "eloRating": 2147, "eloRank": 2, "atpId": "A0E2", "twitter": "carlosalcaraz","tables": { "recent-results": { "headers": ["Date", "Tournament", "Surface", "Rd", "Rk", "vRk", "match", "Score", "DR", "A%", "DF%", "1stIn", "1st%", "2nd%", "BPSvd", "Time"],"rows": [{ "Date": "31-Aug-2026", "Tournament": "US Open", "Surface": "Hard", "Rd": "QF", "match": "(2)Alcaraz vs (8)Berrettini", "opponent": "Berrettini", "opponentKey": "MatteoBerrettini", "Score": "6-1 6-3 6-4", "Time": "2:04" }] },"head-to-heads": { "rows": [{ "Opponent": "Jannik Sinner [ITA]", "opponentKey": "JannikSinner", "Mtgs": "18", "W": "11", "L": "7", "TB W": "9", "TB L": "7" }] } } }
How to use
- Paste your player names, or a mode such as rankings into the input form. The example input is ready to run as is.
- Click Start. Rows appear in the Output tab as they are found.
- Download the table as CSV, JSON or Excel, or read it through the API.
Pricing
Pay per event: player $0.01 per profile with all requested tables, ranking-row $0.0005 per rankings or Elo row, h2h $0.01 per head-to-head with meetings on record. The full ATP rankings (about 2,300 rows) is about $1.15. Players that are not found, pairs that never met, and failed requests are free.
Good to know
- Head-to-head summary exists when one player is among the other's 15 most frequent opponents. Otherwise you get the recent meetings only, with a note.
- Data freshness is Tennis Abstract's, usually within a day of a match.
- Numbers stay as text where the site mixes formats ("83.9%", "64-13"); ranks, Elo and dates in the bio are numbers and ISO dates.
- Not included: live scores, odds, draws. The official tour and score sites block automated access.
- Errors are in plain words:
player not found,ambiguous last name: …,timeout,rate limited (429),ENOTFOUND (domain not found). Your spend limit stops the run cleanly; rows beyond it are neither delivered nor charged.
Use from code or an AI agent
Every run can be started and read through the Apify API, the JavaScript and Python clients, or an AI agent with tool access. Open the API tab on this page for ready-made snippets. Pricing is per event, so an agent pays only for what it receives.
FAQ
Are live scores or odds included? No. The official tour sites block automated access. Rankings, Elo, results and head-to-head records are.
Does it work for retired players? Yes, as long as the player has a page on the source site. Tour is read from the rankings directory; retired players fall back to the site's own tour label.
What about common last names like Zverev? A last name that matches several players is reported as ambiguous with the candidates, free. Use the full name.
Are pairs that never played each other charged?
No. A head-to-head with no meetings on record is returned with found: false and is free.
Where does the data come from and how fresh is it? Tennis Abstract, updated after each tournament week. The ranking date is in every rankings row.