Flashscore Tennis Scraper — Live Scores, Results & Stats
Pricing
$0.50 / 1,000 per match returneds
Flashscore Tennis Scraper — Live Scores, Results & Stats
Scrape every tennis match on Flashscore for any day in its 9-day window — ATP, WTA, Challenger and ITF, singles and doubles — with set-by-set scores, tiebreaks, winner, live game state, players, country, surface, and optional full match statistics. No API key.
Pricing
$0.50 / 1,000 per match returneds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
🎾 Flashscore Tennis Scraper — live scores, results, fixtures & match statistics
Every tennis match Flashscore publishes, for any day in its 9-day window, as one clean row: ATP, WTA, Challenger and ITF, singles and doubles, with the set-by-set score, tiebreaks, the winner, the live game state, both players, their countries, the tournament, the surface — and, if you want it, the full match statistics sheet.
No API key. No login. No browser. A full day of world tennis comes back in about 4 seconds.
📊 What you get, measured — not estimated
Every number below was measured, not guessed. The parser was validated offline against real captured bytes on 2026-09-02: four live day feeds (offsets −2, −1, 0, +1), 1,249 match records → 1,236 unique matches, and 0 integrity failures.
| Measurement | Result |
|---|---|
| Matches parsed in the validation sample | 1,236 unique across 4 days |
| Base fields per match | 51 — 33 populate on 100% of rows |
| Fields per row with statistics on | 120 (measured on a live Apify run) |
| Tournament headers decoded | 84 / 84 (tour, name, country, surface, qualification stage) |
| Winner + set-by-set score on finished matches (n = 566) | 97% |
| Live game points + who is serving on live matches (n = 12) | 100% |
| Both partners + partner countries on doubles (n = 359) | 100% |
| Statistics sheets returned for finished matches (n = 25 sampled) | 24 — 2,452 stat rows, ~102 per match |
| Statistics columns populated when a sheet exists | 68 / 68 at 100% |
| Full unfiltered live run, 5 days (−3 … +1) | 1,340 matches in 4.1 s |
Tours in that sample: ITF Men 454 · ITF Women 397 · Challenger Men 195 · WTA 112 · ATP 78. Surfaces: hard 687 · clay 549.
🎯 What does this actor do?
It reads Flashscore's own live-score feed — the same feed the website's scoreboard is drawn from — and turns it into a flat dataset you can put straight into a model, a spreadsheet or a database.
- 🏆 Every tour, one row shape. Grand Slam and ITF M15 come back identically structured.
- 🗓️ Any day Flashscore serves: 7 days of results back, today, and tomorrow's fixtures.
- 🎾 Set-by-set scores with tiebreak points —
7-6(5), 5-7, 4-6, 6-2, 6-1, plus a structuredsetsarray so you never have to parse a string. - 🔴 Live matches carry the live state: current game points for both players and who is serving.
- 👥 Doubles handled properly — both partners and both partner countries on each side, not a
mangled
"A./B."string. - 📈 Optional full statistics: aces, double faults, 1st/2nd serve percentages and points won, break points saved and converted, average 1st/2nd serve speed, winners, unforced errors, net points, service / return / total points and games won, distance covered — for the match and for every individual set.
- 🔗 Stable public URLs for the match, the tournament and both players.
- 🌍 Timezone-aware day boundaries, so "yesterday" means yesterday where your users are.
🚫 What it deliberately does not do
One site, one job. These are different row shapes and belong in different actors, and saying so is more useful than shipping half of each:
- Head-to-head history. Flashscore's H2H feed measured 120–170 KB per match and its rows are past matches between two players — a different product, and pulling it per match would multiply your bill for data most callers do not want.
- Player rankings. A ranking row is a player, not a match.
- Point-by-point. The point-by-point feed slug returns a literal
0body on this endpoint (measured), so no honest actor can claim it from here today. - Odds. Flashscore ships bookmaker affiliate blocks in the feed; they are stripped, not sold.
🚀 Quick start
{"daysBack": 1, // yesterday + today"includeTomorrow": true, // + tomorrow's fixtures"includeStats": false,"maxItems": 300}
Yesterday's ATP + WTA results with full statistics:
{"daysBack": 1,"includeTomorrow": false,"tours": ["ATP", "WTA"],"matchStatus": "finished","includeStats": true,"maxItems": 0 // 0 = every match that matches}
One tournament, the whole week:
{"daysBack": 7,"tournamentQuery": ["US Open"],"includeStats": true,"maxItems": 0}
Everything a player played this week:
{ "daysBack": 7, "playerQuery": ["Djokovic"], "includeStats": true, "maxItems": 0 }
Live right now:
{ "daysBack": 0, "includeTomorrow": false, "matchStatus": "live", "maxItems": 0 }
📤 Output
One row per match. Real row from a live run (statistics fields truncated):
{"matchId": "hbCCx5Fj","matchUrl": "https://www.flashscore.com/match/hbCCx5Fj/","startTime": "2026-08-30T23:15:00.000Z","startTimestamp": 1788131700,"endTime": "2026-08-31T03:55:45.000Z","date": "2026-08-30","dayOffset": -2,"tour": "ATP","competition": "ATP - Singles","discipline": "singles","gender": "men","tournament": "US Open","tournamentCountry": "USA","tournamentStage": null,"surface": "hard","tournamentUrl": "https://www.flashscore.com/tennis/atp-singles/us-open/","status": "finished","statusCode": 3,"endedEarly": false,"winner": "home","winnerName": "Navone M.","note": "Playing under a closed roof.","homeName": "Navone M.","awayName": "Djokovic N.","homeCountry": "Argentina","awayCountry": "Serbia","homeCode": "NAV","awayCode": "DJO","homePlayerUrl": "https://www.flashscore.com/player/navone-mariano/YoPUeL3o/","awayPlayerUrl": "https://www.flashscore.com/player/djokovic-novak/AZg49Et9/","homeSets": 3,"awaySets": 2,"setsScore": "3-2","setsString": "7-6(5), 5-7, 4-6, 6-2, 6-1","sets": [{ "set": 1, "home": 7, "away": 6, "homeTiebreak": 7, "awayTiebreak": 5 },{ "set": 2, "home": 5, "away": 7, "homeTiebreak": null, "awayTiebreak": null }],"homeGamePoints": null,"awayGamePoints": null,"serving": null,"acesHome": 9, "acesAway": 10,"doubleFaultsHome": 8, "doubleFaultsAway": 10,"firstServePctHome": 63, "firstServePctAway": 55,"breakPointsSavedHome": 8, "breakPointsSavedHomeOf": 12,"avgFirstServeSpeedHome": 179, "avgFirstServeSpeedAway": 183,"winnersHome": 36, "winnersAway": 46,"unforcedErrorsHome": 34, "unforcedErrorsAway": 70,"distanceCoveredMHome": 3874, "distanceCoveredMAway": 3300,"statistics": [{ "scope": "Match", "group": "Service", "stat": "Aces", "home": "9", "away": "10","homeValue": 9, "awayValue": 10 },{ "scope": "Set 1", "group": "Service", "stat": "1st serve percentage", "home": "46%","away": "54%", "homeValue": 46, "awayValue": 54 }],"scrapedAt": "2026-09-02T04:30:00.000Z"}
Field notes
statusisscheduled·live·finished.statusCodeis Flashscore's own finer code, passed through raw.endedEarlyistruewhen a match finished on a code other than the normal one — a retirement, walkover or abandonment. Those rows keep whatever score was reached, andwinnerisnullwhen no result was declared.setsis structured;setsStringis the human string.homeTiebreak/awayTiebreakare the tiebreak points for that set, present only when a tiebreak was played.servingmaps Flashscore's serve indicator tohome/awayon live matches.- Every percentage stat that ships as
X% (won/total)also gets…Ofcolumns with the denominator, so you can re-derive rates yourself instead of trusting a rounded percentage.
💵 Pricing
| Event | Price | When it fires |
|---|---|---|
| Per match returned | $0.0005 | Once per match written to your dataset |
That is half the cheapest per-match price in this category (measured against the live store on 2026-09-02), and the statistics sheet is included in the same charge — there is no separate per-statistics fee. 1,000 matches with full statistics = $0.50.
Matches removed by your filters are never charged, and billing is budget-aware: rows are delivered and charged in the same call, so if you set a spend cap the run stops cleanly instead of handing you rows you already paid past.
❓ FAQ
How far back can I go? Seven days. Measured on 2026-09-02: day offsets −7 through +1 return data; −8 and older return an empty body, and +2 through +7 return a valid but empty response — Flashscore simply does not publish tennis further out. Ask for a date outside that window and the actor logs a warning and skips it rather than pretending it found nothing.
Do I need a proxy? No. The feed answered HTTP 200 from a home IP, from Apify's own network, from Apify datacenter proxies and from Apify residential proxies when this actor was built. A proxy option is there if you want to spread very large sweeps across IPs.
Does it need an API key or a Flashscore account? No. The feed is the same public one the website's own scoreboard reads.
How fast is it? A full unfiltered 5-day sweep returned 1,340 matches in 4.1 seconds. With statistics on, each match costs one extra request, run 8 at a time by default.
How many matches is a normal day?
Roughly 500–600 across all tours — the sample day carried 571 matches in 66 tournament sections.
That is why maxItems defaults to 300; set it to 0 for everything.
Are doubles supported?
Yes, and properly: homePlayer1 / homePlayer2, awayPlayer1 / awayPlayer2 and both partner
countries. 359 doubles matches in the validation sample, all four fields at 100%.
Are ITF and Challenger matches included? Yes — they are the bulk of the feed. In the validation sample ITF and Challenger were 1,046 of the 1,236 matches, versus 190 for ATP + WTA combined.
Can I get statistics for a match that has not finished? Live matches usually publish a partial sheet. Scheduled matches have none, so the actor skips them automatically instead of burning a request per fixture.
Some finished matches have no statistics. Why?
Flashscore does not publish a statistics sheet for every event — small ITF draws in particular. In
the sample, 24 of 25 finished matches had one. The row still ships, with an empty statistics
array, so you can see the gap instead of silently missing rows.
What happens if Flashscore blocks a request? Blocked requests are counted, named in the run's status message, and never reported as "no matches". If nothing at all could be read, the run fails loudly with the transport reason rather than handing you an empty dataset that looks like a quiet day of tennis.
What if the feed's signing token changes? The actor pins the current token and, on a 401/403, re-reads it automatically from Flashscore's own public script before retrying.
Can I filter to just one tournament or one player?
Yes — tournamentQuery and playerQuery are case-insensitive substring matches. Flashscore prints
names as Surname X., so search by surname.
Does it return odds? No. Bookmaker affiliate blocks are stripped from the feed and not sold on.
⚖️ Legal & fair use
This actor reads a publicly available feed with no login, no paywall and no credential of any kind. It fetches at a polite rate and does not attempt to defeat any access control.
https://global.flashscore.ninja/robots.txt returns 404 — that host publishes no robots policy.
https://www.flashscore.com/robots.txt (checked 2026-09-02) states for the generic crawler:
User-agent: *Disallow: /standings/Disallow: /draw/Disallow: /newsfeed/Disallow: */x/js/browsercompatibility*.js
None of those paths are requested by this actor.
Sports facts — who played, what the score was — are not themselves copyrightable in most jurisdictions, but the compilation, the site's terms of service and your own jurisdiction are your responsibility. Use the output for analysis, modelling and research; do not republish Flashscore's compilation wholesale. This actor is not affiliated with or endorsed by Flashscore or Livesport s.r.o.