# Flashscore Tennis Scraper: Scores, Stats, Point-by-Point & H2H (`datasmithlab/flashscore-tennis-scraper`) Actor

ATP, WTA, Challenger and ITF scores and sets from Flashscore, with optional statistics, point-by-point and H2H where available. Main lists: up to 7 days back and 2 ahead, UTC; live scores are snapshots.

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

## Pricing

from $0.60 / 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: Scores, Stats, Point-by-Point & H2H

Get ATP, WTA, Challenger and ITF results, live snapshots and fixtures from [Flashscore](https://www.flashscore.com/tennis/), with set/tiebreak scores and optional statistics, point-by-point and H2H where available.

Main match lists cover up to 7 days back and 2 ahead, in UTC. Filters, availability and match limits determine coverage; counts and completion times vary. H2H is a separate detail source, not a complete historical archive. No proxy or browser is required.

### Quick start

This example returns up to 20 finished matches from today and yesterday UTC, without a tour filter or paid details. daysBack=1 includes today as well as yesterday. Check DAYS and HEALTH. Live scores are snapshots; scheduled/live matches and matches awaiting requested details may return again in monitoring mode.

```json
{
  "daysBack": 1,
  "daysAhead": 0,
  "statuses": [
    "finished"
  ],
  "includeStatistics": false,
  "includePointByPoint": false,
  "includeH2H": false,
  "onlyNewResults": false,
  "maxItems": 20
}
```

### Export tennis results to CSV with Python

Use the standard-library Python example to export a completed Actor dataset into a reproducible match table. The default returns up to 20 finished matches from today and yesterday UTC with paid details off. Set a small run charge cap, inspect HEALTH and DAYS, then export the JSON or read the dataset with your own APIFY_TOKEN environment variable. No credentials are included. A real 20-match run was exported with matching IDs and preserved nested set scores. This is a bounded sample, not a historical archive, odds feed or ranking feed.

- [Download starter ZIP](https://github.com/Datasmith-lab/datasmithlab-tennis-csv/releases/latest/download/tennis-results-csv-starter.zip)
- [View the walkthrough](https://datasmith-lab.github.io/datasmithlab-tennis-csv/)
- [Read the setup guide](https://github.com/Datasmith-lab/datasmithlab-tennis-csv#setup)

### What you get

- **Matches within the selected scope and limit** across ATP, WTA, ATP Challenger, WTA 125 / Challenger, ITF Men and ITF Women, singles and doubles, main draw and qualifying.
- **Clean set scores with tiebreaks.** `sets: [{"set": 2, "home": 7, "away": 6, "tiebreakHome": 7, "tiebreakAway": 1}]` and a readable `score: "3-6 7-6(1) 5-7"`.
- **How the match ended.** `resultType`: normal, retired, walkover, cancelled, disqualified, plus Flashscore's note when there is one.
- **Tournament context.** Tour, tournament, host country, surface, indoor flag, qualifying flag.
- **Optional match details** (charged separately, only when you turn them on):
  - **Match statistics**: aces, double faults, 1st/2nd serve %, serve and return points won, break points saved and converted, total points, for the whole match and each set, plus set durations.
  - **Point-by-point**: every game with server, game winner, whether serve was broken, and the point sequence (`15:0, 30:0, 30:15, 40:15`).
  - **Head-to-head and recent form**: earlier meetings of the two players and each player's last matches, going back years (not limited to the 7-day window).
- **Only new results.** Turn on *Only new results since last run* and schedule it, e.g. every hour: you get each finished match once. Scheduled and live matches keep coming until they finish. If you asked for match details and Flashscore didn't have them yet, the finished match comes again on the next run so you get the details too.
- **Reports** in the run's key-value store: `DAYS` (matches per day) and `HEALTH` (matches by status, details fetched or missing, empty-field ratios). If Flashscore changes its format, the run fails with a clear message instead of returning an empty dataset.

### Input

| Field | What it does |
|---|---|
| Days back / Days ahead | Flashscore keeps **7 days back** and **2 days ahead**. Days are UTC |
| Match status | finished, live, scheduled. Live is a snapshot at run time |
| Tours | ATP, WTA, ATP Challenger, WTA 125 / Challenger, ITF Men, ITF Women, Other |
| Singles / doubles, Surfaces, Include qualifying | Narrow the draw |
| Tournaments, Players | Substring match, e.g. `Shanghai`, `Sinner` |
| Match statistics / Point-by-point / Head-to-head | Optional details, one extra request each per match |
| H2H / recent matches per list | Rows per head-to-head and recent-form list (default 10) |
| Only new results since last run | Finished results tracked; pending details may return again |
| Max matches | Caps match rows; start and detail charges still apply |

### Output example

```json
{
  "id": "flashscore:Y9DqWWxe",
  "tournament": "Beijing", "tournamentCountry": "China", "tour": "atp", "matchType": "singles",
  "surface": "hard", "isIndoor": false, "isQualification": false,
  "startTime": "2026-10-05T09:30:00Z",
  "status": "finished", "resultType": "retired",
  "homePlayer": "De Minaur A.", "awayPlayer": "Hurkacz H.",
  "homeCountry": "Australia", "awayCountry": "Poland",
  "homeSetsWon": 1, "awaySetsWon": 0, "winner": "home",
  "sets": [{"set": 1, "home": 6, "away": 4}, {"set": 2, "home": 3, "away": 2}],
  "score": "6-4 3-2",
  "statistics": [{"period": "Match", "group": "Service", "name": "Aces", "home": "3", "away": "8"}],
  "setDurations": [{"set": "Set 1", "duration": "0:38"}, {"set": "Set 2", "duration": "0:33"}],
  "pointByPoint": [{"set": 1, "gamesHome": 1, "gamesAway": 0, "server": "away", "gameWinner": "home",
                    "serviceBroken": true, "points": ["15:0", "30:0", "30:15", "40:15"], "markers": ["B1"]}],
  "url": "https://www.flashscore.com/match/Y9DqWWxe/#/match-summary"
}
```

### Good to know

- **No rankings.** Flashscore's match lists don't carry world rankings, so they are not included.
- **Odds are not included.**
- **Live scores are snapshots.** Schedule the Actor to poll; there is no continuous stream.
- **Player names** are short forms as shown by Flashscore (e.g. `Djokovic N.`). Umpire names and other personal data are not collected.
- **Polite by design.** Requests go one at a time with a pause in between; a day list is one request, details are one request each.

### Pricing

FREE-tier event rates checked on 11 October 2026 (FREE is the tier name, not a free run):

- `apify-actor-start`: $0.001 per event.
- `result`: $0.001 per event.
- `match-details`: $0.002 per event.

Start event count depends on memory: one per GB, minimum one. Zero output can still incur start and applicable run costs. Row prices do not guarantee the total invoice. Store pricing is authoritative; rates and tier discounts may change.

Available requested details are charged once per match, not once per detail type.

- **Match**: one event per match returned.
- **Match details**: one extra event per match for which you asked for statistics, point-by-point or head-to-head and at least one of them was available. Matches without details are not charged for them.

### Feedback

Missing a field or a filter? Open an issue on this Actor's page. We read every one and reply.

*Not affiliated with or endorsed by Flashscore or Livesport.*

# Actor input Schema

## `daysBack` (type: `integer`):

Include matches from up to 7 days ago (days are UTC). 0 = today only.

## `daysAhead` (type: `integer`):

Include scheduled matches up to 2 days ahead.

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

Leave empty for all. Live matches are a snapshot at run time.

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

Leave empty for all tours.

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

Leave empty for both.

## `surfaces` (type: `array`):

Leave empty for all.

## `includeQualification` (type: `boolean`):

Turn off to skip qualifying rounds.

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

Keep tournaments whose name contains any of these, e.g. Shanghai, US Open.

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

Keep matches where a player name contains any of these, e.g. Sinner, Swiatek.

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

Aces, double faults, serve and return percentages, break points, total points, for the match and each set, plus set durations.

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

Every game: server, winner, breaks and the point sequence.

## `includeH2H` (type: `boolean`):

Previous meetings of the two players and each player's last matches.

## `h2hLimit` (type: `integer`):

How many rows in each head-to-head and recent-form list.

## `onlyNewResults` (type: `boolean`):

Finished matches already returned with the same filters are skipped. Scheduled and live matches are always returned so you can track them until they finish.

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

Hard stop: you are never charged for more matches than this.

## Actor input object example

```json
{
  "daysBack": 1,
  "daysAhead": 0,
  "statuses": [
    "finished"
  ],
  "includeQualification": true,
  "includeStatistics": false,
  "includePointByPoint": false,
  "includeH2H": false,
  "h2hLimit": 10,
  "onlyNewResults": false,
  "maxItems": 20
}
```

# Actor output Schema

## `matches` (type: `string`):

Matches table (JSON/CSV/Excel export).

## `allFields` (type: `string`):

Every field, including sets, statistics, point-by-point and head-to-head.

## `days` (type: `string`):

Matches read per day and any failures.

## `health` (type: `string`):

Matches by status, details fetched or missing, empty-field ratios.

# 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 = {
    "daysBack": 1,
    "daysAhead": 0,
    "statuses": [
        "finished"
    ],
    "includeStatistics": false,
    "includePointByPoint": false,
    "includeH2H": false,
    "onlyNewResults": false,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("datasmithlab/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 = {
    "daysBack": 1,
    "daysAhead": 0,
    "statuses": ["finished"],
    "includeStatistics": False,
    "includePointByPoint": False,
    "includeH2H": False,
    "onlyNewResults": False,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("datasmithlab/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 '{
  "daysBack": 1,
  "daysAhead": 0,
  "statuses": [
    "finished"
  ],
  "includeStatistics": false,
  "includePointByPoint": false,
  "includeH2H": false,
  "onlyNewResults": false,
  "maxItems": 20
}' |
apify call datasmithlab/flashscore-tennis-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datasmithlab/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/OS9YCslm0Zo1jUD7H/builds/QcV68N8shnCpgbtUl/openapi.json
