Tennis Point-by-Point Data - Every Game & Point avatar

Tennis Point-by-Point Data - Every Game & Point

Pricing

Pay per event

Go to Apify Store
Tennis Point-by-Point Data - Every Game & Point

Tennis Point-by-Point Data - Every Game & Point

Point-by-point data of ATP, WTA, Challenger and ITF matches: every game with its server, the points in order, breaks, and break, set and match points, plus the score, round and serve / return statistics. Any day back to 2012, any match, tournament or player. Works as an MCP tool for AI agents.

Pricing

Pay per event

Rating

0.0

(0)

Developer

CrawlPlant

CrawlPlant

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

an hour 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.

Every game and every point of a tennis match, for ATP, WTA, Challenger and ITF matches back to 2012: who served, the score after each point (15:0, 30:0, 40:15...), who won the game, whether serve was broken, and how many break, set and match points it had, tiebreaks point by point included. Ask for a day, a list of matches, a whole tournament edition or a player's matches. Each row is one match with its score, round, duration, both players' Elo before the match and serve / return statistics.

Why this one

  • Any day, not just today. Matches from the last week are read live; anything older comes from our tennis database, which keeps point-by-point for more than 400,000 matches and is updated every hour.
  • Whole tournaments in one run. Wimbledon 2024: 239 matches with qualifying, 237 of them point by point.
  • Pressure points counted for you. Each game says how many break, set and match points it had, and whether serve was broken: no parsing of score strings.
  • Tiebreaks point by point, in the same list as the games.
  • Statistics in the same row: aces, double faults, 1st serve %, points won on 1st and 2nd serve, break points saved and converted, for the match and each set.
  • Search the way you think: by day, by match URL, by tournament page, or by player name ("Alcaraz") with an opponent filter.
  • See it live. How many matches the database has point by point and today's ATP and WTA singles, from the same database your runs read: crawlplant.com/tennis-point-by-point.

What can you use it for?

  • Momentum and pressure models: break points saved, serve holds under pressure, comebacks within a set.
  • In-play betting research: how often a player holds after being 0:30 down, or wins a tiebreak after a mini-break.
  • Match visualisations and apps: game-by-game charts of any match.
  • Coaching and analysis: a player's serve games in finals or against one rival.

Quick start

  1. Click Try for free with the default input (20 of yesterday's finished ATP and WTA matches).
  2. Pick a Mode: a day range, match URLs, tournament pages or players.
  3. Download as JSON (the pointByPoint list keeps its structure) or open the table view.

Copy to your AI assistant

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

crawlplant/tennis-point-by-point on Apify: every game and point of tennis matches (ATP, WTA, Challenger, ITF, from 2012).
Input: mode (matches = days dateFrom..dateTo like "yesterday", "2024-07-14", "-3"; matchIds = Flashscore match ids or URLs;
tournaments = tournamentUrls + years; players = playerUrls names), tours (default atp, wta), matchType, status (default
finished), tournaments / players (name contains filters), includeStatistics, maxItems (default 20).
Row: one match (date, tournament, round, player1Name, player2Name, score, winnerName, durationMinutes, Elo, statistics)
with pointByPoint: [{ set, game, server, winner, breakOfServe, points: ["15:0", ...], breakPoints, setPoints, matchPoints,
gamesPlayer1, gamesPlayer2, tiebreak }]. Price: $1.00 per 1,000 matches + $2.00 per 1,000 with point-by-point (Free plan).

Ready-to-use examples

1. Yesterday's ATP and WTA matches

{ "mode": "matches", "dateFrom": "yesterday", "tours": ["atp", "wta"], "maxItems": 200 }

2. One match by its URL

{ "mode": "matchIds", "matchIds": ["https://www.flashscore.com/match/Sf0bExdB/"] }

3. A whole tournament edition

{ "mode": "tournaments", "tournamentUrls": ["https://www.flashscore.com/tennis/atp-singles/wimbledon/"], "years": [2024], "maxItems": 300 }

4. Every meeting of two rivals, point by point

{ "mode": "players", "playerUrls": ["Carlos Alcaraz"], "players": ["Djokovic"] }

5. A week of WTA matches

{ "mode": "matches", "dateFrom": "-7", "dateTo": "yesterday", "tours": ["wta"], "maxItems": 1000 }

6. Matches in play right now, points so far

{ "mode": "matches", "dateFrom": "today", "status": "live", "tours": [] }

7. A past Grand Slam fortnight

{ "mode": "matches", "dateFrom": "2025-05-25", "dateTo": "2025-06-08", "tournaments": ["French Open"], "maxItems": 1000 }

How to…

Download point-by-point data of a tennis match

Paste the match URL from flashscore.com (example 2): the 8 characters after /match/ also work.

Get point-by-point for a whole tournament

Use the tournament's Flashscore page and the year (example 3). Qualifying matches come with the main draw; tournamentStage is Qualification for them.

Find break points saved, set points and match points

Each game has breakPoints, setPoints and matchPoints (how many the game had) and breakOfServe (the server lost it). In the 2024 Wimbledon final Alcaraz broke Djokovic in the first game at his fifth break point (breakPoints: 5), and the last game is the tiebreak with matchPoints: 1.

Input options

OptionDefaultDescription
modematchesmatches (days), matchIds, tournaments, players
dateFrom / dateToyesterday / same daymatches mode: today, yesterday, 2024-07-14, -3
matchIds[]matchIds mode: match ids or URLs
tournamentUrls / years[] / latesttournaments mode: Flashscore tournament pages and editions
playerUrls[]players mode: names or Flashscore player URLs
toursatp, wtaAlso challenger-men, challenger-women, itf-men, itf-women, teams, other; empty = all
matchTypesinglessingles, doubles, all
statusfinishedfinished, live, all
tournaments, players[]Tournament / player name contains
includeStatisticstrueServe and return statistics (included in the match price)
maxItems20Maximum matches in total

Example output

The 2024 Wimbledon final (shortened: the first game and the tiebreak of 29 games, no statistics or player objects):

{
"recordType": "match",
"matchId": "Sf0bExdB",
"url": "https://www.flashscore.com/match/Sf0bExdB/",
"date": "2024-07-14",
"tour": "atp",
"tournament": "Wimbledon",
"round": "Final",
"surface": "grass",
"player1Name": "Alcaraz C.",
"player2Name": "Djokovic N.",
"player1Elo": 2538,
"player2Elo": 2564,
"winnerName": "Alcaraz C.",
"score": "6-2 6-2 7-6(4)",
"durationMinutes": 147,
"pointByPoint": [
{ "set": 1, "game": 1, "server": "player2", "winner": "player1", "breakOfServe": true, "gamesPlayer1": 1, "gamesPlayer2": 0,
"points": ["15:0", "15:15", "30:15", "30:30", "30:40", "40:40", "A:40", "40:40", "40:A", "40:40", "A:40", "40:40", "40:A",
"40:40", "A:40", "40:40", "A:40", "40:40", "A:40"], "breakPoints": 5, "setPoints": 0, "matchPoints": 0 },
{ "set": 3, "game": 13, "tiebreak": true, "server": "player2", "winner": "player1", "breakOfServe": false,
"gamesPlayer1": 7, "gamesPlayer2": 6, "points": ["0:1", "1:1", "2:1", "3:1", "3:2", "3:3", "4:3", "5:3", "5:4", "6:4", "7:4"],
"breakPoints": 0, "setPoints": 0, "matchPoints": 1 }
],
"source": "live"
}

Output fields

FieldDescription
matchId, url, date, startTimeFlashscore's match id and page, day (UTC) and start time
tour, tournament, tournamentStage, round, surfaceWhere and when in the draw
player1Name, player2Name, player1, player2Both sides with Flashscore ids, URLs and countries
score, sets, winnerName, durationMinutesResult and length
player1Elo, player2Elo, player1EloWinProbabilityElo before the match
statisticsServe and return statistics for the match and each set
pointByPoint[]One entry per game: set, game, server, winner, breakOfServe, gamesPlayer1 / gamesPlayer2 after it, points (the game score after each point, player1:player2), breakPoints, setPoints, matchPoints; a tiebreak has tiebreak: true and the tiebreak score after each point
scrapedAt, sourceWhen the run read it; cache = our tennis database, live = read from Flashscore in the run

Pricing

Pay per result: platform usage is included. A match row, plus point-by-point when the match has it.

EventNo discount (Free plan)Bronze (Starter)Silver (Scale)Gold (Business)
Match (per 1,000)$1.00$0.90$0.80$0.70
Point-by-point, per match that has it (per 1,000)$2.00$1.80$1.60$1.40
Actor start (per run)$0.00005$0.00005$0.00005$0.00005
Example on the Free planMatchesCost
Default run: 20 of yesterday's matches20~$0.06
One match1~$0.003
Wimbledon 2024, every match with qualifying239~$0.71
A week of WTA tour matches (2026-09-24 to 2026-10-01)88~$0.26
Roland Garros 2025, men's and women's singles254~$0.76

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

Reliability

  • Matches older than a week come from our tennis database (updated every hour), so a big historical run doesn't depend on thousands of live requests.
  • Each live request that fails is retried; a match whose point-by-point still can't be read keeps every other field and is not charged for point-by-point.
  • The run stops starting new requests shortly before its time limit and saves what it has.

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-point-by-point').call({ mode: 'matchIds', matchIds: ['Sf0bExdB'] });
const [match] = (await client.dataset(run.defaultDatasetId).listItems()).items;
console.log(match.pointByPoint.filter((g) => g.breakOfServe).map((g) => `set ${g.set} game ${g.game}`));

Python:

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawlplant/tennis-point-by-point").call(run_input={"dateFrom": "yesterday", "maxItems": 100})
for m in client.dataset(run["defaultDatasetId"]).iterate_items():
breaks = sum(g["breakOfServe"] for g in m.get("pointByPoint", []))
print(m["player1Name"], m["player2Name"], m["score"], breaks, "breaks")

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-point-by-point

Try "how many break points did Alcaraz save in the 2024 Wimbledon final?".

More tennis data

FAQ

How far back does point-by-point go?

To 2012 for ATP and WTA matches; Flashscore has none before that. Recent seasons cover almost every tour-level match.

Is it live during a match?

Yes: status: "live" (example 6) returns the games and points played so far.

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.

Privacy

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