Flashscore Tennis Scraper - Live Scores, Results & Set Scores
Pricing
from $2.19 / 1,000 match returneds
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
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-finalsand 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
scoreTextsuch as6-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:
- 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, andfeedAgeSecondssays 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. - 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.
- A cancelled match shows no sets won on Flashscore even when a few games were played. The games per set are kept;
player1Scoreandplayer2Scoreare 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
| Field | What it does |
|---|---|
days | Days 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. |
utcOffsetHours | Your time zone as hours from UTC (0 = UTC). Decides where a day starts, as on Flashscore in that time zone. startTime is always UTC. |
tours | atp, wta, challenger-men, challenger-women, itf-men, itf-women, teams-men, teams-women, other. Empty = all. |
matchTypes | singles, doubles, teams. Empty = all. |
matchStatuses | live, finished, scheduled, other (cancelled, interrupted, postponed...). Empty = all. |
players | Keep a match if one of these appears in a player's name, slug or doubles partner (partial, case-insensitive). |
tournaments | Keep a match if the tournament header contains one of these (partial, case-insensitive). |
includeRound | On (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. |
maxMatches | Maximum rows to return (default 200). Not used in monitoring mode. |
monitoringMode | Return only matches that changed since the row last returned for them. |
changeDetail | In 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). |
resetMonitoringState | Forget the remembered rows for this filter set, so everything counts as new. |
useProxy | On (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:
playerOrderisas-listed: player 1 is the upper name on Flashscore, not necessarily the winner. Usewinner(1 or 2) andwinnerName.player1Score/player2Scoreare sets won; for team ties (matchType: "teams",scoreUnit: "rubbers") they are rubbers won,setsis empty andplayer1SetsWonis null.player1Players/player2Playerslist both partners for doubles, null otherwise.statusCodeis Flashscore's own status number;statusTextis Flashscore's text for it;matchStatusis one ofscheduled,live,finished,retired,walkover,awarded,cancelled,interrupted,postponed,abandoned,delayed,awaiting-updates,to-finish(orended/unknownfor a status number Flashscore adds later).servingPlayer,servingPlayerName,currentGamePlayer1PointsandcurrentGamePlayer2Pointsare 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) ornot-requested(includeRoundoff).infois Flashscore's note on the match, such asPlayed on clay.orChange 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:
status | Meaning |
|---|---|
no-results | Flashscore lists no matches for the day(s) asked for. |
no-filter-match | Matches were read, none fit your filters. |
no-change | Monitoring: no match changed since its last returned row. |
not-returned | More matches fit than maxMatches; the row says how many. |
budget-reached | The run hit its maximum total charge; the row says how many matches were not returned. |
day-out-of-range | Flashscore did not return the day (outside its 7-back / 7-ahead window). |
blocked | Flashscore refused the request even after retrying. |
unreadable | Flashscore's answer could not be read. Nothing is guessed. |
invalid-input | The 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"]indays, 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. Keepfinishedin 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. maxMatchesis 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.