Flashscore Tennis Scraper & API: Live Scores, Stats, H2H & Odds
Pricing
from $1.50 / 1,000 matches
Flashscore Tennis Scraper & API: Live Scores, Stats, H2H & Odds
Flashscore tennis data API: fixtures, live scores and results for ATP, WTA, Challenger and ITF matches, with optional match stats, point-by-point, head-to-head (H2H) and betting odds. From $1.50 per 1,000 matches.
Pricing
from $1.50 / 1,000 matches
Rating
0.0
(0)
Developer
Devarq
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 hours ago
Last modified
Categories
Share
Flashscore tennis data: fixtures, live scores and results for ATP, WTA, Challenger and ITF matches, with optional full match statistics, point-by-point, head-to-head and betting odds. From $1.50 per 1,000 matches.
Tell it a date, a match or a player. It returns clean, ready-to-use match data as JSON, CSV or Excel. There's no account to create on any tennis site, nothing to install and no proxies to configure. Data comes from Flashscore.
Why use this Actor?
Everything in one run. Most tennis scrapers give you either a basic match list or one kind of detail. This one returns fixtures, live scores, results, match statistics, point-by-point, head-to-head, odds and player history from a single Actor, all in the same format.
You only pay for what you actually get.
- Stats on a match that hasn't started? Not charged.
- A match that fails to load? Not charged.
- Matches removed by your filters? Not charged.
- A typo in a player's name? The run explains what went wrong and charges no results.
The only fixed cost is the $0.002 run start fee, which Apify charges for every run.
Verified data, never guessed. Player rankings are the current ATP and WTA singles rankings (top 100), and odds are real bookmaker prices. Anything that can't be verified is left empty rather than filled with a guess.
Built for automation and AI agents. An empty input already returns today's matches. Dates can be written as "yesterday" or "+2", any Flashscore link works, and every run ends with a plain-English status message.
How it compares with other tennis Actors on the Store
| This Actor | Tennis Scraper (crawlstone) | Flashscore Tennis Matches (extractify-labs) | Tennis Abstract Scraper (ParseForge) | |
|---|---|---|---|---|
| Fixtures, live scores, results | ✅ | ✅ | ✅ | ❌ history only |
| ATP, WTA, Challenger, ITF | ✅ | ✅ | ✅ | ATP & WTA |
| Match statistics | ✅ whole match + each set | per period, in point-by-point mode | ❌ | ✅ serve & return |
| Point-by-point | ✅ | ✅ | ❌ | ❌ |
| Head-to-head & per-surface record | ✅ | ❌ | ❌ | ❌ |
| Betting odds | ✅ with opening odds & movement | ✅ | ❌ | ❌ |
| Player results & upcoming matches | ✅ | ✅ | ❌ | ✅ |
| Rounds, seeds, umpire, set durations | ✅ | partial | partial | partial |
| "Only what changed" monitoring | ✅ | ❌ | ❌ | ❌ |
| Data source | Flashscore | Sofascore + Tennis Abstract | Flashscore | Tennis Abstract |
| Price per 1,000 results | $1.50 (+$2 per add-on used) | $8 (at least 1 result charged per run) | $1 | $21 + $0.0035 per run |
Compared on 2 October 2026 using each Actor's public Store page. Other Actors may have changed since; check their pages for current details.
Quick start
- Click Try for free.
- Leave the input as it is, or pick a date and tours.
- Click Start. In about 10 seconds you'll have today's ATP and WTA matches in the Output tab, ready to download as JSON, CSV or Excel.
What can you do with it? (recipes)
Each recipe shows the input to use. Copy it into the JSON input tab, or send it through the API.
1. Today's matches (default)
{}
You get every ATP and WTA singles match today: scheduled, live and finished. If there are none today (for example in the December off-season), you get the nearest day's matches instead, and the status message tells you which day.
2. Yesterday's results with full statistics
{ "date": "yesterday", "tours": ["ATP", "WTA"], "status": ["finished"], "includeStats": true }
You get each finished match plus aces, double faults, serve percentages, break points and more, for the whole match and each set.
3. Tomorrow's matches with betting odds
{ "date": "tomorrow", "tours": ["ATP"], "includeOdds": true }
You get the schedule plus pre-match home/away odds (current, opening, and whether they've moved up or down).
4. A specific match, in full detail
{ "mode": "match", "matchIds": ["https://www.flashscore.com/match/ldWaJXYa/"], "includeH2H": true }
Paste any Flashscore match link or ID. You always get statistics and point-by-point; add includeH2H for the head-to-head record.
5. A player's recent results and upcoming matches
{ "mode": "player", "player": "Sinner", "maxItems": 50 }
Type a name ("Sinner", "Świątek" — accents optional) or paste a Flashscore player link. Matches come newest first, so upcoming matches are at the top. Add "status": ["scheduled"] for upcoming matches only.
6. A week of Challenger and ITF results
{ "dateFrom": "-7", "dateTo": "yesterday", "tours": ["Challenger", "ITF"], "maxItems": 0 }
maxItems: 0 means "no limit". Your Apify maximum charge per run still protects you. A full week like this is over 1,000 matches: it takes about 5 minutes and costs about $1.70.
7. Live score monitoring (only changes)
{ "date": "today", "status": ["live", "finished"], "onlyChanges": true }
Schedule this every 10–15 minutes. The first run returns everything; later runs return only matches whose score or status changed, so you only pay for updates.
What you get back
One row per match. A real example (De Minaur vs Navone, Beijing, 1 October 2026):
{"match_id": "ldWaJXYa","match_url": "https://www.flashscore.com/match/tennis/ldWaJXYa/","start_time_utc": "2026-10-01T03:10:00+00:00","match_status": "FINISHED","tour": "ATP","category": "singles","tournament_name": "Beijing","tournament_country": "China","surface": "hard","round_name": "Round of 32","home_player_names": "De Minaur A.","away_player_names": "Navone M.","score": "7-6 (7-4), 6-2","winner": "home","result_type": "normal","seeds": { "home": "5" },"duration_minutes": 115,"umpire": "Finke T."}
Each row also includes home_players and away_players (name, ID, country, ranking where available), sets (games and tiebreak points per set), and, while a match is live, current_game_score and current_server.
Add-ons (only when you switch them on)
includeStats adds stats: every statistic for the whole match (match) and for each set (set_1, set_2…). Each one has the original label plus parsed numbers:
"first_serve_percentage": { "home": { "raw": "59%", "pct": 59 }, "away": { "raw": "60%", "pct": 60 } },"break_points_converted": { "home": { "raw": "3/7", "won": 3, "total": 7 }, "away": { "raw": "1/10", "won": 1, "total": 10 } }
Included: aces, double faults, first and second serve won %, break points saved and converted, return points won, service and return games won, total points and games, and more.
includePointByPoint adds point_by_point: every game in every set, showing who served, who won, whether it was a break, and each point's score, with break, set and match points marked.
includeH2H adds h2h: overall wins for each player, the record per surface (clay, grass, hard), past meetings with scores, and each player's recent form.
includeOdds adds odds: the bookmaker, current home/away odds, opening odds and the direction of movement:
{ "bookmaker": { "name": "bet365" }, "home": { "value": "1.33", "opening": "1.29", "change": "up" }, "away": { "value": "3.4", "opening": "3.75", "change": "down" } }
Ready-made tables
In the Output tab you can switch between Matches (an overview), Stats (key statistics as columns) and a flat CSV/Excel view that opens cleanly in spreadsheets.
Pricing
Pay per result. No subscription and no proxy fees.
| You get | Price |
|---|---|
| Each run | $0.002 |
| Each match | $0.0015 ($1.50 per 1,000) |
| + statistics and/or point-by-point | $0.002 per match that has them |
| + head-to-head | $0.002 per match that has it |
| + odds | $0.002 per match that has them |
What typical jobs cost:
| Job | About |
|---|---|
| Today's ATP + WTA matches (~25) | $0.04 |
| 100 finished matches with full statistics | $0.35 |
| One match with stats, point-by-point and H2H | $0.008 |
| A player's last 50 matches | $0.08 |
| Monitoring live scores every 15 minutes for a day | about $0.20 + changed matches |
Apify's free plan includes $5 of credit every month, enough for about 125 daily match lists or 900 detailed single-match lookups.
Use it as an API
One HTTP request runs the scraper and returns the matches as JSON in the same response. Use your Apify API token (Console → Settings → API & Integrations):
curl -X POST "https://api.apify.com/v2/acts/devarq~tennis-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"date": "yesterday", "tours": ["ATP", "WTA"], "includeStats": true, "maxItems": 50}'
Or in Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("devarq/tennis-scraper").call(run_input={"date": "today", "includeOdds": True})matches = client.dataset(run["defaultDatasetId"]).list_items().items
Each call starts a short run, so expect a response in roughly 10–60 seconds depending on the add-ons, not milliseconds. For live tracking, schedule a run every few minutes with "onlyChanges": true and you'll only receive (and pay for) matches whose score or status changed.
Use with AI agents (MCP)
Add this Actor to Claude, ChatGPT, Cursor or any MCP client through the Apify MCP server, then just ask:
- "What ATP matches are on tomorrow, with odds?"
- "Get yesterday's WTA results with full statistics."
- "Show Carlos Alcaraz's last 20 matches and his record on clay."
- "Give me the point-by-point of this match: https://www.flashscore.com/match/ldWaJXYa/"
Agents don't need perfect input. Relative dates, names instead of IDs, any Flashscore link and common field aliases are all understood. If something can't be found, the run says so plainly and charges no results (only the $0.002 run start fee).
FAQ
Which matches are included? ATP, WTA, Challenger and ITF; singles by default, doubles with "matchType": "doubles". Grand Slams, Davis Cup and Billie Jean King Cup can be selected as tours too. Junior, wheelchair and exhibition matches appear as tour "Other" (select them with "tours": ["Other"]).
How far back and ahead can I go? 7 days back and 7 days ahead in date mode. Player mode returns a player's longer match history.
Are walkovers and retirements handled? Yes. Each has its own status (WALKOVER, RETIRED, CANCELLED, INTERRUPTED) and result_type. The finished status filter returns only matches that were actually played (including retirements); use cancelled for walkovers, cancellations and postponements.
What time zone is used? All times are UTC, and dates select UTC calendar days. A few matches starting right around midnight UTC may be listed on the neighbouring day.
How live are live scores? Usually within a few minutes of the real score.
Are rankings always filled in? Current ATP and WTA top-100 singles rankings are included. Lower-ranked players and Challenger/ITF players may have no ranking.
Are odds always available? Only when bookmakers offer them for that match. They're never made up. For finished matches you get the closing pre-match odds, which is useful for backtesting betting models.
What if something breaks? The Actor checks every run. If the data source stops returning valid data, the run fails clearly instead of giving you bad data, and no results are charged.
Is this an official Flashscore product? No. It's an independent tool, not affiliated with or endorsed by Flashscore. Every row links to its source page.
Found a bug or need a field? Open an issue on this page or email support@devarq.dev.
Settings reference
Modes
mode | What to provide | What you get |
|---|---|---|
matches (default) | a date or date range | all matching fixtures, live matches and results |
match | matchIds (IDs or Flashscore links) | those matches with stats and point-by-point |
player | player (name or Flashscore link) | that player's matches, newest first (upcoming matches on top) |
All inputs
| Field | Works in | Type | Default | Description |
|---|---|---|---|---|
mode | – | string | matches | matches, match or player |
date | matches | string | today | YYYY-MM-DD, today, yesterday, tomorrow, or -7 … +7 |
dateFrom, dateTo | matches | string | – | a date range (same formats), within 7 days of today |
tours | matches | list | ["ATP", "WTA"] | ATP, WTA, Challenger, ITF, ITF Men/Women, Challenger Men/Women, Grand Slam, Davis Cup, Billie Jean King Cup, Teams, Other |
matchType | matches | string | singles | singles or doubles |
status | matches, player | list | all | scheduled, live (incl. suspended), finished (played to the end or retired), cancelled (walkovers, cancellations, postponements) |
tournament | matches, player | string | – | only tournaments whose name contains this text |
player | player, matches | string | – | player mode: who to look up (name or Flashscore link). matches mode: optional filter on player name |
matchIds | match | list | – | match IDs or Flashscore links |
maxItems | all | integer | 200 | maximum matches returned; 0 = no limit |
includeStats | all | boolean | false | add match and per-set statistics (always on in match mode) |
includePointByPoint | all | boolean | false | add point-by-point (always on in match mode) |
includeH2H | all | boolean | false | add head-to-head and recent form |
includeOdds | all | boolean | false | add pre-match odds |
onlyChanges | all | boolean | false | on repeated runs with the same input, return only matches that changed |
Inputs that don't apply to the chosen mode are simply ignored.
Output fields
Always present
| Field | Example | Meaning |
|---|---|---|
match_id | ldWaJXYa | Flashscore match ID |
match_url | https://www.flashscore.com/match/tennis/ldWaJXYa/ | link to the match |
start_time_utc | 2026-10-01T03:10:00+00:00 | scheduled start, UTC |
match_status | FINISHED | SCHEDULED, LIVE, FINISHED, RETIRED, WALKOVER, CANCELLED, INTERRUPTED |
tour | ATP | ATP, WTA, Challenger, ITF, Teams or Other |
category | singles | singles or doubles |
tournament_name, tournament_country | Beijing, China | tournament and host country |
surface | hard | hard, clay, grass, hard (indoor)… |
round_name | Round of 32 | round, when known |
home_player_names, away_player_names | De Minaur A. | names as text (doubles: A / B) |
home_players, away_players | list | per player: name, ID, country, ranking (top 100), photo link |
score | 7-6 (7-4), 6-2 | score as text |
sets | list | per set: games for each side, tiebreak points, duration |
winner | home | home, away or empty |
result_type | normal | normal, retired, walkover, cancelled… |
seeds, entries | {"home": "5"} | seeds, and qualifier / lucky loser / wild card flags |
duration_minutes, umpire | 115, Finke T. | when available |
current_game_score, current_server | {"home": "30", "away": "15"}, home | live matches only |
source_url, scraped_at | – | source link and collection time (UTC) |
Only with add-ons: stats (includeStats), point_by_point (includePointByPoint), h2h (includeH2H), odds (includeOdds). If one of them couldn't be loaded for a match, the row still arrives with details_error, h2h_error or odds_error explaining why, and that add-on isn't charged.
Changelog
0.1 (October 2026): first release. Date, match and player modes; statistics, point-by-point, head-to-head, odds, rounds and rankings; change-only monitoring; Matches, Stats and CSV/Excel views.