Flashscore Tennis Scraper - Live Scores, Odds, H2H & History avatar

Flashscore Tennis Scraper - Live Scores, Odds, H2H & History

Pricing

Pay per event

Go to Apify Store
Flashscore Tennis Scraper - Live Scores, Odds, H2H & History

Flashscore Tennis Scraper - Live Scores, Odds, H2H & History

ATP, WTA, Challenger and ITF tennis from Flashscore, live and back to 1990: scores, odds from ~20 bookmakers (fair probability, closing odds), H2H over every meeting, Elo per surface, form, player stats, draws with rounds, rankings of any week since 1973. 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

7 hours ago

Last modified

Categories

Share

Independent tool, not affiliated with, endorsed by or connected to Flashscore, Livesport, the ATP, the WTA, the ITF or any bookmaker. It reads the public match pages and feeds that flashscore.com shows to every visitor, and official ranking lists.

Every ATP, WTA, Challenger and ITF match, live or back to 1990, one row per match with everything joined: set-by-set score, live game score, odds from about 20 bookmakers with a link to each (best price, opening and closing odds, win probability without the bookmaker margin), head-to-head over every meeting, Elo ratings and the Elo win probability, each player's last 10 results, fatigue, ATP / WTA rank, the round, serve and return statistics and, on request, point-by-point. Separate modes give live scores now, a tournament's whole draw, a player's whole career, player profiles and statistics (per season, surface or opponent's rank), head-to-head of any two players, Elo lists and ATP / WTA rankings of any week (ATP back to 1973, WTA back to 2001).

Why this one

  • See it live. The Elo leaders of both tours, today's draw with each favourite by Elo and a career head-to-head, from the same database your runs read: crawlplant.com/flashscore-tennis.
  • One row per match, ready for a model. Result, odds, Elo, form, head-to-head, fatigue and statistics arrive in the same record, so there is nothing to join.
  • History, not just today. More than 900,000 matches from 1990 (ATP and WTA from 1990, Challenger from 2008, ITF from 2011), updated every hour. Ask for any past day, a player's whole career or any edition of a tournament with its rounds.
  • Elo for every player and surface. Ratings for 13,000+ players, overall and on hard, clay and grass, computed from every match since 1990. Each match row carries both players' Elo before the match and the Elo win probability, so you can compare it with the market's.
  • Odds you can use, not just numbers. For every match: the best price for each player and the bookmaker offering it, the average price, the opening price, the move since opening, the average bookmaker margin, and the fair win probability (margin removed). Before a match, the margin of the best prices combined shows when they form a sure bet (below 0). Finished matches keep their closing odds, the benchmark for testing a betting model.
  • Bookmakers of your country. Odds come from the bookmakers licensed where you are: about 20 in the UK (bet365, William Hill, Betfair, Sky Bet, Paddy Power, Ladbrokes, Betway, Unibet...), 7 in Germany, 6 in Poland, 3 in the US. Pick the country with one field. Each bookmaker row carries a link that opens the bookmaker.
  • Form as of the match, not as of today. Form, fatigue, head-to-head and Elo are taken from the matches before the match start, so a finished match never counts in its own numbers and historical rows stay honest for back-testing.
  • Player statistics in one call. Win-loss, titles, finals, tiebreaks, deciding sets, aces, 1st and 2nd serve points won, break points saved and converted, service and return games won, per season, surface, tour, or against top-10, top-50 and lower-ranked opponents.
  • Every tour, every day. On 2026-09-29 the default run returned 100 of the day's singles matches (ATP, WTA, Challenger) in 12 seconds: 95 with odds from up to 20 UK bookmakers, all 87 played matches with serve and return statistics, 95 with form and head-to-head (the other 5 were cancelled), all 100 with rankings.

What can you use it for?

  • Betting models and value betting: Elo, form, surface record, fatigue, rank and fair probability side by side; closing odds and results of past seasons to measure your edge.
  • Odds comparison: the best price per player across the bookmakers of a country, with links, for a comparison page or a Telegram / Discord bot.
  • Live score widgets and alerts: current set and game score, who serves, in-play odds.
  • Sports journalism and previews: career head-to-head, recent meetings, last 10 results, record against the top 10, rest days, ranking history.
  • Research datasets: 35 years of results, rankings of every week, serve and return statistics, point-by-point.
  • AI agents: "who is the favourite in Khachanov v Auger-Aliassime, what do Elo and the bookmakers say, and how rested are they?" answered from one record.

Quick start

  1. Click Try for free (or Start) with the default input: today's singles matches of every tour, ATP and WTA first, up to 100, with odds, head-to-head, form, Elo, statistics and rankings. About a minute; about $0.40 on the Free plan.
  2. Pick the day (dateFrom: today, tomorrow, yesterday, 2019-07-14, -3), the tours and the bookmakers' country, or another mode from the examples below.
  3. Download the table as CSV, Excel or JSON, or save the input as a task and schedule it.

Copy to your AI assistant

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

crawlplant/flashscore-tennis on Apify: tennis from Flashscore (ATP, WTA, Challenger, ITF; singles and doubles), live and
back to 1990. Input: mode:
- "matches" (default): matches of days dateFrom..dateTo (UTC; "today"/"tomorrow"/"yesterday"/"2019-07-14"/"-3"; any
past day, up to a week ahead);
- "live": in play now; "matchIds": ids or match URLs;
- "players": playerUrls (player names like "Jannik Sinner", or https://www.flashscore.com/player/<name>/<id>/) -> the
whole career, newest first;
- "tournaments": tournamentUrls (https://www.flashscore.com/tennis/atp-singles/wimbledon/) + years -> every match with
its round;
- "playerProfiles": playerUrls -> full name, birth date, country, photo, rank, Elo per surface;
- "playerStats": playerUrls + statsSplitBy (season | surface | tour | opponentRank | none) -> record and serve/return
statistics;
- "h2h": playerUrls in pairs ("Sinner", "Alcaraz") -> head-to-head with every meeting;
- "elo": eloTour (atp | wta) + eloSurface (all | hard | clay | grass | carpet) -> Elo list;
- "rankings": rankingLists atp|wta|atp-race|wta-race|atp-doubles|wta-doubles, rankingDate (YYYY-MM-DD; ATP from 1973,
WTA from 2001) or the latest.
Filters: tours (atp, wta, challenger-men, challenger-women, itf-men, itf-women, teams, other; [] = all), matchType
(singles default | doubles | all), status (all | scheduled | live | finished), tournaments / players (name contains),
surfaces (hard, clay, grass, carpet). Data: includeOdds (true), oddsCountry (GB default; DE, PL, US, AU...), oddsMarkets
(match-winner | all), includeH2H (true), includeStatistics (true), includePointByPoint (false), includeRankings (true),
sortBy (tour | time), maxItems (100).
Match record: matchId, url, date, startTime, tour, category, matchType, tournament, tournamentStage, round ("Final",
"Semi-finals", "1/8-finals", "Q1"...), tournamentCountry, surface, indoor, status (scheduled, live, finished, retired,
walkover, cancelled, postponed...), statusText, isLive, player1Name, player2Name, player1Rank, player2Rank, player1Form,
player2Form (last 10, newest first, "WLWWL..."), player1Elo, player2Elo, player1EloWinProbability, elo {player1, player2,
player1Surface, player2Surface, basis}, player1/player2 {name, playerId, url, country, players[], rank, rankingPoints},
winner ("player1"|"player2"), winnerName, setsPlayer1, setsPlayer2, score ("7-6(5) 3-6 6-2"), sets[], currentGame
{player1, player2, serving}, note, broadcasts, odds {bookmakerCount, player1Best, player1BestBookmaker, player2Best,
player2BestBookmaker, player1Average, player2Average, player1OpeningAverage, player2OpeningAverage, player1Probability,
player2Probability (margin removed), favourite, averageMarginPct, bestPricesMarginPct, player1MovePct, bookmakers[],
oddsUrl}, oddsMarkets[], headToHead {matches, player1Wins, player2Wins, surfaceMatches, surfacePlayer1Wins,
surfacePlayer2Wins, lastMeetingAt, lastWinner, recent[], source}, form {player1, player2: {last10, winPct,
surfaceWinPct, daysSinceLastMatch, matchesLast7Days, setsLast7Days, matchesLast14Days, setsLast14Days,
retiredLastMatch}}, statistics {match, sets[]}, pointByPoint[], durationMinutes.
Other records: ranking {list, rankingDate, rank, previousRank, rankChange, name, playerId, country, points,
officialId, birthDate}; player {playerId, name, fullName, country, birthDate, heightCm, plays, backhand, photoUrl, rank, elo, eloHard, eloClay,
eloGrass, eloPeak}; playerStats {playerName, splitBy, split, matches, wins, winPct, titles, acesPerMatch,
firstServeInPct, breakPointsSavedPct, returnGamesWonPct...}; h2h {player1Name, player2Name, matches, player1Wins,
player2Wins, surfaces[], meetings[]}; elo {eloRank, name, country, surface, rating, peak, matches}.

Modes

ModeWhat you getTypical run
matches (default)Every match of the days you pick, any past day or a week ahead: results, live and scheduled, with odds, H2H, Elo, form, stats100 matches in 6-12 s; 1,671 matches over 9 days in 5.5 min
liveMatches in play right now: set and game score, server, in-play oddsseconds
matchIdsSpecific matches by id or Flashscore URL, any dateseconds
playersA player's whole career (singles, doubles on request) and scheduled matches, newest firstDjokovic's 1,492 finished matches in 73 s
tournamentsEvery match of a tournament edition with its round (qualifying Q1-Q3 included), any yearWimbledon 2019: 239 matches in 11 s
playerProfilesOne row per player: full name, birth date, height, playing hand and backhand, country, photo, rank, Elo overall and per surfaceseconds
playerStatsA player's win-loss, titles, tiebreaks, serve and return statistics per season, surface, tour or opponent's rankseconds
h2hTwo players' head-to-head over their whole careers, per surface, with every meeting (exhibitions left out, like the official ATP/WTA count)seconds
eloThe Elo list of the men's or women's tour, overall or on one surfaceseconds
sackmannWhole seasons of played singles in the columns of Jeff Sackmann's atp_matches_YYYY.csv / wta_matches_YYYY.csv: winner and loser, rank at the time, age, score, round, minutes, serve statisticsATP 2025: 4,285 matches
rankingsATP / WTA singles, doubles and race rankings, one row per player; rankingDate for any past weekall 6 current lists, 11,056 rows, in 15 s

Ready-to-use examples

Paste one into the JSON tab of the input. Costs are for the Free plan.

1. Today's matches with odds, head-to-head, Elo and form (the default, ~$0.40)

{}

2. Tomorrow's ATP and WTA singles with UK bookmaker odds

{ "dateFrom": "tomorrow", "tours": ["atp", "wta"] }

3. Live tennis scores right now

{ "mode": "live", "includeH2H": false }

4. Live ATP and WTA matches with point-by-point

{ "mode": "live", "tours": ["atp", "wta"], "includePointByPoint": true }

5. Closing odds of yesterday's ATP and WTA matches, every market

{ "dateFrom": "yesterday", "tours": ["atp", "wta"], "status": "finished", "oddsMarkets": "all" }

6. Odds from German bookmakers

{ "tours": ["atp", "wta"], "oddsCountry": "DE" }

7. A past fortnight of ATP and WTA results with statistics (no odds, cheapest)

{ "dateFrom": "2024-06-01", "dateTo": "2024-06-14", "tours": ["atp", "wta"], "status": "finished", "includeOdds": false, "includeH2H": false, "maxItems": 2000 }

8. One tournament, the last three days and tomorrow

{ "dateFrom": "-3", "dateTo": "+1", "tournaments": ["Beijing"] }

9. Wimbledon 2019, every singles match with its round

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

10. A player's whole career, finished singles matches

{ "mode": "players", "playerUrls": ["Novak Djokovic"], "status": "finished", "includeOdds": false, "includeH2H": false, "maxItems": 2000 }

11. Player profiles with Elo per surface

{ "mode": "playerProfiles", "playerUrls": ["Jannik Sinner", "Novak Djokovic", "Iga Swiatek"] }

12. A player's serve and return statistics per season

{ "mode": "playerStats", "playerUrls": ["Jannik Sinner"], "statsSplitBy": "season" }

13. Record against top-10, top-50 and lower-ranked opponents

{ "mode": "playerStats", "playerUrls": ["https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/"], "statsSplitBy": "opponentRank" }

14. Head-to-heads of two pairs of players, every meeting

{ "mode": "h2h", "playerUrls": ["Sinner", "Alcaraz", "Sabalenka", "Swiatek"] }

15. Clay-court Elo ratings, top 100 men

{ "mode": "elo", "eloTour": "atp", "eloSurface": "clay" }

16. The ATP ranking of 1 January 2000

{ "mode": "rankings", "rankingLists": ["atp"], "rankingDate": "2000-01-01", "maxItems": 500 }

17. ATP and WTA rankings today, top 200 each

{ "mode": "rankings", "rankingLists": ["atp", "wta"], "maxItems": 400 }

18. The race rankings (season points)

{ "mode": "rankings", "rankingLists": ["atp-race", "wta-race"], "maxItems": 200 }

19. Specific matches by URL, with point-by-point

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

20. Clay-court ITF women's matches today

{ "tours": ["itf-women"], "surfaces": ["clay"], "includeOdds": false }

21. ATP and WTA doubles

{ "matchType": "doubles", "tours": ["atp", "wta"] }

22. Scheduled matches only, sorted by start time

{ "dateFrom": "today", "dateTo": "tomorrow", "status": "scheduled", "sortBy": "time", "maxItems": 300 }

23. The 2025 ATP season as a tennis_atp-style CSV (export the dataset as CSV)

{ "mode": "sackmann", "years": [2025], "tours": ["atp"], "maxItems": 5000 }

How to…

Find a specific tennis match

No id needed: give the day and a player's surname (or the tournament) and the row comes back with everything joined. { "dateFrom": "2024-07-14", "players": ["Djokovic"] } returns that day's Wimbledon final; dateFrom and dateTo can span weeks or years ("players": ["Sinner"] over 2025 gives each of his matches). Also: a Flashscore match URL in matchIds, all meetings of two players in h2h mode, or one player's matches in a tournament with tournaments mode and players.

Get today's tennis results with odds

Run the default input. Each finished match has its score, winner, closing odds per bookmaker and the fair probability the market gave each player. Filter with tours and status: "finished".

Scrape Flashscore tennis live scores

mode: "live" returns every match in play: score (sets), currentGame (points and who serves), statusText ("Set 2", "Set 3 - Tiebreak"), in-play odds and point-by-point with includePointByPoint. Schedule it every few minutes for a live board.

Download historical tennis results

Set dateFrom and dateTo to any past days (example 7), or ask for one player's career (example 10) or a tournament's editions (example 9). Every match since 1990 has its score, winner, surface and both players' Elo before the match; serve and return statistics come with ATP and WTA matches from 2012 (almost every one from 2020).

Replace Jeff Sackmann's tennis_atp and tennis_wta CSV files

mode: "sackmann" returns every played singles match of the seasons in years in the columns of his atp_matches_YYYY.csv / wta_matches_YYYY.csv, in his order, so code that reads those files by column name keeps working: tourney_id, tourney_name, surface, draw_size, tourney_level, tourney_date, winner_seed and winner_entry (Q, WC, LL, PR, from the official ATP and WTA tour draws), winner_name, winner_hand and winner_ht (from the ATP and WTA player profiles), winner_ioc, winner_age, loser_*, score ("7-6(5) 6-4", "RET", "W/O"), best_of, round (R128 ... F, Q1-Q3), minutes, the serve columns w_ace ... l_bpFaced and winner_rank / loser_rank with points from the ranking of that week (official ATP and WTA lists). Export the dataset as CSV (example 23). Use tours: ["challenger-men"] or ["itf-men"] for his qual_chall and futures files. Four extra columns close each row: match_id, tour, winner_elo and loser_elo (pre-match Elo). How it differs from his files: player ids are Flashscore ids (strings); qualifying rounds come in the same file (keep round values that don't start with "Q" for his main-draw file); draw_size is counted from the main-draw matches played; tourney_level uses G, M, F, D, A for tour level (WTA 1000 included in A), C for Challenger, S for ITF. A full ATP season (4,285 matches with qualifying, 2025) costs about $4.30 on the Free plan.

Get tennis Elo ratings

mode: "elo" lists the men's or women's tour by Elo, overall or on one surface, with each player's peak and number of rated matches. Match rows carry player1Elo, player2Elo and player1EloWinProbability (overall and surface Elo blended), rated before the match.

Tennis head-to-head of two players

mode: "h2h" with two player URLs gives every meeting of their careers, the wins of each, the split by surface and each meeting's round, score and Elo. In match rows, headToHead counts every meeting before that match.

Player statistics against top-10 opponents

mode: "playerStats" with statsSplitBy: "opponentRank" splits a career by the opponent's rank at the time (top 10, 11-50, 51-100, 101-250, 251+): matches, wins, win %, tiebreaks and deciding sets won, serve and return percentages. season, surface and tour split it the other ways.

Tournament draw results with rounds

mode: "tournaments" with a tournament URL and years returns every match of those editions with its round, from the first qualifying round (Q1) to the final. The latest edition includes its scheduled matches.

Historical ATP and WTA rankings

mode: "rankings" with rankingDate returns the official list of that week: rank, points, tournaments played, the player's birth date and Flashscore id. ATP lists go back to 1973, WTA lists to 2001.

Get tennis odds from UK bookmakers (or any country)

Set oddsCountry (GB, DE, PL, IT, ES, FR, US, AU, NG...). odds.bookmakers lists every bookmaker's price with its link; odds.player1Best / player2Best give the best price and who offers it. oddsMarkets: "all" adds set winner, total games and sets, handicaps and correct score.

Find value bets: fair probability and bookmaker margin

odds.player1Probability is the market's win probability with the margin removed (the average of each bookmaker's normalised prices); player1EloWinProbability is Elo's. Compare them with your model; odds.player1Best is the price to take. Before the match, odds.bestPricesMarginPct below 0 means the best prices of two bookmakers form a sure bet.

Download tennis match statistics and point-by-point

statistics.match and statistics.sets[] carry aces, double faults, 1st serve %, points won on 1st and 2nd serve, break points saved and converted, service and return games won, with the counts (player1Won, player1Total). includePointByPoint: true adds every game: server, winner, whether serve was broken, the points in order and how many break, set and match points it had.

Input options

FieldDefaultWhat it does
modematchesmatches, live, matchIds, players, tournaments, playerProfiles, playerStats, h2h, elo, rankings
dateFrom / dateTotoday / same dayDays in UTC: today, yesterday, tomorrow, 2019-07-14, -3, +1
matchIds[]Match ids or URLs (matchIds mode)
playerUrls[]Player names ("Jannik Sinner", "Swiatek") or page URLs (players, playerProfiles, playerStats, h2h; h2h takes them in pairs)
tournamentUrls / years[] / latestTournament URLs and editions (tournaments mode)
statsSplitByseasonseason, surface, tour, opponentRank, none (playerStats mode)
eloTour / eloSurfaceatp / allElo list (elo mode)
rankingLists / rankingDate["atp","wta"] / latestLists and week for rankings mode
toursallatp, wta, challenger-men, challenger-women, itf-men, itf-women, teams, other
matchTypesinglessingles, doubles, all
statusallscheduled, live, finished
tournaments, players[]Name contains (case-insensitive)
surfacesallhard, clay, grass, carpet
includeOdds / oddsCountry / oddsMarketstrue / GB / match-winnerBookmaker odds
includeH2HtrueHead-to-head, form, fatigue
includeStatisticstrueServe and return statistics
includePointByPointfalseEvery game and point
includeRankingstrueRank and points of each player (singles)
sortBytourtour (ATP, WTA, Challenger, ITF, then time) or time
maxItems100Maximum records, counted after the filters

Example output

One match (shortened: 2 of 19 bookmakers, 2 of 17 statistics):

{
"recordType": "match",
"matchId": "WdDDlcIl",
"url": "https://www.flashscore.com/match/WdDDlcIl/",
"date": "2026-09-29",
"startTime": "2026-09-29T02:10:00.000Z",
"tour": "atp",
"category": "ATP - Singles",
"tournament": "Tokyo",
"tournamentStage": "Qualification",
"round": "Q2",
"surface": "hard",
"status": "finished",
"player1Name": "Tsitsipas S.",
"player2Name": "Hijikata R.",
"player1Rank": 44,
"player2Rank": 82,
"player1Form": "WWWLWWWLWL",
"player2Form": "WLWLLWWLWW",
"player1Elo": 2088,
"player2Elo": 1976,
"player1EloWinProbability": 0.6427,
"winner": "player1",
"winnerName": "Tsitsipas S.",
"score": "6-4 6-3",
"durationMinutes": 67,
"odds": {
"country": "GB",
"bookmakerCount": 19,
"player1Best": 1.3, "player1BestBookmaker": "7BetUK",
"player2Best": 3.75, "player2BestBookmaker": "Skybet",
"player1Average": 1.28, "player2Average": 3.47,
"player1OpeningAverage": 1.34, "player2OpeningAverage": 3.06,
"player1Probability": 0.7298, "player2Probability": 0.2702,
"favourite": "player1",
"averageMarginPct": 6.77,
"bestPricesMarginPct": null,
"player1MovePct": -4.2,
"bookmakers": [
{ "bookmaker": "10bet", "player1": 1.29, "player2": 3.5, "player1Opening": 1.38, "player2Opening": 2.9,
"url": "https://www.flashscore.com/bookmaker/14/?from=odds-comparison&sport=2" },
{ "bookmaker": "7BetUK", "player1": 1.3, "player2": 3.4, "player1Opening": 1.3, "player2Opening": 3.1,
"url": "https://www.flashscore.com/bookmaker/895/?from=odds-comparison&sport=2" }
],
"oddsUrl": "https://www.flashscore.com/match/WdDDlcIl/#/odds-comparison/home-away/full-time"
},
"headToHead": { "matches": 2, "player1Wins": 2, "player2Wins": 0, "surfaceMatches": 2, "lastMeetingAt": "2023-10-07T04:40:00.000Z", "source": "database (every meeting)" },
"elo": { "player1": 2088, "player2": 1976, "player1Surface": 2003, "player2Surface": 1911, "basis": "pre-match" },
"form": {
"player1": { "last10": "WWWLWWWLWL", "winPct": 61.2, "surfaceWinPct": 55.1, "daysSinceLastMatch": 1,
"matchesLast7Days": 1, "setsLast7Days": 2, "matchesLast14Days": 3, "setsLast14Days": 7, "retiredLastMatch": false },
"player2": { "last10": "WLWLLWWLWW", "winPct": 55.1, "surfaceWinPct": 60.4, "daysSinceLastMatch": 1,
"matchesLast7Days": 3, "setsLast7Days": 6, "matchesLast14Days": 3, "setsLast14Days": 6, "retiredLastMatch": false }
},
"statistics": {
"match": {
"aces": { "player1": 6, "player2": 4 },
"firstServePointsWon": { "player1": 81, "player2": 69, "player1Won": 26, "player1Total": 32, "player2Won": 25, "player2Total": 36 }
}
},
"scrapedAt": "2026-09-29T20:31:06.488Z",
"source": "live"
}

Output fields

FieldMeaning
matchId, urlFlashscore's match id and page
date, startTimeDay (UTC) and start time (ISO)
tour, category, matchTypeatp, wta, challenger-men...; "ATP - Singles"; singles / doubles / team
tournament, tournamentStage, round"Beijing", "Qualification" (null = main draw), "Final" / "Semi-finals" / "1/8-finals" / "Q1"
surface, indoor, tournamentCountryhard / clay / grass / carpet, indoor court, host country
status, statusText, isLivescheduled, live, finished, retired, walkover, cancelled, postponed, interrupted...; "Set 2"
player1Name, player2Name, player1Rank, player2Rank, player1Form, player2FormFlat fields for tables
player1Elo, player2Elo, player1EloWinProbability, eloElo of both players before the match, overall and on the surface; the win probability from both
player1, player2name, playerId, url, country, players[] (both players of a doubles pair), rank, rankingPoints, rankingDate
winner, winnerName, setsPlayer1, setsPlayer2, score, sets[]Result; tiebreak points per set in sets[]
currentGameIn play: points of each player and who serves
noteFlashscore's note ("Interrupted due to rain.", "X - withdrawn.")
broadcastsTV channels and bookmaker live streams, with links
oddsMatch-winner odds per bookmaker and the consensus fields (see value bets)
oddsMarkets[]With oddsMarkets: "all": bookmaker, market (HOME_AWAY, OVER_UNDER, ASIAN_HANDICAP, CORRECT_SCORE, ODD_OR_EVEN), scope (FULL_TIME, FIRST_SET...), selection, line, lineType, odds, opening
headToHeadMeetings before this match, on all surfaces and this surface, the last 5; source says whether it counts every meeting
form.player1, form.player2Last 10, win % (up to 50 matches), surface form and win %, rest days, matches and sets in 7 / 14 days, retired last match
statisticsMatch and per-set serve / return statistics
pointByPoint[]Games with server, winner, break, points, break / set / match points
endTime, durationMinutesWhen a finished match ended and its length in minutes
scrapedAt, source, storeWhen it was read; live (read now) or cache (from the tennis database); flashscore

The other modes return their own record types (recordType): ranking, player, playerStats, h2h and elo, with the fields listed in Copy to your AI assistant; each has its own table view in the dataset.

"player1" is the player Flashscore lists first (its "home" side); tennis has no home side, so it carries no advantage.

How is Elo calculated?

The classic Elo model used for tennis: every player starts at 1500, each match moves both ratings by K × (result − expected result), and K shrinks as a player plays more matches (K = 250 / (matches + 5)^0.4), so new players settle quickly and established ones move slowly. There is one rating over all matches and one per surface; the win probability blends the two equally. Walkovers don't count; retirements count as played. Ratings are recomputed every night over every match since 1990, and a match row keeps the ratings both players had before it.

Alerts and scheduling

  • Morning preview: schedule example 2 daily at 06:00 UTC and send the dataset to Google Sheets, Slack or e-mail with an Apify integration.
  • Live board: schedule example 3 every 5 minutes; each run is a fresh snapshot of every match in play.
  • Weekly back-test data: example 5 on Mondays with dateFrom: "-7" and dateTo: "yesterday".
  • Weekly rankings: example 17 every Monday afternoon (the lists are published on Mondays).
  • Webhooks: add a webhook on "run succeeded" to push the dataset into your own system.

Run it through the API

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawlplant/flashscore-tennis').call({ dateFrom: 'tomorrow', tours: ['atp', 'wta'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const m of items) console.log(m.player1Name, m.player1Elo, m.odds?.player1Best, 'v', m.player2Name, m.player2Elo, m.odds?.player2Best);

Python:

from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("crawlplant/flashscore-tennis").call(run_input={"mode": "live"})
for m in client.dataset(run["defaultDatasetId"]).iterate_items():
print(m["player1Name"], m["score"], m["currentGame"], m["player2Name"])

Use with AI agents

Add the Actor as a tool through Apify's MCP server: https://mcp.apify.com?tools=crawlplant/flashscore-tennis. An agent can ask for one match (a day plus a surname, or matchIds), a player's profile, statistics or career by name, a head-to-head or an Elo list, and read the answer from flat fields with plain values (numbers, ISO dates), easy to quote in a preview or store for retrieval.

How much does it cost to scrape Flashscore tennis?

Pay per result: platform usage is included.

EventFree planStarterScaleBusiness and up
Match or ranking row (per 1,000)$1.00$0.90$0.80$0.70
Bookmaker odds, per match that has odds (per 1,000, on top of the row)$1.50$1.35$1.20$1.05
Head-to-head, form and fatigue, per match (per 1,000, on top of the row)$1.50$1.35$1.20$1.05
Point-by-point, per match (per 1,000, on top of the row)$1.00$0.90$0.80$0.70
Elo list row (per 1,000)$1.00$0.90$0.80$0.70
Player profile (per 1,000)$3.00$2.70$2.40$2.10
Player statistics row: one season, surface, tour or rank band (per 1,000)$5.00$4.50$4.00$3.50
Head-to-head of two players, with every meeting (per 1,000)$5.00$4.50$4.00$3.50
Actor start (per run)$0.00005$0.00005$0.00005$0.00005

Statistics, Elo, rounds, rankings, live scores and TV / stream links are included in the row price. Turn off what you don't need (includeOdds, includeH2H) and those events are not charged.

Example on the Free planRowsCost
Default run: 100 matches with odds, head-to-head and form100~$0.40
1,000 finished matches with statistics only1,000~$1.00
50 live matches with odds, form and point-by-point50~$0.25
ATP and WTA rankings, top 200 each400~$0.40
A player's career, 1,492 finished matches with statistics1,492~$1.49
A player's statistics per season (20 seasons)20~$0.10
Head-to-head of 10 pairs of players10~$0.05

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

Other tennis Actors on the Apify Store, Free-plan prices read from the Store on 2026-09-29:

ActorUsers (30 days)Price
extractify-labs/flashscore-tennis-matches875$1.00 / 1,000 matches + $0.00005 per run
crawlstone/tennis-scraper (SofaScore, Tennis Abstract)1,059$8.00 / 1,000 results
sourabhbgp/flashscore-tennis-scraper25$1.00 / 1,000 results, one mode (results, point-by-point, statistics, H2H or odds) per run
zen-studio/flashscore-tennis-api1$1.99 / 1,000 matches + $4.99 / 1,000 odds requests + $5.99 / 1,000 detail requests
memo23/flashscore-sofascore-tennis-scraper19$5.00 / 1,000 items + $15.00 / 1,000 match details + $5.00 / 1,000 H2H + $0.005 per run
This Actornew$1.00 / 1,000 matches + $1.50 odds + $1.50 head-to-head and form

Reliability

  • Each request that fails is retried and, when an address is refused, sent again through another route; a match whose odds or statistics still can't be read keeps every other field, with the missing part null.
  • The run always finishes: it stops starting new requests shortly before the time limit and saves what it has.
  • Every run writes a summary to the key-value store (OUTPUT): records saved, how many came from the tennis database and how many were read live, requests, warnings (filters that matched nothing, unknown ids) and the events charged.

Data sources and freshness

  • Live and upcoming matches, odds, in-play scores: read from Flashscore at the moment of the run.
  • The tennis database: every match Flashscore lists from 1990, kept up to date every hour (results, rounds, statistics, point-by-point), with Elo recomputed every night.
  • Rankings: the latest lists from Flashscore (singles, doubles, race), and the official weekly ATP (from 1973) and WTA (from 2001) singles lists for past weeks, updated every Monday.

Troubleshooting

  • Fewer matches than expected: matchType defaults to singles and maxItems to 100; filters combine (all must match). A day in UTC may start or end in the middle of your evening session.
  • No odds on a match: a few ITF and interrupted matches are not priced (10 of 129 ITF matches on 2026-09-29); the field is null and not charged. A different oddsCountry may have more bookmakers.
  • Form is empty: brand-new players or team ties (form and head-to-head are then null and not charged); doubles form is the pair's.
  • No Elo on a match: doubles, team ties and players with no rated singles match yet (a first match on the tour).
  • Player not found, or the wrong one: a name picks the best-known player whose names hold every word you wrote ("Alcaraz" is Carlos); the run's warnings name the others it matched. For one of them, paste their Flashscore page URL (/player/sinner-jannik/6HdC3z4H/).

FAQ

How much does it cost to scrape Flashscore tennis?

About $0.40 for the default run of 100 matches with odds and form; $1.00 per 1,000 matches for results and statistics alone. See the price table.

How far back does it go?

Matches: every match Flashscore lists from 1990 (ATP and WTA; Challenger from 2008, ITF from 2011). Serve and return statistics: ATP and WTA matches from 2012, almost every one from 2020. Rankings: ATP from 1973, WTA from 2001.

Which bookmakers are included?

The bookmakers Flashscore shows in the country you pick. For GB on 2026-09-29: bet365, 10bet, 7BetUK, Betano, Betfair, Betfred, BetMGM, BetUK, BetVictor, Betway, Coral, Ladbrokes, Midnite, Paddy Power, Parimatch, Sky Bet, SpreadEX, Talksport Bet, Unibet, William Hill.

Are the odds live?

For a match in play the odds are the bookmakers' in-play prices at the moment of the run; before the match they are pre-match prices; after it, the closing prices. Opening prices come with every row.

How is the win probability calculated?

From the odds: for each bookmaker, 1/odds of each player divided by the sum of both (this removes the margin); the average over the bookmakers is player1Probability. From Elo: see How is Elo calculated?.

Does it include doubles and team events?

Yes: matchType: "doubles" (both players of each pair) and tours: ["teams"] with matchType: "all" (Davis Cup, Billie Jean King Cup, Laver Cup ties).

The Actor reads public pages without logging in, at a polite pace. Match results, rankings and odds are factual data; how you use and publish them is your responsibility, so check the site's terms for your use case.

Limits

  • Up to 5 requests at a time to each Flashscore host; about 5 matches per second with odds, head-to-head and statistics (1,671 in 5.5 minutes on 2026-09-30). Rows from the tennis database without odds come much faster.
  • Up to 100 player URLs per run in the player modes.
  • Rankings are attached to singles players (ATP list for men's tours, WTA for women's); Elo to singles matches.

Privacy

The data is about professional players' public sporting results and profiles (names, countries, birth dates, photos, scores, rankings). No logins, no account data. Each run sends the developer anonymous feature-usage statistics (the mode and which options were used, never the players or matches you asked for); your Apify account id is replaced by a one-way hash on arrival.