# Flashscore Tennis Scraper & API | ATP, WTA Live Scores, Odds (`zen-studio/flashscore-tennis-api`) Actor

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.

- **URL**: https://apify.com/zen-studio/flashscore-tennis-api.md
- **Developed by:** [Zen Studio](https://apify.com/zen-studio) (community)
- **Categories:** Sports, Developer tools, Integrations
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 matches

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

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

<blockquote style="margin:0 0 16px;border-left:5px solid #4C945E;background:#F0FDF4;padding:16px 20px">
<span style="font-size:18px;font-weight:700;color:#1C1917">The deepest Flashscore tennis record on Apify: 54 fields per match, available as a dataset or as a real-time HTTP API.</span>
</blockquote>

<a href="https://console.apify.com/actors/V6kpzFq0uj3tyobvM/input"><img src="https://api.apify.com/v2/key-value-stores/pJ7iaZsTFhR3k9tjV/records/flashscore-tennis-api-hero.png" alt="Flashscore tennis data: ATP and WTA live scores, set-by-set results with tiebreak points, player seeds and rankings, and bookmaker odds as structured JSON" style="max-width:100%"></a>

 

<table>
<tr>
<td colspan="4" style="padding:10px 14px;background:#4C945E;border:none;border-radius:4px 4px 0 0">
<span style="color:#FAFAF9;font-size:14px;font-weight:700;letter-spacing:0.5px">Zen Studio Sports Data</span>
<span style="color:#E8F5E9;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;Scores, stats and odds across every major source</span>
</td>
</tr>
<tr>
<td style="padding:12px 16px;border:1px solid #E7E5E4;border-radius:0 0 0 4px;background:#D3EDD9;border-right:none;border-top:none;vertical-align:top;width:25%">
<span style="white-space:nowrap">&#127934;&nbsp;&nbsp;<a href="https://apify.com/zen-studio/flashscore-tennis-api" style="color:#4C945E;text-decoration:none;font-weight:700;font-size:13px">Flashscore Tennis</a></span><br>
<span style="color:#4C945E;font-size:12px;font-weight:600">&#10148; You are here</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#E8F5E9;border-right:none;border-top:none;vertical-align:top;width:25%">
<span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-PReplR3mQf3tUpbKG-zUBywwwF1K-bet365-icon_lc6m4t.png" width="20" height="20" style="vertical-align:middle">&nbsp;&nbsp;<a href="https://apify.com/zen-studio/bet365-live-scores" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">Bet365 Scores</a></span><br>
<span style="color:#78716C;font-size:12px">13 sports, live</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#E8F5E9;border-right:none;border-top:none;vertical-align:top;width:25%">
<span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-KhQrxB1NlVTWdsggg-aMGqlNypR0-bet365-icon_lc6m4t.png" width="20" height="20" style="vertical-align:middle">&nbsp;&nbsp;<a href="https://apify.com/zen-studio/bet365-sports-data" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">Bet365 Sports Data</a></span><br>
<span style="color:#78716C;font-size:12px">Fixtures, stats, history</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;border-radius:0 0 4px 0;background:#E8F5E9;border-top:none;vertical-align:top;width:25%">
<span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-W8rOXiLSj8wrgF96k-PQehXxTEV5-draftkings-real-time-api-logo.png" width="20" height="20" style="vertical-align:middle">&nbsp;&nbsp;<a href="https://apify.com/zen-studio/draftkings-odds" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">DraftKings Odds</a></span><br>
<span style="color:#78716C;font-size:12px">Lines, props, SGP</span>
</td>
</tr>
</table>

 

<table>
<tr><td colspan="2" style="padding:10px 14px;background:#4C945E;border:none;border-radius:4px 4px 0 0"><span style="color:#FFFFFF;font-size:14px;font-weight:700">What you get that a plain Flashscore scrape misses</span></td></tr>
<tr>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;background:#F0FDF4;width:34%"><span style="color:#1C1917;font-weight:700">&#127934; Tiebreak scores filled in</span></td>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;border-left:none;background:#F0FDF4"><span style="color:#44403C">A 7-6 set returns <strong style="color:#1C1917">9-7</strong> in the breaker, not an empty placeholder</span></td>
</tr>
<tr>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;background:#E8F5E9"><span style="color:#1C1917;font-weight:700">&#128202; Point by point</span></td>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;border-left:none;background:#E8F5E9"><span style="color:#44403C">Every point of every game, with break, set and match points marked</span></td>
</tr>
<tr>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;background:#F0FDF4"><span style="color:#1C1917;font-weight:700">&#128176; Bookmaker odds</span></td>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;border-left:none;background:#F0FDF4"><span style="color:#44403C">Up to <strong style="color:#1C1917">20</strong> books per market, opening and current, best price per selection</span></td>
</tr>
<tr>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;background:#E8F5E9"><span style="color:#1C1917;font-weight:700">&#127942; Round and seeding</span></td>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;border-left:none;background:#E8F5E9"><span style="color:#44403C">Final, Semi-finals, 1/8-finals, plus each player's seed and entry route</span></td>
</tr>
<tr>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;border-radius:0 0 0 4px;background:#F0FDF4"><span style="color:#1C1917;font-weight:700">&#128197; Past seasons</span></td>
<td style="padding:9px 12px;border:1px solid #E7E5E4;border-top:none;border-left:none;border-radius:0 0 4px 0;background:#F0FDF4"><span style="color:#44403C">Whole tournament draws by year, and the actor tells you what each year holds</span></td>
</tr>
</table>

 

### Key Features

<table>
<tr>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#F0FDF4;vertical-align:top;width:50%;border-radius:4px 0 0 0">
<span style="color:#1C1917;font-weight:700;font-size:14px">&#128203;&nbsp;&nbsp;54 fields per match</span><br>
<span style="color:#57534E;font-size:13px">Sets with tiebreak points, surface, round, venue, umpire, timing</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#F0FDF4;vertical-align:top;width:50%;border-left:none;border-radius:0 4px 0 0">
<span style="color:#1C1917;font-weight:700;font-size:14px">&#128100;&nbsp;&nbsp;15 fields per player</span><br>
<span style="color:#57534E;font-size:13px">Country, photo, seed, entry route, singles and doubles ranking</span>
</td>
</tr>
<tr>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#E8F5E9;vertical-align:top;width:50%;border-top:none">
<span style="color:#1C1917;font-weight:700;font-size:14px">&#128308;&nbsp;&nbsp;Live while it plays</span><br>
<span style="color:#57534E;font-size:13px">Current set, game score, who is serving, tiebreak in progress</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#E8F5E9;vertical-align:top;width:50%;border-top:none;border-left:none">
<span style="color:#1C1917;font-weight:700;font-size:14px">&#127757;&nbsp;&nbsp;Every tour, singles and doubles</span><br>
<span style="color:#57534E;font-size:13px">ATP, WTA, Challenger, ITF, juniors and team events</span>
</td>
</tr>
<tr>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#F0FDF4;vertical-align:top;width:50%;border-top:none;border-radius:0 0 0 4px">
<span style="color:#1C1917;font-weight:700;font-size:14px">&#9889;&nbsp;&nbsp;Scraper or live API</span><br>
<span style="color:#57534E;font-size:13px">One dataset run, or 10 endpoints on a warm container</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;background:#F0FDF4;vertical-align:top;width:50%;border-top:none;border-left:none;border-radius:0 0 4px 0">
<span style="color:#1C1917;font-weight:700;font-size:14px">&#128269;&nbsp;&nbsp;Names, not ids</span><br>
<span style="color:#57534E;font-size:13px">&quot;US Open&quot;, &quot;wta&quot;, &quot;Final&quot;, &quot;2013&quot; all work as filters</span>
</td>
</tr>
</table>

 

### How to Scrape Flashscore Tennis Data

#### Basic: today's matches

```json
{
    "dayOffsets": ["0"]
}
```

#### Yesterday's ATP and WTA singles results

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

#### One tournament, with odds and full match detail

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

#### A past season

```json
{
    "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

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `dayOffsets` | array | `["0"]` | Days relative to today, `-7` to `+7`. `0` is today. |
| `matchStatuses` | array | `["all"]` | `finished`, `live`, `scheduled`, or `all`. |
| `tours` | array | all | `atp`, `wta`, `challenger`, `itf`, `juniors`, `teams`. |
| `matchTypes` | array | both | `singles` or `doubles`. |
| `tournaments` | array | all | Keep tournaments whose name contains one of these. Also names which tournaments to collect for past seasons. |
| `startUrls` | array | none | Restrict to specific tournament pages. Takes precedence over the name filter. |
| `seasons` | array | none | Years to collect, e.g. `["2024"]`. Switches the run from day mode to past seasons. |
| `enrich` | array | none | `summary`, `statistics`, `points`, `h2h`, `highlights`, `news`, `detail`. |
| `includeRounds` | boolean | `true` | Round name and player seeding. |
| `includeRankings` | boolean | `true` | ATP or WTA ranking and points. Not applied to past seasons. |
| `includeOdds` | boolean | `false` | Bookmaker odds for every match. |
| `oddsMarkets` | array | `["GB"]` | Which market's bookmakers to return. Bookmakers are country-specific. |
| `maxItems` | integer | none | Stop 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

```json
{
  "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

Switch the actor to Standby and it answers HTTP instead of writing a dataset. The container stays warm between calls, so a listing you already asked for comes back without refetching.

#### Live data

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/matches` | GET | Matches for a day, with every filter the scraper has |
| `/live` | GET | Only matches in play right now |
| `/match/{matchId}` | GET | One match, optionally enriched |

#### Match detail

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/match/{matchId}/summary` | GET | Set durations, umpire, venue, total match time |
| `/match/{matchId}/stats` | GET | Aces, serve percentages, break points, per set |
| `/match/{matchId}/points` | GET | Point by point, with break, set and match points |
| `/match/{matchId}/h2h` | GET | Head-to-head history for both players |
| `/match/{matchId}/odds` | GET | Bookmaker odds with best price per selection |

#### Discovery (free)

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/tournaments` | GET | Find a tournament by name |
| `/seasons` | GET | Every season it has, and what one season actually holds |
| `/draw` | GET | The bracket: rounds, entrants, and who received a bye |
| `/match/{matchId}/available` | GET | Which detail a match has before you ask for it |
| `/health` | GET | Health check |

#### Past seasons

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/history` | GET | A whole past season of matches. Billed per match returned. |

#### Quick Start

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

```bash
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:

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

#### Response Format

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

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

#### Error Codes

| Code | Meaning | What to do |
|------|---------|------------|
| 400 | A parameter value is not valid | The message names the parameter and the accepted values |
| 402 | Free plan allowance reached | Upgrade your Apify plan |
| 404 | Match, tournament or season not found | For older matches use `/history`, or pass `day=` |
| 503 | Tennis data is temporarily unavailable | Retry |

### Advanced Usage

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

#### Live scoreboard, refreshed on a schedule

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

#### Odds across several markets

```json
{
    "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

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

#### Doubles only, with head-to-head

```json
{
    "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):

https://www.youtube.com/watch?v=1OW8gOqlZbY

https://www.youtube.com/watch?v=1jI7WcVQmwM

### 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

| Event | Per unit | Per 1,000 |
|-------|----------|-----------|
| Match in the dataset | $0.002 | $2.00 |
| Bookmaker odds, per match per market | $0.005 | $5.00 |
| Extra match detail, per match per section | $0.006 | $6.00 |
| Run start | $0.005 | one 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

| Event | Per unit | Per 1,000 |
|-------|----------|-----------|
| Listing call (`/matches`, `/live`) | $0.010 | one per call |
| Match returned by a listing | $0.002 | $2.00 |
| Match returned from a past season (`/history`) | $0.002 | $2.00 |
| Bookmaker odds, per match per market | $0.005 | $5.00 |
| One match section (`/match/{id}/...`) | $0.006 | $6.00 |

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.

**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?**
Use Standby mode. The actor runs as an HTTP server with 10 endpoints and answers requests directly. See the Standby tab for the hostname.

**What's Standby mode?**
The actor runs as an HTTP server instead of a queued job, so a request is answered directly rather than waiting for a run to start. Apify keeps the container warm while you keep using it and shuts it down after a few idle minutes; the next request after that takes a few seconds while it wakes.

**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](https://apify.com/zen-studio/bet365-live-scores) for 13 sports, or [Bet365 Sports Data](https://apify.com/zen-studio/bet365-sports-data) for fixtures and history.

### More Zen Studio scrapers for sports betting

**🏟️ Sportsbook odds**

- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-oLjv3CSV3BhHm5dGN-62o7r64lQq-fanduel-odds-api-logo.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **FanDuel**
  - [FanDuel Odds API](https://apify.com/zen-studio/fanduel-odds)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-W8rOXiLSj8wrgF96k-PQehXxTEV5-draftkings-real-time-api-logo.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **DraftKings**
  - [DraftKings Odds API](https://apify.com/zen-studio/draftkings-odds)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-TjShOnNguT17e9hfQ-ntCswWAqze-betmgm-real-time-api-logo-padded.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **BetMGM**
  - [BetMGM Odds API](https://apify.com/zen-studio/betmgm-odds)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-l6JP3yaLczAdUaiSf-yDHq17ycGp-bet365-icon_lc6m4t.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **Bet365**
  - [Bet365 Real-Time Odds API](https://apify.com/zen-studio/bet365-real-time-odds)
  - [Bet365 Sports Data Scraper](https://apify.com/zen-studio/bet365-sports-data)

**🎯 Daily fantasy & player props**

- <img src="https://api.apify.com/v2/key-value-stores/pJ7iaZsTFhR3k9tjV/records/player-props-aggregator-icon.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **Player Props Aggregator**
  - [Player Props Line Shopping](https://apify.com/zen-studio/player-props-aggregator)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-4AmgQeem8dEgMEiRF-VGffbe665M-prizepicks-scraper-logo.jpeg" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **PrizePicks**
  - [PrizePicks Player Props Scraper](https://apify.com/zen-studio/prizepicks-player-props)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-09TtSjF9Uzs5qfvLc-f9HhMKXsLt-underdog-fantasy-picks-api-logo.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **Underdog Fantasy**
  - [Underdog Fantasy Player Props API](https://apify.com/zen-studio/underdog-player-props)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-vZGwNIMCrwkjp76uR-6jWYFxsPSD-sleeper-fantasy-api-logo.jpg" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **Sleeper**
  - [Sleeper Player Props](https://apify.com/zen-studio/sleeper-player-props)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-otCGHYjTnE0YKgVNJ-iYqrcfxJiq-draftkings-pick6-api-logo.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **DraftKings Pick6**
  - [DraftKings Pick6 Player Props](https://apify.com/zen-studio/draftkings-pick6-player-props)
- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-l6JP3yaLczAdUaiSf-yDHq17ycGp-bet365-icon_lc6m4t.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **Bet365**
  - [Bet365 Player Props API](https://apify.com/zen-studio/bet365-player-props)

**🎾 Live scores & match data**

- <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-PReplR3mQf3tUpbKG-zUBywwwF1K-bet365-icon_lc6m4t.png" width="16" height="16" style="vertical-align:middle;border-radius:3px"> **Bet365**
  - [Bet365 Live Scores API](https://apify.com/zen-studio/bet365-live-scores)

### Support

- **Bugs**: Issues tab
- **Features**: Issues tab

### Legal Compliance

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.*

# Actor input Schema

## `dayOffsets` (type: `array`):

Which days to collect, relative to today. <b>0</b> is today, <b>-1</b> yesterday, <b>1</b> tomorrow. Pick several to cover a range.

## `matchStatuses` (type: `array`):

Keep only matches in these states. <b>All</b> returns everything. Live reflects the moment the run happens.

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

Keep only these tours. Leave empty for every tour.

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

Keep only singles or only doubles. Leave empty for both.

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

Keep only tournaments whose name contains one of these. Case-insensitive. Ignored when <b>Tournament pages</b> is filled in. Also names which tournaments to collect when <b>Past seasons</b> is set.

## `startUrls` (type: `array`):

Restrict the run to specific tournaments by pasting their Flashscore pages. Takes precedence over <b>Tournament name</b>.

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

Collect finished seasons instead of a day of matches. Enter years, e.g. <b>2024</b>. Fill in <b>Tournament name</b> as well: every named tournament is collected for every year listed here. A whole season comes back quickly, so this is the cheapest way to gather a lot of matches. Coverage differs by tournament and era — leave this empty for today's matches.

## `drawCategory` (type: `string`):

One tournament name covers several draws: Wimbledon has men's and women's singles, three doubles draws and four junior draws. Enter <b>WTA</b>, <b>ATP doubles</b>, <b>mixed</b>, <b>boys</b> and so on to pick one. Leave empty for the men's singles.

## `enrich` (type: `array`):

Add deeper data to every match. Each option makes a broad run take longer, so pick only what you need. Scores, set-by-set results and tiebreaks are always included without this.

## `includeRounds` (type: `boolean`):

Add the round each match belongs to (Final, Semi-finals, 1/8-finals...) and each player's tournament seeding. Adds very little time, however many matches you collect.

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

Add each player's ATP or WTA ranking and points. Adds almost no time, however many matches you collect. Not applied to <b>Past seasons</b>: a ranking list is today's, so it would not be the player's rank at the time.

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

<b>Bookmaker odds for every match</b>, including match winner, over/under, handicap, correct score and odd/even, with opening and current prices plus the best available price for every selection. Off by default because it makes a run slower.

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

Whose bookmakers to return. <b>Bookmakers are country-specific</b>: almost every one operates in a single market, so pick the market(s) you can actually bet in. Each extra market makes the run slower.

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

Stop after this many matches. Leave empty for no limit.

## Actor input object example

```json
{
  "dayOffsets": [
    "0"
  ],
  "matchStatuses": [
    "all"
  ],
  "tours": [],
  "matchTypes": [],
  "tournaments": [
    "Wimbledon",
    "French Open"
  ],
  "startUrls": [
    {
      "url": "https://www.flashscore.com/tennis/atp-singles/us-open/"
    }
  ],
  "seasons": [
    "2024",
    "2023"
  ],
  "drawCategory": "WTA",
  "enrich": [],
  "includeRounds": true,
  "includeRankings": true,
  "includeOdds": false,
  "oddsMarkets": [
    "GB"
  ]
}
```

# Actor output Schema

## `results` (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 = {
    "dayOffsets": [
        "0"
    ],
    "startUrls": [
        {
            "url": "https://www.flashscore.com/tennis/atp-singles/us-open/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zen-studio/flashscore-tennis-api").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 = {
    "dayOffsets": ["0"],
    "startUrls": [{ "url": "https://www.flashscore.com/tennis/atp-singles/us-open/" }],
}

# Run the Actor and wait for it to finish
run = client.actor("zen-studio/flashscore-tennis-api").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 '{
  "dayOffsets": [
    "0"
  ],
  "startUrls": [
    {
      "url": "https://www.flashscore.com/tennis/atp-singles/us-open/"
    }
  ]
}' |
apify call zen-studio/flashscore-tennis-api --silent --output-dataset

```

## MCP server setup

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

```

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/V6kpzFq0uj3tyobvM/builds/S9Ho3dRJkxivVyEhI/openapi.json
