Flashscore Tennis Scraper - Live Scores, Results & Set Scores avatar

Flashscore Tennis Scraper - Live Scores, Results & Set Scores

Pricing

from $2.19 / 1,000 match returneds

Go to Apify Store
Flashscore Tennis Scraper - Live Scores, Results & Set Scores

Flashscore Tennis Scraper - Live Scores, Results & Set Scores

For tennis bettors, analysts and score apps: ATP, WTA, Challenger and ITF matches with players, round, start time, set scores with tiebreaks, winner, server and live game score. 535 of 535 matches matched Flashscore's page in a 3-day check. Monitoring returns only matches that changed.

Pricing

from $2.19 / 1,000 match returneds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

For tennis bettors, data analysts and score-app builders: every ATP, WTA, Challenger and ITF match on Flashscore with players, tournament, round, start time, set-by-set games with tiebreaks, sets won, winner and match status, plus the server and the current game score while a match is live. In a check on 2026-09-21, 535 of 535 matches over 3 days matched Flashscore's own page field by field. Turn on monitoring and a schedule receives only the matches whose score or status changed since the last run.

Export as JSON, CSV or Excel.

What you get

One row per match, for any day from 7 days back to 7 days ahead:

  • Players: both sides as Flashscore shows them (Sinner J.), name slug, Flashscore player id and country; doubles pairs with each partner listed.
  • Tournament: name, full header (WTA - SINGLES: Seoul (South Korea), hard), tour (ATP, WTA, Challenger Men, Challenger Women, ITF Men, ITF Women, Teams), singles / doubles / team tie, surface, qualification flag, tournament page and id.
  • Round: Final, 1/16-finals and so on, read from the match page (Flashscore's daily feed does not carry it).
  • Score: sets won, games per set with tiebreak points, a readable scoreText such as 6-2 6(7)-7(9) 3-6, the winner.
  • Status: scheduled, live (with the set in play and whether it is a tiebreak), finished, retired, walkover, awarded, cancelled, interrupted, postponed and more, with Flashscore's own status text.
  • Live: who is serving and the points of the current game (15, 30, 40, A).

Between 2026-09-15 and 2026-09-20 Flashscore's daily tennis feed carried 194 to 376 matches a day.

How it matches Flashscore's page

The rows come from the same feed Flashscore's website reads, assembled the way the page assembles it:

  1. The daily feed can be minutes old. It is served from a cache (ages up to 6 minutes were measured on 2026-09-21), so the page applies Flashscore's recent-changes feed on top right after loading. This Actor does the same; without it, live matches were a game behind and one finished match still showed "Set 2". Every row says whether that step worked in liveUpdatesApplied. The cache also has copies of different ages; when the copy that answered is older than two minutes, the Actor asks again (up to twice) and keeps the freshest, and feedAgeSeconds says how old the daily feed behind the row was. If the copy is older than the recent-changes feed reaches back, a match that started or ended in between can still show its earlier state, exactly as Flashscore's page does right after loading; in monitoring mode such a step backwards is never returned as a change.
  2. Each day's feed also carries matches that belong to the day before or after. Flashscore's page does not show them on that day, and neither does this Actor: a match is returned under the day it starts on (in your time zone), and a team tie that runs over several days is returned once per run.
  3. A cancelled match shows no sets won on Flashscore even when a few games were played. The games per set are kept; player1Score and player2Score are null.

The check behind the numbers above: Flashscore's tennis page was opened in a browser on 2026-09-21 for three days, and at the same moment the daily feed and the recent-changes feed were read. Every match on the page (535) was compared on names, sets won, games and tiebreaks for sets 1 to 5, current points, the serve marker, the winner's bold name, the status text, the start time and the day it is listed on: 535 of 535 matched.

Input

FieldWhat it does
daysDays to read: today, yesterday, tomorrow, a number from -7 to 7, or YYYY-MM-DD. Empty = today. Days outside Flashscore's 15-day window are refused before anything is requested.
utcOffsetHoursYour time zone as hours from UTC (0 = UTC). Decides where a day starts, as on Flashscore in that time zone. startTime is always UTC.
toursatp, wta, challenger-men, challenger-women, itf-men, itf-women, teams-men, teams-women, other. Empty = all.
matchTypessingles, doubles, teams. Empty = all.
matchStatuseslive, finished, scheduled, other (cancelled, interrupted, postponed...). Empty = all.
playersKeep a match if one of these appears in a player's name, slug or doubles partner (partial, case-insensitive).
tournamentsKeep a match if the tournament header contains one of these (partial, case-insensitive).
includeRoundOn (default) = one small extra request per returned match to read the round from its page (only the first 32 KB are read). Off = faster, round is null.
maxMatchesMaximum rows to return (default 200). Not used in monitoring mode.
monitoringModeReturn only matches that changed since the row last returned for them.
changeDetailIn monitoring mode: status (any change of Flashscore's status - start, end, next set, tiebreak, break, medical timeout - or of the sets won), games (default, also every game and tiebreak point) or points (also every point and the server).
resetMonitoringStateForget the remembered rows for this filter set, so everything counts as new.
useProxyOn (default) = if Flashscore answers 401, 403, 429 or 503, retry through an Apify proxy. The feed answered from a plain Apify datacentre address when this Actor was built.

Example: today's live and finished WTA matches in Tokyo time.

{
"days": ["today"],
"utcOffsetHours": 9,
"tours": ["wta"],
"matchStatuses": ["live", "finished"]
}

Output

A live match returned by a monitoring run (change and the previous... fields appear only in monitoring mode):

{
"source": "flashscore.com",
"status": "ok",
"matchId": "SOlLdOBb",
"matchUrl": "https://www.flashscore.com/match/SOlLdOBb/",
"date": "2026-09-21",
"utcOffsetHours": 0,
"startTime": "2026-09-21T05:40:00.000Z",
"tournament": "Seoul (South Korea)",
"tournamentHeader": "WTA - SINGLES: Seoul (South Korea), hard",
"tournamentId": "Q3ZRxpBf",
"tournamentUrl": "https://www.flashscore.com/tennis/wta-singles/seoul/",
"category": "WTA - Singles",
"tour": "WTA",
"matchType": "singles",
"surface": "hard",
"isQualification": false,
"round": "1/16-finals",
"roundStatus": "ok",
"matchStatus": "live",
"statusText": "Set 2",
"statusCode": 18,
"isLive": true,
"isCompleted": false,
"currentSet": 2,
"isTiebreak": false,
"playerOrder": "as-listed",
"player1Name": "Rakhimova K.",
"player1Slug": "rakhimova-kamilla",
"player1Id": "boU2UKtN",
"player1Country": "Uzbekistan",
"player1Players": null,
"player2Name": "Kudermetova P.",
"player2Slug": "kudermetova-polina",
"player2Id": "8O9jYpK8",
"player2Country": "Uzbekistan",
"player2Players": null,
"winner": null,
"winnerName": null,
"scoreUnit": "sets",
"player1Score": 1,
"player2Score": 0,
"player1SetsWon": 1,
"player2SetsWon": 0,
"sets": [
{ "set": 1, "player1Games": 7, "player2Games": 6, "player1Tiebreak": 7, "player2Tiebreak": 4 },
{ "set": 2, "player1Games": 4, "player2Games": 4, "player1Tiebreak": null, "player2Tiebreak": null }
],
"scoreText": "7(7)-6(4) 4-4",
"servingPlayer": 1,
"servingPlayerName": "Rakhimova K.",
"currentGamePlayer1Points": "0",
"currentGamePlayer2Points": "0",
"info": null,
"liveUpdatesApplied": true,
"feedAgeSeconds": 41,
"change": "score-changed",
"previousMatchStatus": "live",
"previousScoreText": "7(7)-6(4) 3-3",
"previousPlayer1Score": 1,
"previousPlayer2Score": 0,
"previousReturnedAt": "2026-09-21T07:22:49.000Z",
"scrapedAt": "2026-09-21T07:27:49.000Z"
}

Notes on the columns:

  • playerOrder is as-listed: player 1 is the upper name on Flashscore, not necessarily the winner. Use winner (1 or 2) and winnerName.
  • player1Score / player2Score are sets won; for team ties (matchType: "teams", scoreUnit: "rubbers") they are rubbers won, sets is empty and player1SetsWon is null.
  • player1Players / player2Players list both partners for doubles, null otherwise.
  • statusCode is Flashscore's own status number; statusText is Flashscore's text for it; matchStatus is one of scheduled, live, finished, retired, walkover, awarded, cancelled, interrupted, postponed, abandoned, delayed, awaiting-updates, to-finish (or ended / unknown for a status number Flashscore adds later).
  • servingPlayer, servingPlayerName, currentGamePlayer1Points and currentGamePlayer2Points are filled only while a match is live or interrupted (Flashscore keeps showing the points where an interrupted match stopped).
  • roundStatus: ok, not-shown (the match page shows no round, as for Davis Cup rubbers), unreadable (the match page could not be read) or not-requested (includeRound off).
  • info is Flashscore's note on the match, such as Played on clay. or Change of nomination.
  • change (monitoring): "first-check" (not returned before for this filter set), "status-changed" or "score-changed".
  • Odds and TV listings are not included.

Rows that are not charged

When something is not returned, a row says why. These rows have no matchId and cost nothing:

statusMeaning
no-resultsFlashscore lists no matches for the day(s) asked for.
no-filter-matchMatches were read, none fit your filters.
no-changeMonitoring: no match changed since its last returned row.
not-returnedMore matches fit than maxMatches; the row says how many.
budget-reachedThe run hit its maximum total charge; the row says how many matches were not returned.
day-out-of-rangeFlashscore did not return the day (outside its 7-back / 7-ahead window).
blockedFlashscore refused the request even after retrying.
unreadableFlashscore's answer could not be read. Nothing is guessed.
invalid-inputThe input could not be used; nothing was requested.

Monitoring

Run the Actor on a schedule with monitoringMode on. The first run returns every match that fits your filters. Later runs compare each match with the row last returned for it and return only the ones that changed at your changeDetail level, with the previous score and status next to the new ones.

  • Every match compared is a check, also the first time a match is seen. A match that was already returned as finished (or cancelled) and has not changed is not charged a check.
  • A match is listed on the day it starts. For a schedule that runs across midnight, put ["yesterday", "today"] in days, or a late match that finishes after midnight drops off the list before its result is returned.
  • With matchStatuses: ["live"] a match leaves your filter when it ends, so its final result is not returned. Keep finished in the filter to receive results.
  • A match that looks older than the row already returned for it (an older cached copy of Flashscore's feed, or a score Flashscore corrected downwards) is not returned as a change.
  • Rows are remembered per filter set (tours, matchTypes, matchStatuses, players, tournaments, changeDetail) for 10 days after the match starts, so two schedules with different filters do not affect each other.
  • maxMatches is not used in monitoring mode, so no match is left out behind the limit.
  • A row is remembered only after it was delivered and charged. If a run hits its maximum total charge, the matches it could not return are not remembered as returned, so they still count as changed when they are compared again.
  • Do not put the same filter set in two schedules that can run at the same time: the remembered rows live in a key-value store without atomic updates, so this cannot be fully prevented.

Pricing

Pay per event:

  • $3.00 per 1,000 match rows, charged only for rows with status: "ok".
  • $0.30 per 1,000 match checks in monitoring mode.

Example: 30 matches you follow, checked every 5 minutes for 10 hours, is 3,600 checks, which is $1.08, plus $0.003 for each change row. Checking every match of a busy day (about 300) every minute would be 432,000 checks a day, so use filters for frequent schedules.

Notes

  • Unofficial. Not affiliated with Flashscore or Livesport. Data is what Flashscore shows publicly and can change or be corrected by Flashscore.
  • Only Flashscore's tennis pages and feeds that its robots.txt allows are read; draws, standings and news are not.
  • Requests are spaced out: a 0.4 s pause before each request, and at most 3 match pages in flight at once when reading rounds.