# Flashscore Tennis Scraper: Results, Live Scores, Odds & Stats (`themineworks/flashscore-tennis-results-scraper`) Actor

Flashscore tennis matches for ATP, WTA, Challenger and ITF: live scores, results and fixtures with set and tiebreak scores, player rankings, match statistics, point by point, umpire, duration and bookmaker odds. Player match history by link. No login. Pay per match.

- **URL**: https://apify.com/themineworks/flashscore-tennis-results-scraper.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Sports, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 tennis matches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Flashscore Tennis Scraper: Results, Live Scores, Odds & Stats

[![200 tennis matches in 24 seconds: a recorded run returned 200 of the day's Flashscore tennis matches, with current ATP and WTA rankings, in 24 seconds](https://api.apify.com/v2/key-value-stores/cUXz95yxflDho41nn/records/flashscore-tennis-results-scraper-hero-fix0930.png)](https://console.apify.com/actors/otjnHtz1gOphjeQpQ/input)

From **The Mine Works**, makers of [Threads Scraper](https://apify.com/themineworks/threads-scraper) and [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder), with over 140,000 runs across 170+ public actors.

Collect tennis matches from Flashscore for ATP, WTA, Challenger, ITF, juniors and team events, singles and doubles, as one row per match: the score and every set with tiebreak points, the winner, the result type, both players with ids, countries, links and current rankings, the tournament and surface, and live game scores with who is serving. Switch on match statistics, point by point, durations and umpire, or bookmaker odds, and they arrive in the same row. It reads the same public data feeds the Flashscore pages load, so there is no browser, no login and no cookie.

### Why choose this actor?

- **200 matches in 24 seconds.** On 1 Oct 2026 a run with the default settings returned 200 of that day's 385 Flashscore matches, from ATP to ITF, finished, live and scheduled, with each singles player's current ranking, from 4 requests.
- **Statistics, point by point and odds in the same row.** In our 1 Oct test, all 10 finished ATP and WTA singles matches of the day before came back with 34 statistics columns, every game point by point, set durations and opening and current odds from 20 UK bookmakers. The options are included in the match price.
- **From $0.70 per 1,000 matches, plus a flat $0.005 per run.** Matches your filters leave out, duplicates, rows past `maxMatches`, players with no matches and the information row are never charged.

[![Run it on Apify](https://api.apify.com/v2/key-value-stores/cUXz95yxflDho41nn/records/button-run.png)](https://console.apify.com/actors/otjnHtz1gOphjeQpQ/input)

**Part of The Mine Works More tools family:** [Tennis Match & Player Data Scraper](https://apify.com/themineworks/tennis-match-data), [Google Hotels Prices Scraper](https://apify.com/themineworks/google-hotels-prices-scraper), [LandWatch Scraper](https://apify.com/themineworks/landwatch-land-for-sale-scraper).

### Try it in one minute

Paste this into the JSON tab of the input page and press Start. It returns 10 of yesterday's ATP and WTA matches in a few seconds.

```json
{
  "mode": "matchesByDay",
  "days": ["yesterday"],
  "tours": ["atp", "wta"],
  "maxMatches": 10
}
```

There are two ways in. For matches by day, give `days` as `today`, `yesterday`, `tomorrow`, an offset such as `-3` or `+2`, or a date such as `2026-09-28`, anywhere from 7 days back to 7 days ahead (UTC days). For a player's history, set `mode` to `playerResults` and give `players` as Flashscore player links (`https://www.flashscore.com/player/djokovic-novak/AZg49Et9/`) or just the slug and id (`sinner-jannik/6HdC3z4H`).

Apify's free plan includes $5 of credit every month, which covers about 4,990 matches at this actor's price.

#### Copy to your AI assistant

```
themineworks/flashscore-tennis-results-scraper on Apify. It collects tennis matches from Flashscore (ATP, WTA, Challenger, ITF, juniors, team events; singles and doubles) as one row per match with score, sets, winner, players, rankings, tournament and surface, plus optional statistics, point by point, durations and umpire, and bookmaker odds. Call ApifyClient("TOKEN").actor("themineworks/flashscore-tennis-results-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: nothing (defaults to today's matches). Optional: mode ("matchesByDay" default or "playerResults"), days (array: "today", "yesterday", "tomorrow", "-3", "+2" or "2026-09-28", within 7 days of today UTC; empty means today), players (array of Flashscore player links or slug/id, for playerResults), maxMatchesPerPlayer (default 40, up to 2000), statuses (finished, live, scheduled, cancelled, postponed, abandoned), tours (atp, wta, challenger, itf, juniors, teams, exhibition, other), matchTypes (singles, doubles), tournaments (name contains), includeRankings (default true), includeStatistics, includePointByPoint, includeSummary, includeOdds (all default false), oddsCountry (default "GB"), oddsMarkets (winner, over_under, handicap, correct_score, odd_even), maxMatches (default 200, up to 50000). Rows with a _type field are information rows, not matches. Full spec: GET https://api.apify.com/v2/acts/themineworks~flashscore-tennis-results-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations
```

### Key features

- **Two modes.** Matches by day (7 days back to 7 days ahead: results, live scores and the schedule), or a player's match history, newest first, up to 2,000 matches per player and 100 players per run.
- **22 fields on every match row**, including both players as objects with Flashscore id, slug, country, link, image and, for singles, the current ATP or WTA ranking, points and previous rank. Doubles rows carry both players of each pair.
- **4 detail options, each one extra request per match and included in the match price**: statistics (34 flat columns for the match plus a list per set), point by point (every game with server, break flag and point scores marked for break, set and match points), durations and umpire, and odds (opening and current, for the bookmakers Flashscore shows in the country you pick, in 5 markets).
- **Filters applied before you pay**: 6 statuses, 8 tour groups (ATP, WTA, Challenger, ITF, juniors, team events, exhibitions, other), singles or doubles, and tournament names.
- **Current rankings for about 3,800 players**: 2,290 ATP and 1,553 WTA on 1 Oct 2026, loaded with two requests per run.
- **Up to 50,000 matches per run.** A day on Flashscore held 385 matches on 1 Oct 2026 and 467 on 30 Sep.

### How to use it

#### Basic: yesterday's results

```json
{
  "days": ["yesterday"],
  "statuses": ["finished"],
  "maxMatches": 500
}
```

#### Several days, ATP and WTA singles only

```json
{
  "days": ["-3", "-2", "-1"],
  "tours": ["atp", "wta"],
  "matchTypes": ["singles"],
  "statuses": ["finished"],
  "includeStatistics": true,
  "maxMatches": 300
}
```

Days are UTC days. A match that starts late in the evening in the Americas can fall on the next UTC day.

#### A live scoreboard for one tournament

```json
{
  "days": ["today"],
  "statuses": ["live"],
  "tournaments": ["Beijing"]
}
```

Rows carry `current_game_home`, `current_game_away` and `serving` while a match is live. Schedule it every few minutes during play, for example with the cron `*/5 * * * *`. Each run pays the $0.005 start fee, so a run every 5 minutes for 10 hours is 120 runs, $0.60 in start fees plus the matches.

#### Tomorrow's schedule with match winner odds

```json
{
  "days": ["tomorrow"],
  "tours": ["atp", "wta"],
  "statuses": ["scheduled"],
  "includeOdds": true,
  "oddsCountry": "GB",
  "oddsMarkets": ["winner"]
}
```

Odds come from the bookmakers Flashscore shows in the country you pick with `oddsCountry`. Run it again just before play and compare `opening` with `odds` to see how the market moved.

#### A week of results for a model

```json
{
  "days": ["-7", "-6", "-5", "-4", "-3", "-2", "-1"],
  "statuses": ["finished"],
  "includeStatistics": true,
  "includeSummary": true,
  "maxMatches": 3000
}
```

Save it as a task and schedule it weekly, for example every Monday at 06:00 UTC with `0 6 * * 1`. For older matches than 7 days, use player results.

#### A player's last 100 matches

```json
{
  "mode": "playerResults",
  "players": ["https://www.flashscore.com/player/djokovic-novak/AZg49Et9/"],
  "maxMatchesPerPlayer": 100
}
```

Player rows add `player_name`, `player_side`, `opponent_name` and `player_won`, written from the point of view of the player you asked for. On 1 Oct 2026, 40 matches of Novak Djokovic's history reached back to 27 Aug 2025.

#### ITF results only

```json
{
  "days": ["today"],
  "tours": ["itf"],
  "statuses": ["finished"]
}
```

### Input parameters

| Parameter | Type | Default | What it does |
|---|---|---|---|
| `mode` | string | `matchesByDay` | `matchesByDay` for the matches of chosen days, or `playerResults` for the match history of chosen players. |
| `days` | array of strings | today | For matches by day: `today`, `yesterday`, `tomorrow`, an offset (`-3`, `+2`) or a date (`2026-09-28`). 7 days back to 7 days ahead, UTC days. |
| `players` | array of strings | none | For player results: Flashscore player links such as `https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/`, or the slug and id (`sinner-jannik/6HdC3z4H`). Up to 100 per run. |
| `maxMatchesPerPlayer` | integer, 1 to 2,000 | `40` | Most recent matches per player, newest first. About 40 matches per page. |
| `statuses` | array | all | `finished`, `live`, `scheduled`, `cancelled`, `postponed`, `abandoned`. |
| `tours` | array | all | `atp`, `wta`, `challenger`, `itf`, `juniors`, `teams` (Davis Cup, BJK Cup, United Cup), `exhibition`, `other`. |
| `matchTypes` | array | both | `singles`, `doubles`. Player results default to singles. |
| `tournaments` | array of strings | all | Keep only tournaments whose name contains one of these, such as `Beijing` or `US Open`. |
| `includeRankings` | boolean | `true` | Current singles ranking, points and previous rank of each player in singles matches. Two extra requests per run. |
| `includeStatistics` | boolean | `false` | Aces, double faults, first serve percentage, points won on serve and return, break points and more, for the match and each set. |
| `includePointByPoint` | boolean | `false` | Every game with the server, whether serve was broken, and each point score with break, set and match point markers. |
| `includeSummary` | boolean | `false` | Match duration, each set's duration and the chair umpire. |
| `includeOdds` | boolean | `false` | Opening and current odds from the bookmakers Flashscore shows in one country. |
| `oddsCountry` | string | `GB` | Two letter country code whose bookmakers to show, for example `GB`, `DE`, `US`, `AU`. |
| `oddsMarkets` | array | all | `winner` (match and set winner), `over_under`, `handicap`, `correct_score`, `odd_even`. |
| `maxMatches` | integer, 1 to 50,000 | `200` | Stop after this many matches in the run. The run stops as soon as the cap is met, without reading the remaining days or players, and its summary shows `reached_max_matches: true`. |

The input form in Apify Console starts with `yesterday` filled in. Runs started through the API or an AI assistant get only what you send, plus the defaults above, so an empty input returns up to 200 of today's matches.

### What data do you get?

One row per match. Fields Flashscore has no value for are left out of that row rather than sent as `null`: a scheduled match has no `score`, and only live matches carry `serving`.

**The match**: `record_type` (always `match`), `match_id`, `match_url`, `start_time`, `end_time`, `status` (`finished`, `live`, `scheduled`, `cancelled`, `postponed` or `abandoned`), `status_detail` (such as `Set 2` while live), `result_type` (`completed`, `retired`, `walkover` or `cancelled`), `match_type` and `note` (Flashscore's remark, such as "Played indoor.").

**The tournament**: `tour`, `category`, `tournament`, `tournament_header`, `tournament_country`, `surface`, `qualification`, `tournament_id` and `tournament_url`.

**The players**: `home_player` and `away_player` as display names, and `home` and `away` as objects with `name`, `id`, `slug`, `country`, `country_id`, `short_code`, `url` and `image_url`. Singles players also get `ranking`, `ranking_points`, `previous_ranking` and `ranking_list`. In doubles, each side adds `partner_name`, `partner_id`, `partner_country`, `partner_country_id` and `partner_image_url`.

**The result**: `winner` (`home` or `away`), `winner_name`, `sets_home`, `sets_away`, `score` (from the home player's side, with the tiebreak loser's points in brackets) and `sets`, a list with each set's games and tiebreak points. Live matches add `current_game_home`, `current_game_away` and `serving`.

**With the options on**: `statistics` (a list of period, group, name and both values, in Flashscore's own text such as `75% (27/36)`) and flat `stat_..._home` and `stat_..._away` columns for the whole match; `point_by_point`; `duration`, `duration_minutes`, `set_durations` and `umpire`; `odds_country` and `odds`, a list of bookmaker, market, scope (full time or a set) and selections with current and opening odds.

**Player results** add `player_id`, `player_name`, `player_side`, `opponent_name` and `player_won`.

**Run rows**: every run that delivers matches ends with one `_type: "info"` row, and a run that delivers none adds one that says why. They are never charged. Filter on `_type` to keep only matches.

What we saw in the 200 rows of our 1 Oct 2026 run (today's matches, taken at 09:07 UTC), so you can plan for it:

- 114 matches were scheduled, 63 finished, 20 live and 3 cancelled. `score` was present on 82 rows and `winner` on 58; a walkover has a winner but no score.
- 82 rows were ITF, 70 Challenger, 32 ATP and 16 WTA; 40 were doubles.
- `umpire` is often missing even with `includeSummary` on: it was present on 1 of our 10 detailed matches. `duration` was on all 10.
- Statistics and point by point exist only where Flashscore has them. A match without them keeps its row without those fields, and the run summary counts it in `details_missing`.

#### Stable fields for automations

These 15 fields were present in every one of the 290 match rows we sampled on 1 Oct 2026 (200 by day, 10 with every option, 80 from player results). Their names will not change, so a Sheet, Zap, Make scenario or n8n flow can map to them safely.

| Field | What it is |
|---|---|
| `match_id` | Flashscore match id. Use it as the unique key. |
| `match_url` | Link to the match on Flashscore |
| `start_time` | Scheduled start, ISO 8601 in UTC |
| `status` | `finished`, `live`, `scheduled`, `cancelled`, `postponed` or `abandoned` |
| `status_detail` | Flashscore's status text, such as `Finished` or `Set 2` |
| `match_type` | `singles` or `doubles` |
| `tour` | `atp`, `wta`, `challenger`, `itf`, `juniors`, `teams`, `exhibition` or `other` |
| `tournament` | Tournament name, such as `Beijing (China)` |
| `tournament_country` | Country of the tournament |
| `surface` | Court surface, such as `hard` or `clay` |
| `home_player` | First listed player or pair, as a display name |
| `away_player` | Second listed player or pair |
| `home` | First player's object with id, country, link and, for singles, ranking |
| `away` | Second player's object |
| `scraped_at` | When the row was collected, ISO 8601 in UTC |

#### Output examples

Real rows from our 1 Oct 2026 runs, trimmed where marked. Values are as Flashscore gives them.

**A finished ATP match with every option on** (local run for 30 Sep; the category and header fields, most statistics columns, all but one game of point by point and all but one of 56 odds lines are trimmed)

```json
{
  "record_type": "match",
  "match_id": "YBGg3Lr2",
  "match_url": "https://www.flashscore.com/match/tennis/YBGg3Lr2/",
  "start_time": "2026-09-30T11:10:00.000Z",
  "end_time": "2026-09-30T13:01:04.000Z",
  "status": "finished",
  "status_detail": "Finished",
  "result_type": "completed",
  "match_type": "singles",
  "tour": "atp",
  "tournament": "Beijing (China)",
  "tournament_country": "China",
  "surface": "hard",
  "qualification": false,
  "home_player": "Borges N.",
  "away_player": "Djokovic N.",
  "home": {
    "name": "Borges N.",
    "id": "hzbEPIOa",
    "country": "Portugal",
    "url": "https://www.flashscore.com/player/borges-nuno/hzbEPIOa/",
    "ranking": 49,
    "ranking_points": 1070,
    "previous_ranking": 48,
    "ranking_list": "ATP"
  },
  "away": {
    "name": "Djokovic N.",
    "id": "AZg49Et9",
    "country": "Serbia",
    "url": "https://www.flashscore.com/player/djokovic-novak/AZg49Et9/",
    "ranking": 11,
    "ranking_points": 2980,
    "previous_ranking": 12,
    "ranking_list": "ATP"
  },
  "winner": "away",
  "winner_name": "Djokovic N.",
  "sets_home": 0,
  "sets_away": 2,
  "score": "3-6 6-7(2)",
  "sets": [
    { "set": 1, "home": 3, "away": 6 },
    { "set": 2, "home": 6, "away": 7, "tiebreak_home": 2, "tiebreak_away": 7 }
  ],
  "statistics": [
    { "period": "Match", "group": "Service", "name": "Aces", "home": "3", "away": "8" }
  ],
  "stat_aces_home": "3",
  "stat_aces_away": "8",
  "stat_first_serve_points_won_home": "75% (27/36)",
  "stat_first_serve_points_won_away": "88% (42/48)",
  "stat_break_points_converted_home": "0/2",
  "stat_break_points_converted_away": "1/2",
  "point_by_point": [
    {
      "set": 1, "game": 2, "games_home": 0, "games_away": 2, "server": "home", "winner": "away", "break": true,
      "points": [{ "score": "0:15" }, { "score": "15:15" }, { "score": "30:15" }, { "score": "30:30" }, { "score": "30:40", "marker": "break_point" }]
    }
  ],
  "duration": "1:52",
  "duration_minutes": 112,
  "set_durations": [{ "set": 1, "duration": "0:43" }, { "set": 2, "duration": "1:09" }],
  "umpire": "Lahyani M.",
  "odds_country": "GB",
  "odds": [
    {
      "bookmaker_id": 625, "bookmaker": "Unibetuk", "market": "HOME_AWAY", "scope": "FULL_TIME",
      "selections": [{ "side": "home", "odds": 3.3, "opening": 2.75 }, { "side": "away", "odds": 1.34, "opening": 1.42 }]
    }
  ],
  "scraped_at": "2026-10-01T13:42:27.469Z"
}
```

**A live match, with the game score and server** (platform run, 1 Oct 2026 at 09:07 UTC, trimmed)

```json
{
  "match_id": "0bIo5sEk",
  "start_time": "2026-10-01T07:55:00.000Z",
  "status": "live",
  "status_detail": "Set 2",
  "tour": "atp",
  "tournament": "Beijing (China)",
  "home_player": "Shang J.",
  "away_player": "Baez S.",
  "sets_home": 0,
  "sets_away": 1,
  "score": "5-7 3-2",
  "current_game_home": "30",
  "current_game_away": "30",
  "serving": "home"
}
```

**A doubles match: both players of each pair** (platform run, 1 Oct 2026, trimmed)

```json
{
  "match_id": "YeUevI3d",
  "status": "finished",
  "result_type": "completed",
  "match_type": "doubles",
  "tour": "atp",
  "tournament": "Beijing (China)",
  "home_player": "Cash R./Erler A.",
  "away_player": "Luz O./Matos R.",
  "home": { "name": "Cash R.", "id": "8fvnhGme", "country": "USA", "partner_name": "Erler A.", "partner_id": "buoHUFzo", "partner_country": "Austria" },
  "away": { "name": "Luz O.", "id": "nokgCiD2", "country": "Brazil", "partner_name": "Matos R.", "partner_id": "vTTQuqa9", "partner_country": "Brazil" },
  "winner": "home",
  "winner_name": "Cash R./Erler A.",
  "score": "7-6(6) 7-6(10)",
  "sets": [
    { "set": 1, "home": 7, "away": 6, "tiebreak_home": 8, "tiebreak_away": 6 },
    { "set": 2, "home": 7, "away": 6, "tiebreak_home": 12, "tiebreak_away": 10 }
  ]
}
```

**A player results row, seen from the player you asked for** (local run, 1 Oct 2026, trimmed)

```json
{
  "match_id": "YBGg3Lr2",
  "start_time": "2026-09-30T11:10:00.000Z",
  "tournament": "Beijing (China)",
  "surface": "hard",
  "home_player": "Borges N.",
  "away_player": "Djokovic N.",
  "score": "3-6 6-7(2)",
  "player_id": "AZg49Et9",
  "player_name": "Djokovic N.",
  "player_side": "away",
  "opponent_name": "Borges N.",
  "player_won": true
}
```

`score` stays written from the home player's side in player results too; use `player_side` to read it from the player's side.

**The information row at the end of a run** (platform run, 1 Oct 2026, never charged)

```json
{
  "_type": "info",
  "delivered": 200,
  "message": "200 matches delivered. This row is informational: it is never billed.",
  "schedule_tip": "Want this refreshed automatically? Apify Console -> this Actor -> Schedules -> Add schedule -> pick how often (e.g. daily) -> Save. It reruns with the same input on autopilot, no code required.",
  "review_tip": "Found this useful? A quick Store review helps other buyers find it: https://apify.com/themineworks/flashscore-tennis-results-scraper#reviews",
  "scraped_at": "2026-10-01T09:07:32.155Z"
}
```

### Pricing

Pay per event: you are charged for each match saved to your dataset, plus a flat fee once per run. The detail options are included in the match price. The match price drops as your Apify plan goes up.

| Event | Free plan | Bronze (Starter) | Silver (Scale) | Gold and above (Business) |
|---|---|---|---|---|
| `match-scraped`, per match | $0.001 | $0.0009 | $0.0008 | $0.0007 |
| Per 1,000 matches | $1.00 | $0.90 | $0.80 | $0.70 |
| `run-start`, per run | $0.005 | $0.005 | $0.005 | $0.005 |

- **Start fee: a flat $0.005 per run**, charged once when the run starts, whatever memory you choose. It is our own `run-start` event, not Apify's per GB start charge, so a bigger memory setting does not raise it.
- **Never charged**: matches your filters leave out, matches past `maxMatches`, the same match found twice, empty days, players with no matches, refused pages and the information rows.
- **Included at no extra cost**: rankings, statistics, point by point, durations, umpire, odds and the datacenter proxies. You pay nothing for platform compute on top of these prices.
- **Spending cap**: if you set a maximum cost per run in Apify, the actor stops adding matches once that budget is used, so you never receive rows past your cap.
- **No price change is scheduled.** These prices have applied since 1 Oct 2026. The Pricing tab always shows the rate for your own plan; if this table and the Pricing tab ever disagree, the Pricing tab is right.

Worked examples on the Free plan: the 467 matches Flashscore listed for 30 Sep 2026 would cost $0.467 plus $0.005, so $0.472. On Gold, 1,000 matches cost $0.705 with the start fee.

### FAQ

**What is Flashscore?**
Flashscore is a live score and results site run by Livesport. For tennis it lists every match from the ATP and WTA tours down to ITF and junior events, with live scores, statistics and odds.

**How many matches can I get?**
Up to 50,000 per run. A single day held 385 matches on 1 Oct 2026 and 467 on 30 Sep; ATP and WTA together are a small part of that. In player results, up to 2,000 matches per player and 100 players per run.

**How do I know whether `maxMatches` cut my run short?**
Read the run summary in the key-value record `OUTPUT`. `reached_max_matches` is `true` when the run delivered exactly `maxMatches` matches and stopped there, and `stop_reason` then reads "reached maxMatches (N)". Days and players after that point are not read and do not appear in the summary's `days` or `players` lists. If `reached_max_matches` is `false`, the run delivered everything your days, players and filters allowed: on 1 Oct 2026 a run for today with `maxMatches: 2000` delivered all 380 listed matches and reported `false`.

**How far back can I go?**
Day lists cover 7 days back to 7 days ahead, as on Flashscore. For older matches use player results: 40 matches of Novak Djokovic's history reached back 13 months on 1 Oct 2026.

**How fresh are live scores?**
As fresh as Flashscore's feed at the moment of the request. For a running scoreboard, schedule the actor every few minutes and filter on `statuses: ["live"]`.

**Do I need a Flashscore account, cookies or a proxy?**
No. The actor reads the public data feeds the Flashscore pages load for every visitor, with no login, through Apify datacenter proxies that are included in the price. In our 1 Oct 2026 runs every request was answered on the first attempt (54 of 54).

**Why is there no round field?**
Round names such as quarter-final are not in the lists this actor reads, so there is no round field. `qualification` tells you whether the match is in qualifying.

**Are rankings from the day of the match?**
No. Rankings are the current singles lists (2,290 ATP and 1,553 WTA players on 1 Oct 2026), not the ranking on the day of an old match. Doubles players get no ranking.

**Why do some matches have no statistics?**
Statistics, point by point and the umpire exist only where Flashscore has them. A match without them keeps its row without those fields, and the run summary in the key-value record `OUTPUT` counts it in `details_missing`.

**What if Flashscore refuses requests?**
Each request is tried up to 4 times. If six requests in a row are refused, the run stops and adds an information row saying so; nothing is charged for refused pages, and matches already delivered stay in your dataset. If a feed answers that its access code is out of date, the actor reads a fresh one from www.flashscore.com once and carries on.

**Does it follow robots.txt?**
Yes. Every address is checked against the host's robots.txt, read fresh at the start of each run. The data feeds live on hosts that serve no robots.txt (global.flashscore.ninja answers 404, the odds host 418), which under Google's rules means no restrictions. The actor does not open the `/tennis/finished/` or `/tennis/live/` pages that www.flashscore.com's robots.txt asks crawlers to skip.

**Can I run it on a schedule?**
Yes. Save your input as a task, then add a schedule in Apify Console under Schedules: daily for results, every few minutes during play for live scores. Each scheduled run is billed like a manual one, including the $0.005 start fee; the schedule itself costs nothing.

**Which formats can I export?**
JSON, CSV, Excel, XML, RSS or HTML from the run's Storage tab, or through the Apify API. For spreadsheets, use the flat `stat_..._home` and `stat_..._away` columns; nested lists such as `sets` and `odds` are split into numbered columns in CSV and Excel.

**Can I use it from Claude, ChatGPT or another AI assistant?**

- Connector URL: `https://mcp.apify.com/?tools=themineworks/flashscore-tennis-results-scraper`.
- Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
- ChatGPT: developer mode, add an MCP connector with the URL, sign in with Apify.
- Cursor or VS Code: add it as an HTTP MCP server with that URL.
- Claude Code: `claude mcp add -t http flashscore-tennis-results-scraper "https://mcp.apify.com/?tools=themineworks/flashscore-tennis-results-scraper"`.

**Is it legal to scrape Flashscore?**
The actor collects only public match data and follows robots.txt. You are responsible for following Flashscore's terms of use. Those terms restrict copying and reuse of its content and database without consent, so check that your use fits, and ask Livesport before you republish. This is general information, not legal advice.

### Integrations

- **Google Sheets**: send each run's matches to a sheet with Apify's Google Sheets integration.
- **Make, Zapier and n8n**: start a run and read the matches with the official Apify modules and nodes, for example to post each day's results to a team chat.
- **Webhooks**: have Apify call your URL when a run finishes, then fetch the dataset.
- **API**: start runs and read results over HTTP, or with the Python and JavaScript clients.
- **MCP clients**: Claude, ChatGPT, Cursor and other MCP clients can call the actor through `https://mcp.apify.com`.

### More from The Mine Works

**More tools**

- [Tennis Match & Player Data Scraper](https://apify.com/themineworks/tennis-match-data)
- [Google Hotels Prices Scraper](https://apify.com/themineworks/google-hotels-prices-scraper)
- [LandWatch Scraper](https://apify.com/themineworks/landwatch-land-for-sale-scraper)

**Social media and video**

- [Threads Scraper](https://apify.com/themineworks/threads-scraper)
- [Reddit Scraper](https://apify.com/themineworks/reddit-scraper)
- [Threads Search Scraper](https://apify.com/themineworks/threads-search-scraper)
- [Instagram Profile Scraper](https://apify.com/themineworks/instagram-profile-scraper)

**Leads and business directories**

- [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder)
- [Skip Trace Lookup](https://apify.com/themineworks/skip-trace-lookup)
- [Google Maps Email Scraper](https://apify.com/themineworks/maps-leads)
- [JustDial Scraper](https://apify.com/themineworks/justdial-business)

**Marketing, SEO and reviews**

- [Facebook Ad Library Scraper](https://apify.com/themineworks/meta-ad-library-scraper)
- [Similarweb Scraper](https://apify.com/themineworks/similarweb-scraper)
- [Google Ads Transparency Scraper](https://apify.com/themineworks/google-ads-transparency)
- [Google News Scraper](https://apify.com/themineworks/google-news)

**LinkedIn**

- [LinkedIn Company Scraper](https://apify.com/themineworks/linkedin-company-details)
- [LinkedIn Post Scraper](https://apify.com/themineworks/linkedin-post-search)
- [LinkedIn Employees Scraper](https://apify.com/themineworks/linkedin-employees)
- [LinkedIn Profile Scraper](https://apify.com/themineworks/linkedin-profile-scraper)

**Real estate**

- [Zillow Rentals Scraper](https://apify.com/themineworks/zillow-rental-listings)
- [Zillow Sold Comps Scraper](https://apify.com/themineworks/zillow-recently-sold)
- [Housing.com Scraper](https://apify.com/themineworks/housing-com-scraper)
- [India Real Estate MCP](https://apify.com/themineworks/india-real-estate-mcp)

**Science, health and government data**

- [CourtListener Scraper](https://apify.com/themineworks/courtlistener-court-records)
- [data.gov.in Scraper](https://apify.com/themineworks/india-data-gov-scraper)
- [Socrata Open Data Scraper](https://apify.com/themineworks/socrata-open-data)
- [Academic Research MCP](https://apify.com/themineworks/academic-research-mcp)

**Jobs and hiring**

- [Foundit Monster India Jobs](https://apify.com/themineworks/foundit-jobs-scraper)
- [Hirist Jobs Scraper](https://apify.com/themineworks/hirist-jobs-scraper)
- [India Jobs MCP](https://apify.com/themineworks/india-jobs-mcp)
- [Naukri Jobs Scraper](https://apify.com/themineworks/naukri-jobs)

**E-commerce and marketplaces**

- [Ozon.ru Scraper](https://apify.com/themineworks/ozon-product-search)
- [⭐ Amazon Reviews Scraper](https://apify.com/themineworks/amazon-reviews)
- [Amazon Product Scraper](https://apify.com/themineworks/amazon-products)
- [Carsales.com.au Scraper](https://apify.com/themineworks/carsales-scraper)

**Company and business data**

- [Company Domain Finder](https://apify.com/themineworks/company-domain-finder)
- [GST Taxpayer Lookup](https://apify.com/themineworks/gst-taxpayer-lookup)
- [World Bank Trade Scraper](https://apify.com/themineworks/global-trade-data)
- [Company KYB Resolver](https://apify.com/themineworks/company-identity-resolver)

**Food and local services**

- [NoBroker Scraper](https://apify.com/themineworks/nobroker-scraper)
- [Swiggy Restaurant Scraper](https://apify.com/themineworks/swiggy-scraper)
- [Zomato Scraper](https://apify.com/themineworks/zomato-scraper)

**Developer and AI tools**

- [Website to Markdown Crawler](https://apify.com/themineworks/rag-crawler)
- [GitHub Skill Finder](https://apify.com/themineworks/github-skill-discovery)
- [GitHub Repo Scraper](https://apify.com/themineworks/github-repo-intelligence)
- [GitHub Trending Scraper](https://apify.com/themineworks/github-trending-scraper)

### Support

Found a bug or need a field we do not return? Open an issue in the Issues tab. Want another sport or data source? Email dmineworks@gmail.com.

This actor is an independent tool and is not affiliated with, endorsed by or sponsored by Flashscore or Livesport s.r.o. Flashscore is a trademark of its owner.

*Flashscore Tennis Scraper turns any day's tennis, or any player's history, into one clean row per match with scores, rankings and optional statistics, point by point and odds, from $0.70 per 1,000 matches.*

# Actor input Schema

## `mode` (type: `string`):

Matches of chosen days, or the match history of chosen players.

## `days` (type: `array`):

For matches by day. One per line: today, yesterday, tomorrow, an offset such as -3 or +2, or a date such as 2026-09-28. Flashscore lists 7 days back to 7 days ahead. Days are UTC days. Leave empty for today.

## `players` (type: `array`):

For player results. Flashscore player links, one per line, for example https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/ (slug/id such as sinner-jannik/6HdC3z4H works too).

## `maxMatchesPerPlayer` (type: `integer`):

Most recent matches per player, newest first. About 40 matches per page.

## `statuses` (type: `array`):

Leave empty for all.

## `tours` (type: `array`):

Leave empty for all.

## `matchTypes` (type: `array`):

Leave empty for both (player results default to singles).

## `tournaments` (type: `array`):

Keep only tournaments whose name contains one of these, for example Beijing or US Open.

## `includeRankings` (type: `boolean`):

Current singles ranking, points and previous rank of each player in singles matches. Two extra requests per run.

## `includeStatistics` (type: `boolean`):

Aces, double faults, first serve percentage, points won on serve and return, break points and more, for the match and each set.

## `includePointByPoint` (type: `boolean`):

Every game with the server, whether serve was broken, and each point score with break, set and match point markers.

## `includeSummary` (type: `boolean`):

Match duration, each set's duration and the chair umpire.

## `includeOdds` (type: `boolean`):

Opening and current odds from the bookmakers Flashscore shows in one country.

## `oddsCountry` (type: `string`):

Two letter country code whose bookmakers to show, for example GB, DE, US, AU.

## `oddsMarkets` (type: `array`):

Leave empty for every market.

## `maxMatches` (type: `integer`):

Stop after this many matches in the run. A full day holds 130 to 470.

## Actor input object example

```json
{
  "mode": "matchesByDay",
  "days": [
    "yesterday"
  ],
  "maxMatchesPerPlayer": 40,
  "includeRankings": true,
  "includeStatistics": false,
  "includePointByPoint": false,
  "includeSummary": false,
  "includeOdds": false,
  "oddsCountry": "GB",
  "maxMatches": 200
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "matchesByDay",
    "days": [
        "yesterday"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/flashscore-tennis-results-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "matchesByDay",
    "days": ["yesterday"],
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/flashscore-tennis-results-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "matchesByDay",
  "days": [
    "yesterday"
  ]
}' |
apify call themineworks/flashscore-tennis-results-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/flashscore-tennis-results-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/otjnHtz1gOphjeQpQ/builds/SjGl6qfW9z0ZriG2F/openapi.json
