Flashscore Tennis Scraper & API | ATP, WTA Live Scores, Odds avatar

Flashscore Tennis Scraper & API | ATP, WTA Live Scores, Odds

Pricing

from $1.39 / 1,000 matches

Go to Apify Store
Flashscore Tennis Scraper & API | ATP, WTA Live Scores, Odds

Flashscore Tennis Scraper & API | ATP, WTA Live Scores, Odds

Real-time tennis API and scraper for Flashscore: ATP and WTA live scores, tiebreaks, statistics and bookmaker odds. Challenger, ITF, singles and doubles. 54 fields per match, plus point by point and head-to-head. Past seasons too.

Pricing

from $1.39 / 1,000 matches

Rating

0.0

(0)

Developer

Zen Studio

Zen Studio

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

1

Monthly active users

5 days ago

Last modified

Share

Flashscore Tennis Scraper & API | ATP, WTA, ITF Live Scores, Stats, Odds

54 fields per match. Point by point. Season by season. Tiebreaks, player rankings and bookmaker odds.

From Zen Studio, creators of Tennis Abstract, Bet365 Sports Data and Bet365 Live Scores. Tennis analysis, historical match research and live score tracking from the same team.

Why choose this actor?

  • Get the match detail behind the final score. A 54-field match record includes set scores, tiebreak points, surface, round and player details. Add point-by-point scores with the server, game winner and break/set/match-point markers, plus serve and return statistics by match and set.
  • Build datasets across tournament seasons. Collect whole draws by tournament and year, including singles, doubles and junior categories. Keep players, seeds, rounds, winners and scores together. Available statistics and point histories depend on the tournament and season.
  • Compare opening and current bookmaker odds. Get prices for match winner, totals, handicaps, correct score and odd/even, with the best available price per selection in each chosen country market. Current match listings can also include ATP/WTA rankings and ranking points.

Explore tennis data

Try three matches with points, stats and odds

{
"dayOffsets": ["-1"],
"tours": ["atp", "wta"],
"matchStatuses": ["finished"],
"enrich": ["statistics", "points"],
"includeOdds": true,
"oddsMarkets": ["GB"],
"maxItems": 3
}

Open actor input and click Start. This collects up to 3 finished ATP/WTA matches from yesterday, with available statistics, point-by-point scores and GB bookmaker odds. If there were no matches, choose another recent day. Export JSON, CSV or Excel.

Optional match details and odds carry additional charges when delivered; see Pricing below. Fields depend on source coverage. For past draws, set tournaments and seasons, and use drawCategory to select the draw. Historical runs do not attach today's player rankings.

Zen Studio · Tennis & Sports Data
Flashscore Flashscore
You are here
Tennis Abstract Tennis Abstract
Player stats & Elo
Live Scores Live Scores
Quarters, sets & form
Sports Data Sports Data
Seasons & players
Bet365 Odds Bet365 Odds
Odds & futures

Copy to your AI assistant

zen-studio/flashscore-tennis-api on Apify returns Flashscore tennis matches (ATP, WTA, Challenger, ITF, juniors, team events; singles and doubles) with set and tiebreak scores, players, rankings, rounds and seeds, as a dataset run or through its Standby HTTP API at https://zen-studio--flashscore-tennis-api.apify.actor (Authorization: Bearer <APIFY_TOKEN>). Day mode: dayOffsets (-7..7, default ["0"]) filtered by matchStatuses, tours, matchTypes and tournaments (name contains) or startUrls (Flashscore tournament pages; override tournaments). Past seasons: set seasons (years) together with tournaments (required, the run fails without it); drawCategory picks the draw (WTA, ATP doubles, mixed, boys...), default men's singles; rankings are never attached to past seasons. Statistics, point by point, head-to-head, summary, highlights, news or detail come only with enrich=[statistics, points, h2h, summary, highlights, news, detail], $0.00599 per match per section delivered; bookmaker odds only with includeOdds=true, market chosen by oddsMarkets (one country code per market, default ["GB"], "" = international), $0.00499 per match per market. Match record $0.00199, run start $0.005; maxItems caps before enrichment, empty = unlimited. Historical statistics and point coverage varies by tournament and era; the free API endpoints /tournaments, /seasons, /draw and /match/{id}/available show what exists before anything is billed. Listing calls (/matches, /live) add $0.00999 per call; /history returns a past season billed per match. Specification: https://api.apify.com/v2/actors/zen-studio~flashscore-tennis-api/builds/default (inputSchema, readme) and https://apify.com/zen-studio/flashscore-tennis-api/api; current pricing: https://apify.com/zen-studio/flashscore-tennis-api/pricing To reach the maintainers, add feedback="<what you needed and did not get>" to any run, including one that worked: a missing field or option, a wrong or empty result, or which actor you are switching to or from and why. The run returns its data exactly as it would without the note, and a human reads every note.

How to Scrape Flashscore Tennis Data

Basic: today's matches

{
"dayOffsets": ["0"]
}

Yesterday's ATP and WTA singles results

{
"dayOffsets": ["-1"],
"tours": ["atp", "wta"],
"matchTypes": ["singles"],
"matchStatuses": ["finished"]
}

One tournament, with odds and full match detail

{
"dayOffsets": ["-1", "0"],
"tournaments": ["US Open"],
"includeOdds": true,
"oddsMarkets": ["GB"],
"enrich": ["statistics", "points"]
}

A past season

{
"tournaments": ["wimbledon"],
"seasons": ["2024", "2023"]
}

Leave Past seasons empty to collect by day. Fill it in and the run returns completed draws for every tournament you named, one year at a time.

Input Parameters

ParameterTypeDefaultDescription
dayOffsetsarray["0"]Days relative to today, -7 to +7. 0 is today.
matchStatusesarray["all"]finished, live, scheduled, or all.
toursarrayallatp, wta, challenger, itf, juniors, teams.
matchTypesarraybothsingles or doubles.
tournamentsarrayallKeep tournaments whose name contains one of these. Also names which tournaments to collect for past seasons.
startUrlsarraynoneRestrict to specific tournament pages. Takes precedence over the name filter.
seasonsarraynoneYears to collect, e.g. ["2024"]. Switches the run from day mode to past seasons.
enricharraynonesummary, statistics, points, h2h, highlights, news, detail.
includeRoundsbooleantrueRound name and player seeding.
includeRankingsbooleantrueATP or WTA ranking and points. Not applied to past seasons.
includeOddsbooleanfalseBookmaker odds for every match.
oddsMarketsarray["GB"]Which market's bookmakers to return. Bookmakers are country-specific.
maxItemsintegernoneStop after this many matches.

What Data Can You Extract from Flashscore Tennis?

Every match record carries:

  • Identity and timing: match id, link, singles or doubles, start and end time, both as ISO and unix.
  • State: status, result type (finished, retired, walkover, awarded, canceled), current set, whether a tiebreak is in play, live game score, who is serving.
  • Result: winner, sets won, and per-set games with tiebreak points.
  • Players: name, short name, id, nationality, photo, seed, entry route, and singles plus doubles ranking with points and previous rank.
  • Tournament: name, category, country, surface, round, ids, and the Flashscore page.
  • Betting: which bookmakers are taking live bets, and full odds when requested.

Output Example

{
"match_id": "6k4MeS57",
"match_url": "https://www.flashscore.com/match/tennis/6k4MeS57/",
"match_type": "singles",
"match_date": "2026-09-11T19:15:00+00:00",
"match_end_timestamp": "2026-09-11T22:16:02+00:00",
"end_timestamp": 1789164962,
"last_period_timestamp": 1789164962,
"start_timestamp": 1789154100,
"match_status": "FINISHED",
"match_status_code": 3,
"result_type": "FINISHED",
"result_type_code": 3,
"current_set": null,
"in_tiebreak": false,
"match_note": null,
"walkover_note": null,
"winner": "home",
"sets_won_home": 3,
"sets_won_away": 0,
"sets": [
{
"set_number": 1,
"home": 6,
"away": 3,
"tiebreak_home": null,
"tiebreak_away": null,
"duration": null,
"duration_minutes": null
},
{
"set_number": 2,
"home": 7,
"away": 6,
"tiebreak_home": 9,
"tiebreak_away": 7,
"duration": null,
"duration_minutes": null
},
{
"set_number": 3,
"home": 7,
"away": 6,
"tiebreak_home": 8,
"tiebreak_away": 6,
"duration": null,
"duration_minutes": null
}
],
"current_game_score_home": null,
"current_game_score_away": null,
"current_server": null,
"home_players": [
{
"name": "Zverev A.",
"short_name": "ZVE",
"slug": "zverev-alexander",
"id": "dGbUhw9m",
"team_id": "vejGE316",
"nationality": "Germany",
"nationality_id": 81,
"photo_url": "https://static.flashscore.com/res/image/data/lU8NIJlC-2DqYxEbl.png",
"seed": 1,
"entry_status": null,
"ranking": 2,
"ranking_points": 7790,
"previous_ranking": 2,
"singles_ranking": 2,
"doubles_ranking": 109
}
],
"away_players": [
{
"name": "Khachanov K.",
"short_name": "KHA",
"slug": "khachanov-karen",
"id": "4bNPtZT5",
"team_id": "C8lOCsWI",
"nationality": "World",
"nationality_id": 8,
"photo_url": "https://static.flashscore.com/res/image/data/dI1pPHjC-hz8C9Mh1.png",
"seed": null,
"entry_status": null,
"ranking": 50,
"ranking_points": 1050,
"previous_ranking": 49,
"singles_ranking": 50,
"doubles_ranking": 142
}
],
"home_team": "Zverev A.",
"away_team": "Khachanov K.",
"tournament_name": "US Open (USA)",
"tournament_short_name": "US Open",
"tournament_qualifier": null,
"tournament_header": "ATP - SINGLES: US Open (USA), hard",
"tournament_id": "65k5lHxU",
"tournament_stage_id": "tQZGKy9k",
"tournament_season_id": "IJYwdktC",
"tournament_url": "https://www.flashscore.com/tennis/atp-singles/us-open/",
"tournament_logo_url": "https://static.flashscore.com/res/image/data/SS8DFXWI-l6sarjdt.png",
"category_name": "ATP - Singles",
"category_id": 9011,
"tour_id": 5724,
"stage_type_id": 5,
"country": "USA",
"surface": "hard",
"season": null,
"round_name": "Semi-finals",
"round_id": 2,
"seed_home": 1,
"seed_away": null,
"entry_status_home": null,
"entry_status_away": null,
"broadcasters": [],
"live_betting_bookmaker_ids": [],
"has_live_betting": null,
"play_dates": [],
"odds": [
{
"market": "GB",
"bookmakers": [
{
"id": 14,
"name": "10bet"
},
{
"id": 15,
"name": "William Hill"
},
{
"id": 16,
"name": "bet365"
},
"... 17 more"
],
"markets": [
{
"bookmaker_id": 983,
"bookmaker": "Parimatch.uk",
"bet_type": "HOME_AWAY",
"scope": "FIRST_SET",
"has_live_betting": false,
"selections": [
{
"selection": "home",
"side": "home",
"participant_id": "vejGE316",
"value": 1.36,
"opening": 1.36,
"active": true,
"handicap": null,
"handicap_type": null,
"score": null
},
{
"selection": "away",
"side": "away",
"participant_id": "C8lOCsWI",
"value": 2.88,
"opening": 2.88,
"active": true,
"handicap": null,
"handicap_type": null,
"score": null
}
]
},
"... 122 more"
],
"best": [
{
"bet_type": "ASIAN_HANDICAP",
"scope": "FIRST_SET",
"selection": "away",
"handicap": "-1.5",
"handicap_type": "SETS",
"value": 4.4,
"bookmaker": "Unibetuk",
"bookmaker_id": 625
},
{
"bet_type": "ASIAN_HANDICAP",
"scope": "FIRST_SET",
"selection": "away",
"handicap": "1.5",
"handicap_type": "SETS",
"value": 2.03,
"bookmaker": "Unibetuk",
"bookmaker_id": 625
},
"... 106 more"
]
},
"... 1 more market"
]
}

Selecting enrich adds statistics, points, head_to_head, summary, highlights, news and detail blocks to the same record.

Real-Time Tennis API: Query It Live Instead

Call the actor over HTTP and it answers directly instead of writing a dataset. The service stays warm between calls, so a listing you already asked for comes back without refetching.

Live data

EndpointMethodDescription
/matchesGETMatches for a day, with every filter the scraper has
/liveGETOnly matches in play right now
/match/{matchId}GETOne match, optionally enriched

Match detail

EndpointMethodDescription
/match/{matchId}/summaryGETSet durations, umpire, venue, total match time
/match/{matchId}/statsGETAces, serve percentages, break points, per set
/match/{matchId}/pointsGETPoint by point, with break, set and match points
/match/{matchId}/h2hGETHead-to-head history for both players
/match/{matchId}/oddsGETBookmaker odds with best price per selection

Discovery (free)

EndpointMethodDescription
/tournamentsGETFind a tournament by name
/seasonsGETEvery season it has, and what one season actually holds
/drawGETThe bracket: rounds, entrants, and who received a bye
/match/{matchId}/availableGETWhich detail a match has before you ask for it
/healthGETHealth check

Past seasons

EndpointMethodDescription
/historyGETA whole past season of matches. Billed per match returned.

Quick Start

Find a tournament, see its seasons, pull a year:

curl "https://zen-studio--flashscore-tennis-api.apify.actor/tournaments?q=wimbledon" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN"
curl "https://zen-studio--flashscore-tennis-api.apify.actor/seasons?tournament=wimbledon&season=2013" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN"
curl "https://zen-studio--flashscore-tennis-api.apify.actor/history?tournament=wimbledon&season=2013&round=Final" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN"

Today's ATP matches with odds:

curl "https://zen-studio--flashscore-tennis-api.apify.actor/matches?tour=atp&odds=true&oddsMarkets=GB" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN"

Response Format

{
"success": true,
"count": 42,
"total": 130,
"matches": [ ]
}

count is what came back, total is how many matched before the page limit.

Error Codes

CodeMeaningWhat to do
400A parameter value is not validThe message names the parameter and the accepted values
402Free plan allowance reachedUpgrade your Apify plan
404Match, tournament or season not foundFor older matches use /history, or pass day=
503Tennis data is temporarily unavailableRetry

Advanced Usage

Ready-made configurations for live score tracking, betting model inputs, historical backfill, and doubles analysis.

Live scoreboard, refreshed on a schedule

{
"dayOffsets": ["0"],
"matchStatuses": ["live"],
"includeRankings": true
}

Odds across several markets

{
"dayOffsets": ["0", "1"],
"includeOdds": true,
"oddsMarkets": ["GB", "DE", "US"]
}

Bookmakers are country-specific: most operate in exactly one market, so pick the markets you can actually bet in. Best prices are computed inside each market, because a price you cannot act on is not a comparison.

Historical backfill for one tournament

{
"tournaments": ["french open"],
"seasons": ["2024", "2023", "2022", "2021", "2020"]
}

Doubles only, with head-to-head

{
"dayOffsets": ["-1"],
"matchTypes": ["doubles"],
"enrich": ["h2h"]
}

Run it on a schedule to keep a dataset current: hourly during a Grand Slam, daily otherwise. Results flow into Google Sheets, Make, Zapier or your own webhook through Apify's integrations.

How to run the scraper and put it on a schedule (official Apify videos):

Pricing: Pay Per Event

You pay for what a run produces, not for time. Prices below are the standard rate; higher Apify plans get an automatic volume discount on every event.

Running it as a scraper

EventPer unitPer 1,000
Match in the dataset$0.00199$1.99
Bookmaker odds, per match per market$0.00499$4.99
Extra match detail, per match per section$0.00599$5.99
Run start$0.005one per run

A day of ATP and WTA singles, about 20 matches, costs around $0.05. The same day with odds is about $0.15.

Querying it as an API

EventPer unitPer 1,000
Listing call (/matches, /live)$0.00999one per call
Match returned by a listing$0.00199$1.99
Match returned from a past season (/history)$0.00199$1.99
Bookmaker odds, per match per market$0.00499$4.99
One match section (/match/{id}/...)$0.00599$5.99

A match costs the same whether you scrape it or request it, so neither mode is the cheap way to get the same data. The listing call fee applies to every call, including one that matches nothing, so filter server-side rather than polling speculatively.

Free: /tournaments, /seasons, /draw, /match/{id}/available and /health. Find what exists and what a season holds before you pay for any of it.

API usage also consumes Apify platform credit for the time the server is running, billed by Apify at your plan's rate and separate from the events above. It shuts down after a few idle minutes, so you pay for the time you actually use. If you query it only occasionally, running it as a scraper on a schedule is cheaper.

FAQ

What is Flashscore? Flashscore is a live-score service covering tennis alongside dozens of other sports, publishing scores, draws, statistics and bookmaker odds. This actor covers its tennis side: ATP, WTA, Challenger, ITF, juniors and team events, singles and doubles.

Does this include ATP and WTA? Yes, plus ATP Challenger, ITF men's and women's, junior events (boys and girls) and team competitions. Filter with tours.

Can I get live tennis scores in real time? Yes. A live match returns the current set, the game score, who is serving, and whether a tiebreak is in play. Note that during a tiebreak the game score holds tiebreak points rather than 0/15/30/40.

Does it return set-by-set scores and tiebreaks? Yes, both. Every set returns games for each player and the tiebreak points where one was played, so a 7-6 set shows the breaker as 9-7 rather than leaving it blank.

Can I get bookmaker odds for tennis matches? Yes, with includeOdds. You get match winner, over/under, handicap, correct score and odd/even, with opening and current prices, plus the best available price for every selection. Choose the market with oddsMarkets.

How far back does the historical tennis data go? It depends on the tournament and on which data you want, so the actor reports it rather than promising a single year. Grand Slams reach much further back than Challengers, and statistics and point-by-point start much later than results do. Ask /seasons?tournament=X&season=Y and it tells you exactly what that season holds before you commit to it.

Can I get a player's whole career with serve and return statistics? Not by player here: this actor collects by day and by tournament. Tennis Abstract Scraper returns every match of an ATP or WTA player's career with serve and return counts, Elo ratings by surface and shot-by-shot point by point, and joins to this one on player name.

Does it cover doubles as well as singles? Yes. A doubles record carries both players per side with their own ids, nationalities and doubles rankings, and the pair's shared seed at match level.

Can I get point-by-point data? Yes, via enrich: ["points"] or the /match/{id}/points endpoint. Break points, set points and match points are marked on the points where they occurred.

How do I get tennis data as an API instead of a dataset? Call the endpoints above. The actor runs as an HTTP server with 10 endpoints and answers requests directly; the base URL is in the examples.

Do I need to start the actor before calling it? No. The service answers each request directly and scales with demand; there is nothing to start, schedule or keep alive. You pay the per-request events and nothing else.

Do I need a proxy? No. There is no proxy option because none is needed, and adding one would only slow your runs down.

How do I export the data? JSON, CSV, Excel, XML or HTML from the run's Storage tab, or through the Apify API. JSON preserves the nested players, sets and odds structures; CSV flattens them.

Is it legal to scrape Flashscore tennis data? This actor extracts publicly available data only, nothing behind a login. You are responsible for complying with Flashscore's terms and with data protection law (GDPR, CCPA). Player names are personal data, so handle them accordingly.

Can I get football or basketball scores here? Not in this actor; it is tennis only. For other sports use Bet365 Live Scores for 13 sports, or Bet365 Sports Data for fixtures and history.

More Zen Studio scrapers for sports betting

🏟️ Sportsbook odds

🎯 Daily fantasy & player props

🎾 Live scores & match data

Support

  • Bugs: Issues tab
  • Features: Issues tab

Extracts publicly available data. Users must comply with Flashscore terms and data protection regulations (GDPR, CCPA).


Tennis match data from Flashscore: ATP, WTA, Challenger and ITF scores, statistics, point by point, rankings and bookmaker odds, as a dataset or a live API.