# Flashscore Tennis Scraper: Stats & Rankings (`incognito_mode/flashscore-tennis-scraper`) Actor

Scrape tennis from Flashscore: ATP, WTA, Challenger & ITF results and fixtures with set scores, serve stats, point-by-point, odds, full tournament draws and complete ATP/WTA rankings (2,000+ players). Any day, tournament or past edition. No API key.

- **URL**: https://apify.com/incognito\_mode/flashscore-tennis-scraper.md
- **Developed by:** [Elena Vance](https://apify.com/incognito_mode) (community)
- **Categories:** Sports, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 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: Stats & Rankings

Scrape tennis from [Flashscore](https://www.flashscore.com): **ATP, WTA,
Challenger and ITF** results and fixtures with set-by-set scores, tiebreaks
and durations, plus optional **serve & return statistics**, full
**point-by-point**, and **betting odds** from dozens of bookmakers. It also
scrapes **complete tournament draws** and **whole ranking lists**: the full
ATP list is 2,000+ players in a single request.

All of it comes from one Actor with one flat output format. You don't need an
API key, login, browser or proxy. Export to **JSON, CSV, Excel** or use the API.

***

### What can it scrape?

| Mode | Input | One row per |
| --- | --- | --- |
| **Matches by day** | days from 7 back to 7 ahead, tour categories | match |
| **Matches by tournament** | a tournament URL, any past edition (majors back to 1990) | match |
| **Matches by URL/ID** | match URLs or ids, with both players' ranking at match time | match |
| **Rankings** | ATP/WTA singles, doubles and race lists, or live rankings | ranked player |
| **Draws** | tournament URLs: main draw, qualifying or both | bracket slot |

Each match can be enriched with three add-ons, which you pay for only on the
matches that actually have that data:

- **Statistics**: aces, double faults, 1st serve %, 1st/2nd serve points
  won, break points saved and converted, return points, total points, and
  service/return games won. You get these for the whole match and for each
  set.
- **Point-by-point**: every game with its server, the winner, whether serve
  was broken, and the point sequence, with break, set and match points
  flagged. Tiebreaks come point by point with mini-breaks marked.
- **Odds**: each bookmaker's moneyline, main set handicap, main game handicap
  and main total-games line, with opening prices and margin. You also get the
  best and average moneyline for each player.

***

### Output example

A finished ATP match with statistics and point-by-point (abridged):

```json
{
  "recordType": "match",
  "eventId": "0lgU6PM7",
  "eventUrl": "https://www.flashscore.com/match/0lgU6PM7/",
  "category": "ATP - SINGLES",
  "tournament": "Chengdu (China)",
  "surface": "hard",
  "round": "Quarter-finals",
  "startTime": "2026-09-27T05:05:00Z",
  "status": "finished",
  "homeName": "Brooksby J.",
  "awayName": "Basilashvili N.",
  "homePlayers": [{ "name": "Brooksby J.", "id": "MoOtVkbN", "country": "USA" }],
  "winner": "away",
  "homeSets": 0,
  "awaySets": 2,
  "score": "4-6, 6-7(4)",
  "sets": [
    { "set": 1, "homeGames": 4, "awayGames": 6, "homeTiebreak": null, "awayTiebreak": null, "duration": "0:39" },
    { "set": 2, "homeGames": 6, "awayGames": 7, "homeTiebreak": 4, "awayTiebreak": 7, "duration": "0:55" }
  ],
  "duration": "1:34",
  "homeAces": 3, "awayAces": 9,
  "homeDoubleFaults": 2, "awayDoubleFaults": 1,
  "homeFirstServePct": 81, "awayFirstServePct": 58,
  "homeBreakPointsSaved": 5, "homeBreakPointsSavedOf": 7,
  "statistics": { "match": { "aces": { "home": 3, "away": 9 }, "…": {} }, "set1": {}, "set2": {} },
  "games": 22, "tiebreaks": 1, "homeBreaks": 1, "awayBreaks": 2,
  "pointByPoint": [
    { "set": 1, "game": 1, "server": "home", "winner": "away", "brokeServe": true,
      "homeGames": 0, "awayGames": 1,
      "points": [{ "score": "0:15" }, { "score": "0:30" }, { "score": "0:40", "breakPoint": true }] }
  ]
}
```

A ranking row:

```json
{ "recordType": "ranking", "ranking": "atp", "rankingDate": "2026-09-21", "rank": 1, "previousRank": 1,
  "rankChange": 0, "playerName": "Sinner Jannik", "playerId": "6HdC3z4H", "country": "Italy",
  "points": 11500, "tournamentsPlayed": 17 }
```

A draw row:

```json
{ "recordType": "draw", "tournament": "Chengdu (China)", "season": "2026", "stage": "Singles - Main",
  "round": "1/16-finals", "roundNumber": 1, "drawPosition": 2, "homeName": "Harris L.", "homeEntry": "Q",
  "homeCountry": "South Africa", "awayName": "Kovacevic A.", "awayCountry": "USA",
  "homeSets": 2, "awaySets": 0, "winner": "home", "eventId": "Ecz6wUvp" }
```

The Console's dataset tab has ready-made table views for **Matches**, **Serve
statistics**, **Odds**, **Rankings** and **Draws**.

***

### How to use it

**Yesterday's ATP and WTA results with full stats:**

```json
{ "days": ["-1"], "categories": ["atp-singles", "wta-singles"], "status": "finished",
  "includeStatistics": true, "includePointByPoint": true }
```

**Every match of the last three US Opens:**

```json
{ "tournamentUrls": ["https://www.flashscore.com/tennis/atp-singles/us-open/"],
  "seasons": ["2023", "2024", "2025"], "maxMatches": 1000 }
```

**Today's and tomorrow's matches with German bookmakers' odds:**

```json
{ "days": ["0", "1"], "categories": ["atp-singles", "wta-singles"], "status": "scheduled",
  "includeOdds": true, "oddsCountry": "DE" }
```

**The complete ATP and WTA rankings:**

```json
{ "mode": "rankings", "rankings": ["atp", "wta"], "maxRank": 0, "maxItems": 10000 }
```

**Main and qualifying draws of a tournament:**

```json
{ "mode": "draws", "tournamentUrls": ["https://www.flashscore.com/tennis/wta-singles/beijing/"],
  "drawStages": "all" }
```

#### Tips

- **Days are UTC calendar days.** Flashscore only lists 7 days back and 7
  days ahead. For anything older, use a tournament URL with `seasons`.
- **Categories filter by prefix**, so `atp` covers ATP singles and doubles
  and `challenger` covers all four Challenger lists. Leave the list empty to
  get everything. An ITF-heavy day can run to several hundred matches.
- **Match URLs add rankings.** Scraping by match URL or id also returns
  each player's ranking at the time of the match, and the round.
- **Draws for upcoming events** can list only qualifying until the main draw
  is published. The run tells you when that is the case.
- `homeName` and `awayName` follow Flashscore's order (the first-listed
  player is "home"). `winner` says who won.

***

### Pricing

Pay per event. You are charged only for rows you receive:

| Event | Price |
| --- | ---: |
| Match | $0.001 |
| + statistics (per match that has them) | $0.001 |
| + point-by-point (per match that has it) | $0.002 |
| + odds (per match with odds) | $0.001 |
| Ranking entry | $0.0002 |
| Draw slot | $0.0005 |

Some examples:

- 1,000 matches with no add-ons cost **$1**.
- 100 fully enriched matches (all three add-ons) cost **$0.50**.
- The complete ATP ranking (2,291 players) costs **$0.46**.
- A Grand Slam main draw (127 slots) costs **$0.06**.

Invalid input and unknown match ids are never charged. The run stops cleanly
when it reaches your maximum charge.

***

### FAQ

**Is it legal to scrape Flashscore?** This Actor only collects publicly
visible sports data, without logging in. You are responsible for how you use
the data. Check Flashscore's terms and your local laws before using it
commercially.

**Why are some statistics or point-by-point missing?** Flashscore doesn't
cover every match at the same depth. ATP, WTA and most Challenger matches
have both. Lower ITF levels often have only the score. A match without the
data is not charged for that add-on.

**Can I get live scores?** Yes. Set `status` to `live` and `days` to `0`.
Live matches carry their current set scores and `stage` (for example
`Set 2 - Tiebreak`). You can schedule the Actor every few minutes.

**Do you have other sports?** See the other Flashscore and Sofascore Actors on
this account: odds comparison, standings, match statistics and more.

***

### Ready-made examples

Open one, press **Try for free**, and change the input to your own:

- [Export the full ATP and WTA rankings](https://apify.com/incognito_mode/flashscore-tennis-scraper/examples/atp-wta-rankings)
- [Get today's ATP and WTA results with serve stats](https://apify.com/incognito_mode/flashscore-tennis-scraper/examples/tennis-results-with-serve-stats)
- [Scrape the Wimbledon men's singles draw](https://apify.com/incognito_mode/flashscore-tennis-scraper/examples/wimbledon-draw)
- [Get tennis match odds for today and tomorrow](https://apify.com/incognito_mode/flashscore-tennis-scraper/examples/tennis-betting-odds)

### More Flashscore Actors

Same data source, same flat rows and pay-per-result pricing:

- [Flashscore Betting Odds Scraper](https://apify.com/incognito_mode/flashscore-odds-scraper) — pre-match odds from 100+ bookmakers with opening prices, plus outright winner odds
- [Flashscore Odds Movement Tracker](https://apify.com/incognito_mode/flashscore-odds-tracker) — line movement and exact closing lines on a schedule
- [Flashscore Match Stats Scraper](https://apify.com/incognito_mode/flashscore-match-stats-scraper) — player stats with xG, lineups, box scores and team stats per match
- [Flashscore League Archive](https://apify.com/incognito_mode/flashscore-league-archive-scraper) — every season's results, tables and top scorers, back to 1901
- [Flashscore Teams & Players](https://apify.com/incognito_mode/flashscore-team-player-scraper) — squads, transfers with fees, market values and player careers

# Actor input Schema

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

Matches: results and fixtures with optional statistics, point-by-point and odds. Rankings: ATP/WTA singles, doubles and race lists. Draws: full brackets of the tournaments in Tournament URLs.

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

Days to list, as offsets from today (0 = today, -1 = yesterday, 1 = tomorrow) or dates like 2026-09-28. UTC days, 7 days back to 7 days ahead.

## `categories` (type: `array`):

Tours to include when listing by day. Leave empty for everything (ITF and Challenger make a day several hundred matches).

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

Optional. When listing by day, keep only tournaments whose name contains one of these (case-insensitive), e.g. Tokyo or Beijing.

## `status` (type: `string`):

Keep only matches in this state.

## `tournamentUrls` (type: `array`):

Flashscore tournament pages, e.g. https://www.flashscore.com/tennis/atp-singles/us-open/. In Matches mode every match of the edition is scraped; in Draws mode its brackets. Past editions work too (…/us-open-2024/), or use Seasons.

## `seasons` (type: `array`):

Optional years to scrape for each Tournament URL, e.g. 2023, 2024. Empty = the current edition.

## `matchUrls` (type: `array`):

Specific matches, as Flashscore match URLs or 8-character ids (e.g. 0lgU6PM7). Adds both players' ranking at match time. Overrides Days and Tournament URLs.

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

Aces, double faults, 1st/2nd serve %, break points, return and total points — for the whole match and per set. Charged per match that has statistics.

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

Every game with its server, winner, breaks and point sequence (break, set and match points flagged), plus tiebreak points. Charged per match that has it.

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

Each bookmaker's moneyline, main set and game handicaps and main total-games line, with opening prices, plus best and average moneyline. Charged per match with odds.

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

Which country's licensed bookmakers to show odds from: GB, DE, IT, ES, FR, BR, US-NJ … (two-letter code, optional region).

## `rankings` (type: `array`):

Rankings mode: which lists to scrape.

## `maxRank` (type: `integer`):

Keep players ranked this high or better. 0 = the entire list.

## `liveRankings` (type: `boolean`):

ATP/WTA top 100 as they stand during this week's tournaments, with each player's current event and the points they would have after their next win.

## `drawStages` (type: `string`):

Draws mode: the main draw, qualifying, or both.

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

Stop after this many matches.

## `maxItems` (type: `integer`):

Stop after this many dataset rows in total.

## `proxyConfiguration` (type: `object`):

Not needed: Flashscore's data hosts do not block by IP. The Actor escalates to Apify proxies automatically if it is ever refused.

## Actor input object example

```json
{
  "mode": "matches",
  "days": [
    "-1",
    "0"
  ],
  "categories": [
    "atp-singles",
    "wta-singles"
  ],
  "status": "all",
  "tournamentUrls": [
    "https://www.flashscore.com/tennis/atp-singles/us-open/"
  ],
  "seasons": [
    "2024",
    "2025"
  ],
  "includeStatistics": false,
  "includePointByPoint": false,
  "includeOdds": false,
  "oddsCountry": "GB",
  "rankings": [
    "atp",
    "wta"
  ],
  "maxRank": 100,
  "liveRankings": false,
  "drawStages": "main",
  "maxMatches": 50,
  "maxItems": 5000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing every scraped row.

# 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": "matches",
    "days": [
        "0"
    ],
    "categories": [
        "atp-singles",
        "wta-singles"
    ],
    "rankings": [
        "atp",
        "wta"
    ],
    "maxRank": 100,
    "maxMatches": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("incognito_mode/flashscore-tennis-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": "matches",
    "days": ["0"],
    "categories": [
        "atp-singles",
        "wta-singles",
    ],
    "rankings": [
        "atp",
        "wta",
    ],
    "maxRank": 100,
    "maxMatches": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("incognito_mode/flashscore-tennis-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": "matches",
  "days": [
    "0"
  ],
  "categories": [
    "atp-singles",
    "wta-singles"
  ],
  "rankings": [
    "atp",
    "wta"
  ],
  "maxRank": 100,
  "maxMatches": 50
}' |
apify call incognito_mode/flashscore-tennis-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,incognito_mode/flashscore-tennis-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/9aPz5RdE9kP3DeO6s/builds/fNtchUMFPUbDNexVx/openapi.json
