Tennis Match History - Career Results & Stats avatar

Tennis Match History - Career Results & Stats

Pricing

from $0.70 / 1,000 matches

Go to Apify Store
Tennis Match History - Career Results & Stats

Tennis Match History - Career Results & Stats

Every match of a tennis player's career, newest first: ATP, WTA, Challenger and ITF results back to 1990 with score, round, surface, both players' Elo before the match and serve / return statistics. Type a name, get the whole career. Works as an MCP tool for AI agents.

Pricing

from $0.70 / 1,000 matches

Rating

0.0

(0)

Developer

CrawlPlant

CrawlPlant

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

2

Monthly active users

16 days ago

Last modified

Categories

Share

Independent tool, not affiliated with, endorsed by or connected to Flashscore, Livesport, the ATP, the WTA or the ITF. It reads the public match data that flashscore.com shows to every visitor.

Type a player's name, get every match of their career. ATP, WTA, Challenger and ITF singles and doubles back to 1990, newest first, one row per match: date, tournament, round, surface, opponent, set-by-set score, winner, duration, both players' Elo rating before the match with the Elo win probability, and serve and return statistics (aces, double faults, 1st serve %, points won on 1st and 2nd serve, break points saved and converted).

Why this one

  • The whole career, not the last 40 results. Jannik Sinner: 544 singles matches from his first ITF event in 2018 (476 ATP, 42 Challenger, 26 ITF). Novak Djokovic: 1,444. One run, a few seconds.
  • Names work. "Jannik Sinner", "Swiatek" or "Alcaraz" finds the player; paste a Flashscore player URL to pick one exactly.
  • Statistics included. Serve and return statistics for ATP and WTA matches from 2012 (458 of Sinner's 544 matches), at no extra cost.
  • Elo before every match. Overall and per surface, computed from every match since 1990, with the win probability it gave: test a model on years of history without leaking the result into the rating.
  • Head-to-head in one filter. Add the opponent's name and get every meeting: Sinner v Alcaraz returns their 18 tour meetings (exhibitions are left out unless you ask for them).
  • Updated every hour from a database of more than 900,000 matches (ATP and WTA from 1990, Challenger from 2008, ITF from 2011).
  • See it live. A career head-to-head with every meeting and the Elo leaders of both tours, from the same database your runs read: crawlplant.com/tennis-match-history.

What can you use it for?

  • Betting and prediction models: years of results per player with pre-match Elo and serve statistics.
  • Scouting and journalism: a player's record on a surface, at the Grand Slams or against one rival.
  • Fantasy and apps: career data for player pages without maintaining your own scraper.
  • AI agents: ask for any player's history as JSON.

Quick start

  1. Click Try for free with the default input (Jannik Sinner's 200 latest matches).
  2. Replace Players with the names you want, or raise Max results for whole careers.
  3. Download the table as CSV, Excel or JSON, or save the input as a task and schedule it to keep a dataset current.

Copy to your AI assistant

Paste this into ChatGPT, Claude or any agent so it knows how to use the Actor:

crawlplant/tennis-match-history on Apify: every match of a tennis player's career (ATP, WTA, Challenger, ITF, back to
1990), newest first. Input: playerUrls (names like "Jannik Sinner" or Flashscore player URLs), players (opponent name
contains: head-to-head), surfaces (hard/clay/grass/carpet), tournaments (name contains, e.g. "Wimbledon"), tours,
matchType (singles/doubles/all), status (finished/scheduled/live/all), includeStatistics, maxItems (default 200).
Row: date, tournament, round, surface, player1Name, player2Name, score, sets, winnerName, durationMinutes, player1Elo,
player2Elo (pre-match), player1EloWinProbability, statistics (aces, serve %, break points...), url.
Price: $1.00 per 1,000 matches on the Free plan.

Ready-to-use examples

1. A player's whole career

{ "playerUrls": ["Jannik Sinner"], "maxItems": 2000 }

2. Every meeting of two rivals

{ "playerUrls": ["Jannik Sinner"], "players": ["Alcaraz"] }

3. Clay-court matches of several players

{ "playerUrls": ["Carlos Alcaraz", "Iga Swiatek"], "surfaces": ["clay"], "maxItems": 1000 }

4. Grand Slam matches only

{ "playerUrls": ["Novak Djokovic"], "tournaments": ["Australian Open", "French Open", "Wimbledon", "US Open"], "maxItems": 1000 }

5. A player's next scheduled matches

{ "playerUrls": ["Coco Gauff"], "status": "scheduled" }

6. One exact player by URL, Challenger and ITF years only

{ "playerUrls": ["https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/"], "tours": ["challenger-men", "itf-men"] }

7. Doubles career

{ "playerUrls": ["Rajeev Ram"], "matchType": "doubles", "maxItems": 1000 }

How to…

Download a tennis player's match history

Put the name in playerUrls and set maxItems above the career length (example 1): a long career has 1,000-1,500 singles matches. Rows come newest first.

Get the head-to-head of two players, match by match

One player in playerUrls, the other in players (example 2). Each row is one meeting with its score, round and both players' Elo at the time.

Compare players on one surface or at the Grand Slams

surfaces keeps hard, clay, grass or carpet (example 3); tournaments keeps tournaments whose name contains any of the words (example 4).

Input options

OptionDefaultDescription
playerUrlsJannik SinnerPlayer names or Flashscore player page URLs
players[]Opponent name contains: keep only matches against these players
surfacesallhard, clay, grass, carpet
tournaments[]Tournament name contains, e.g. Wimbledon, Masters
toursall but exhibitionsatp, wta, challenger-men, challenger-women, itf-men, itf-women, teams, other
matchTypesinglessingles, doubles, all
statusfinishedfinished, scheduled, live, all
includeStatisticstrueServe and return statistics (included in the price)
maxItems200Maximum matches in total

Example output

Sinner's 2026 Wimbledon final (shortened: 2 of the match statistics, no player objects):

{
"recordType": "match",
"matchId": "n5DWLXD5",
"url": "https://www.flashscore.com/match/n5DWLXD5/",
"date": "2026-07-12",
"startTime": "2026-07-12T15:10:00.000Z",
"tour": "atp",
"tournament": "Wimbledon",
"round": "Final",
"surface": "grass",
"status": "finished",
"player1Name": "Sinner J.",
"player2Name": "Zverev A.",
"player1Elo": 2717,
"player2Elo": 2483,
"player1EloWinProbability": 0.7613,
"winner": "player1",
"winnerName": "Sinner J.",
"score": "6-7(7) 7-6(2) 6-3 6-4",
"durationMinutes": 228,
"elo": { "player1": 2717, "player2": 2483, "player1Surface": 2157, "player2Surface": 1988, "basis": "pre-match" },
"statistics": {
"match": {
"aces": { "player1": 15, "player2": 17 },
"winners": { "player1": 58, "player2": 49 }
}
},
"source": "cache"
}

Output fields

FieldDescription
matchId, urlFlashscore's match id and page
date, startTime, endTimeDay (UTC) and times (ISO)
tour, category, tournament, tournamentStage, roundatp, wta, challenger-men...; "Qualification" or null for the main draw; "Final", "Semi-finals", "Q1"
surface, indoor, tournamentCountryhard / clay / grass / carpet, indoor court, host country
player1, player2, player1Name, player2NameBoth sides with Flashscore ids, URLs and countries (both players of a doubles pair)
score, sets, setsPlayer1, setsPlayer2"6-7(7) 7-6(2) 6-3 6-4" and each set with tiebreak points
winner, winnerName, statusplayer1 / player2; finished, retired, walkover, scheduled...
durationMinutesMatch length
player1Elo, player2Elo, player1EloWinProbability, eloElo before the match, overall and on the surface
statisticsServe and return statistics for the match and each set (ATP and WTA from 2012)
scrapedAt, sourceWhen the run read it; cache = our tennis database, live = read from Flashscore in the run

How is Elo calculated?

Every singles match since 1990 updates both players' ratings (a K-factor that shrinks with the number of matches played, plus a separate rating per surface). A row keeps the ratings both players had before the match, so a result never counts in its own numbers.

How much does tennis match history data cost?

Pay per result: platform usage is included. One price per match, statistics included.

EventNo discount (Free plan)Bronze (Starter)Silver (Scale)Gold (Business)
Match (per 1,000)$1.00$0.90$0.80$0.70
Actor start (per run)$0.00005$0.00005$0.00005$0.00005
Example on the Free planMatchesCost
Default run: Sinner's 200 latest matches200~$0.20
Sinner's whole career544~$0.54
Djokovic's whole career1,444~$1.44
Sinner v Alcaraz, every meeting18~$0.02

Set a maximum cost per run in the run options to stop a large run at your budget.

Reliability

  • Careers come from our tennis database, updated every hour; a run doesn't depend on scraping hundreds of pages.
  • If the database can't be reached, the run falls back to the player's Flashscore page (about 40 recent results) and says so in the log.
  • A name that matches several players takes the best-known one and names the others in the run's warnings.

Run it through the API

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('crawlplant/tennis-match-history').call({ playerUrls: ['Jannik Sinner'], players: ['Alcaraz'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((m) => `${m.date} ${m.tournament} ${m.round}: ${m.winnerName} ${m.score}`));

Python:

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawlplant/tennis-match-history").call(run_input={"playerUrls": ["Iga Swiatek"], "maxItems": 2000})
for m in client.dataset(run["defaultDatasetId"]).iterate_items():
print(m["date"], m["tournament"], m["winnerName"], m["score"])

Use with AI agents

The Actor works as a tool in the Apify MCP server for Claude, ChatGPT, Cursor and others:

https://mcp.apify.com?tools=crawlplant/tennis-match-history

Try "how has Sinner done against Alcaraz on clay?".

Use it when you need a player's matches from a name: a whole career, one surface or tournament, or every meeting with one rival.

Not for bookmaker odds, form or rankings next to each match (use the Flashscore Tennis Scraper).

More tennis data

FAQ

How far back does it go?

ATP and WTA matches from 1990, Challenger from 2008, ITF from 2011. Serve and return statistics: ATP and WTA from 2012.

Does it include doubles?

Yes, matchType: "doubles" (example 7); both players of each pair are in the row.

The data is public sporting results read without logging in, at a polite pace. How you use and publish them is your responsibility, so check the source's terms for your use case.

Questions, a missing field or a source you need? Open an issue on this Actor: we reply within a day. If it saved you time, a short review helps others find it.

Privacy

The data is about professional players' public sporting results. Each run sends the developer anonymous feature-usage statistics (the options used, never the players you asked for); your Apify account id is replaced by a one-way hash.