# Tennis Scraper - Live Scores, Stats, Point-by-Point & Odds (`akhil_rajesh/tennis-scraper`) Actor

Tennis scores, results and fixtures for ATP, WTA, Challenger and ITF: match statistics for each set, point-by-point, odds from every bookmaker with opening prices, head-to-head, player profiles and rankings. Ask by date, player or tournament; no ids needed.

- **URL**: https://apify.com/akhil\_rajesh/tennis-scraper.md
- **Developed by:** [Akhil rajesh](https://apify.com/akhil_rajesh) (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.10 / 1,000 results

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

Get **tennis scores, results and fixtures for ATP, WTA, Challenger and ITF** as clean JSON: **match statistics for every set, point-by-point, odds from every bookmaker with the opening price, head-to-head, player profiles and rankings**. Ask in plain terms, such as a date, a player's name or a tournament. You don't need to look up or copy any ids.

- **Every match of a day in one run.** Live, finished and scheduled matches, 7 days back or forward, with the players' current ranking. ATP and WTA matches come first, so a small **Max results** keeps the ones that matter most.
- **Full match details in the same row.** Aces, double faults, serve and return points, and break points, for the match and each set; every game point by point; the odds and the head-to-head.
- **Odds that show how the market moved.** Every bookmaker's price with its opening price, the average and the best. For finished matches that's the closing price, so you can measure closing-line value.
- **Players.** Profile (height, weight, birth date, playing hand, current and best ranking) and their latest matches.
- **Tournaments back to 2004.** Every match of a season, with its round, including qualifying.
- **Rankings.** ATP and WTA singles, doubles and race lists, with previous rank and movement.
- **Only what changed.** On a schedule, output only new matches and matches whose score, status or odds moved.

No login, no API key, and no proxy is needed. Runs are fast: 100 matches of a day take about 4 seconds, and so do 8 matches with every detail. A whole day of 232 matches with every detail took about 70 seconds.

### What you get for each match

| Field | Example |
|---|---|
| `tour`, `tournament`, `surface` | WTA, Seoul, hard |
| `round` | Final, Semi-finals, 1/8-finals (Tournaments mode and match links) |
| `homePlayer`, `awayPlayer` | Bondar A., Charaeva A. |
| `homeRanking`, `awayRanking`, `homeSeed` | 69, 121, 6 (for doubles, the doubles ranking of the first player listed) |
| `status`, `statusDetail` | finished, live ("Set 2", "Set 1 - Tiebreak"), retired, walkover... |
| `score`, `sets` | 6-4 6-7(6) 7-6(5), with each set's games, tiebreak points and duration |
| `winner`, `duration`, `umpire` | home, 3:18 |
| `server`, `gamePointsHome`, `gamePointsAway` | live: who serves and the point score, e.g. 40 v 15 |
| `acesHome`, `doubleFaultsAway`, `firstServePctHome`, `breakPointsConvertedHome`... | 3, 16, 64, 5/11 |
| `statistics` | all 17 measures, for the match and for each set |
| `pointByPoint` | each game's server, winner, points, breaks, break, set and match points; tiebreaks and doubles match tiebreaks point by point |
| `oddsHome`, `oddsOpeningHome`, `oddsBestHome`, `oddsBookmakers`, `odds` | 1.506 (average), 1.85 (opening), 1.55 (best), 20 bookmakers, each bookmaker's price |
| `headToHead`, `homeForm`, `awayForm` | meetings before this match (exhibitions listed and marked, not counted in the wins); the last 10 official results before it, such as WLWLWWLLWL |

Player rows add `heightCm`, `weightKg`, `dateOfBirth`, `plays`, `ranking`, `highestRankSingles` and `recentForm`. Ranking rows have `rank`, `previousRank`, `movement`, `points` and `tournamentsPlayed`.

### How to use it

Pick what to get under **What to get**, then fill in the section for it. Every field has a sensible default.

#### Matches by day, or live now

```json
{ "mode": "matches", "date": "yesterday", "tours": ["atp", "wta"], "includeStatistics": true, "includeOdds": true }
```

`date` accepts `today`, `yesterday`, `tomorrow` or a date like `2026-09-25` (UTC), up to 7 days back or forward. `days` reads several days at once. Filter by `status` (live, finished, scheduled), `tours`, singles or doubles, `tournaments` or `players`. To follow live scores, use `"status": ["live"]`: it reads what's on court now, including matches that began before midnight UTC.

A day often has 150 to 250 singles matches (152 and 232 on the two days checked, mostly ITF), so raise `maxResults` (100 by default) to get them all. When there are more matches than `maxResults`, ATP, WTA and team events come first, then Challenger, WTA 125 and exhibitions, then ITF. Within each group, live matches come first, then the rest by start time.

#### Exact matches by link

```json
{ "mode": "matches", "matchUrls": ["https://www.flashscore.com/match/Sf0bExdB/"], "includeStatistics": true, "includePointByPoint": true }
```

Links work for live and upcoming matches as well as finished ones.

#### A player's profile and latest matches

```json
{ "mode": "players", "players": ["Jannik Sinner", "Coco Gauff"], "maxMatchesPerPlayer": 20, "includeStatistics": true }
```

Up to about 40 recent singles matches per player are available. When several players share `maxResults`, each gets an equal share.

#### Every match of a tournament season

```json
{ "mode": "tournaments", "tournaments": ["Wimbledon"], "seasons": ["2024"], "includeStatistics": true, "maxResults": 500 }
```

Leave `seasons` empty for the current season, including matches still to come. A name reads the men's and the women's draw; `tours` narrows it to one. Wimbledon 2024 returns 478 singles matches: 254 in the two main draws and 224 in qualifying. The main draws come first, latest round first, so a smaller `maxResults` keeps the finals.

#### Rankings

```json
{ "mode": "rankings", "rankings": ["atp", "wta", "atp-race"], "maxResults": 200 }
```

### Match details and how far back they go

Turn on what you need; each detail is fetched only when asked for.

| Detail | Coverage |
|---|---|
| Statistics and point-by-point | Every played ATP, WTA, Challenger and WTA 125 match, singles and doubles (151 of 151 in a 500-match test run), back to about 2014. ITF matches have no statistics, but about half have point-by-point. |
| Odds | All levels, ITF included, back to about 2009. Turn on **All odds markets** for set winners, total games, handicaps, correct score and odd/even. |
| Head-to-head and form | All levels. |
| Results | Back to at least 2004, through Tournaments mode. |

### Only new or changed matches, on a schedule

Turn on **Only new or changed matches** and schedule the run, for example every 10 minutes during a tournament, or every morning for yesterday's results. Each run then outputs only matches that are new since the last run of the same search, or whose status, score, live points, round or odds changed. Each output row is marked `changeType: "new"` or `"updated"`, and unchanged matches are neither output nor charged. When you follow live matches this way, a match that has ended since the last run is delivered once more with its final score, even though it's no longer live. **Max results** caps what each run outputs; on a busy day the rest come in the following runs. Each search keeps its own history automatically, and a search with other dates or other details is a separate search. Give several schedules the same **History name** to share one.

### Use it with AI agents

Through the [Apify MCP server](https://mcp.apify.com), assistants such as Claude, ChatGPT and Cursor can run this Actor as a tool. Add `https://mcp.apify.com?tools=akhil_rajesh/tennis-scraper` as an MCP server, then ask in plain words, for example *"who is playing live at the ATP events right now, and what are the odds?"* or *"compare Sinner's serve stats in his last 10 matches"*. Every input is plain text, such as names, dates or "live", so an agent never has to look up ids. The Actor is also open to AI agents that pay per run without an Apify account.

### Sample output

A finished WTA match with statistics, odds and head-to-head (lists shortened):

```json
{
  "recordType": "match",
  "matchId": "8lTPC1mm",
  "matchUrl": "https://www.flashscore.com/match/8lTPC1mm/",
  "tour": "WTA",
  "matchType": "singles",
  "tournament": "Seoul",
  "tournamentCountry": "South Korea",
  "surface": "hard",
  "startTime": "2026-09-24T03:05:00Z",
  "endTime": "2026-09-24T06:23:22Z",
  "status": "finished",
  "homePlayer": "Bondar A.",
  "homeCountry": "Hungary",
  "homeRanking": 69,
  "homeSeed": "6",
  "awayPlayer": "Charaeva A.",
  "awayCountry": "Armenia",
  "awayRanking": 121,
  "winner": "home",
  "winnerPlayer": "Bondar A.",
  "score": "6-4 6-7(6) 7-6(5)",
  "sets": [
    {"set": 1, "home": 6, "away": 4, "tiebreakHome": null, "tiebreakAway": null, "duration": "0:47"},
    {"set": 2, "home": 6, "away": 7, "tiebreakHome": 6, "tiebreakAway": 8, "duration": "1:12"},
    {"set": 3, "home": 7, "away": 6, "tiebreakHome": 7, "tiebreakAway": 5, "duration": "1:19"}
  ],
  "duration": "3:18",
  "acesHome": 3,
  "acesAway": 4,
  "doubleFaultsHome": 5,
  "doubleFaultsAway": 16,
  "firstServePctHome": 64,
  "firstServePctAway": 52,
  "breakPointsConvertedHome": "5/11",
  "breakPointsConvertedAway": "4/9",
  "totalPointsWonHome": 122,
  "totalPointsWonAway": 114,
  "oddsOpeningHome": 1.85,
  "oddsOpeningAway": 1.883,
  "oddsHome": 1.506,
  "oddsAway": 2.492,
  "oddsBestHome": 1.55,
  "oddsBestAway": 2.63,
  "oddsBookmakers": 20,
  "odds": [
    {"bookmaker": "Unibetuk", "market": "HOME_AWAY", "scope": "FULL_TIME", "selection": "home", "value": 1.52, "opening": 1.88}
  ],
  "headToHead": {"homeWins": 1, "awayWins": 0, "meetings": [
    {"date": "2026-07-24T09:10:00Z", "tournament": "Hamburg", "surface": "clay", "winner": "home", "score": "2-0"}
  ]},
  "homeForm": "WLWLWWLLWL",
  "awayForm": "WLWWLLWWLW"
}
```

With **Point-by-point** on, `pointByPoint` lists every game:

```json
{"set": 1, "games": [{"game": 1, "score": "1-0", "server": "home", "winner": "home", "broken": false,
  "points": ["0:15", "15:15", "30:15", "30:30", "40:30"], "breakPoints": 0, "setPoints": 0, "matchPoints": 0}]}
```

You can download the dataset as JSON, CSV, Excel or HTML. The Output tab has ready-made tables for matches, statistics, odds, players and rankings.

### How much does it cost to scrape tennis data?

This Actor uses pay-per-event pricing, and platform usage is included, so there's nothing else to pay. You pay for each row returned, plus **$0.001** each time a run starts. A match that comes with details costs **$0.002** more, whatever your plan. That one price covers statistics, point-by-point, odds and head-to-head together. The price per row depends on your Apify plan:

| Your plan | Per 1,000 rows | Per 1,000 matches with details |
|---|---|---|
| Free | $0.25 | $2.25 |
| Starter | $0.20 | $2.20 |
| Scale | $0.15 | $2.15 |
| Business and above | $0.10 | $2.10 |

| Run | Rows | On Free | On Business |
|---|---|---|---|
| A day's first 100 matches, scores only (the default input) | 100 | $0.026 | $0.011 |
| 20 matches with statistics and odds (the example input) | 20 | $0.046 | $0.043 |
| A whole day, 232 matches with every detail | 232 | $0.523 | $0.488 |
| ATP and WTA rankings, 1,000 players each | 2,000 | $0.501 | $0.201 |

Matches your filters leave out, and unchanged matches when **Only new or changed matches** is on, are not charged. To cap spending, set **Max results** or a maximum cost per run in the run options; the Actor stops cleanly at the limit.

### Input

| Field | Default | What it does |
|---|---|---|
| `mode` | `matches` | `matches`, `players`, `tournaments` or `rankings` |
| `date` | `today` | Matches mode: `today`, `yesterday`, `tomorrow` or `YYYY-MM-DD` (UTC), up to 7 days away |
| `days` | 1 | Matches mode: how many days from `date` |
| `status` | all | `live`, `finished`, `scheduled` |
| `tours` | all | `atp`, `wta`, `atp-challenger`, `wta-125`, `itf-men`, `itf-women`, `teams`, `exhibition`, `other` |
| `matchType` | `singles` | `singles`, `doubles` or `both` |
| `players` | none | Surnames, full names or Flashscore player links: a filter in Matches mode, the players to read in Players mode |
| `tournaments` | none | Names or Flashscore tournament links: a filter in Matches mode, the events to read in Tournaments mode (a link to one season reads that season) |
| `matchUrls` | none | Exact matches by Flashscore link or 8-character id, live and upcoming ones included |
| `includeStatistics` | off | Statistics for the match and each set |
| `includePointByPoint` | off | Every game point by point, with tiebreaks |
| `includeOdds` | off | Match-winner odds from every bookmaker, with opening prices |
| `includeAllOddsMarkets` | off | Also set winners, total games, handicaps, correct score, odd/even |
| `includeHeadToHead` | off | Earlier meetings and each player's last 10 matches |
| `includePlayerRankings` | on | The players' current ATP or WTA ranking |
| `onlyChanges` | off | Only matches that are new or changed since the last run of the same search |
| `historyName` | automatic | The store that remembers earlier runs; empty gives each search its own |
| `maxMatchesPerPlayer` | 20 | Players mode: latest matches per player; 0 for the profile only |
| `includePlayerProfiles` | on | Players mode: height, weight, birth date, playing hand, best ranking |
| `seasons` | current | Tournaments mode: years such as `2024` |
| `rankings` | `atp`, `wta` | Rankings mode: `atp`, `wta`, `atp-race`, `wta-race`, `atp-doubles`, `wta-doubles`, `atp-doubles-race`, `wta-doubles-race` |
| `maxResults` | 100 | Most matches to return, main tours first; per list in Rankings mode; shared among players in Players mode |
| `proxy` | none | Optional; not needed |

### FAQ

**Where does the data come from?** Flashscore's public data feeds for scores, statistics, point-by-point, head-to-head, rankings and tournament results; Flashscore's odds comparison for odds; and TennisExplorer player pages for height, weight, birth date and playing hand.

**How live is "live"?** Each run is a snapshot taken as it runs; the data itself updates within seconds. For a running feed, schedule the Actor every few minutes with **Only new or changed matches** on.

**What do "1/8-finals" and "1/16-finals" mean?** They're the rounds of 16 and 32. The round is filled in Tournaments mode and for match links. Qualifying rounds (`tournamentStage` "Qualification") are named as the site names them, so the last qualifying round is also called "Final". Filter on `tournamentStage` to keep the main draw only.

**Why is the form of an old match short?** The source lists each player's latest matches. For an older match, only the ones played before it are kept, so the form can have fewer than 10 results, or none.

**Why is `homePlayer` sometimes the player listed first rather than the higher seed?** "Home" and "away" are simply the two sides as the site lists them. The winner is in `winner` and `winnerPlayer`.

**Why do some matches have no statistics?** ITF matches aren't covered with statistics, and about half of them have no point-by-point; walkovers and cancelled matches have neither. Their scores, odds and head-to-head are still there.

**Can I get older seasons?** Yes, through Tournaments mode with `seasons`, back to 2004. Matches by date reach 7 days back.

### Other Actors by this developer

- [SEEK, JobStreet & JobsDB Jobs Scraper](https://apify.com/akhil_rajesh/seek-jobstreet-jobsdb-scraper): jobs in Australia, New Zealand and six Asian markets, with pay as numbers, applicant counts and change tracking
- [Indeed Jobs Scraper](https://apify.com/akhil_rajesh/indeed-jobs-scraper): job listings from Indeed in Canada, the US and six more countries
- [Wellfound Jobs Scraper](https://apify.com/akhil_rajesh/wellfound-jobs-scraper): startup jobs with salary and equity ranges
- [Price Scraper for Bot-Protected Stores](https://apify.com/akhil_rajesh/bot-wall-price-scraper): live price comparison across major Canadian retailers

### Disclaimer

This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by Flashscore, TennisExplorer, the ATP, the WTA or the ITF. It reads publicly available data at a modest pace. Use the data in line with the sources' terms and the laws that apply to you.

# Changelog

This Actor's version history is a separate document: https://apify.com/akhil\_rajesh/tennis-scraper/changelog.md

# Actor input Schema

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

Matches: matches by day (7 days back or forward) or live now. Players: a player's profile and recent matches. Tournaments: every match of a tournament season, with rounds, back to 2004. Rankings: ATP and WTA ranking lists.

## `date` (type: `string`):

Matches mode: 'today', 'yesterday', 'tomorrow' or a date such as 2026-09-25 (UTC). Up to 7 days back or forward.

## `days` (type: `integer`):

Matches mode: how many days from the date. 3 with date 'yesterday' reads yesterday, today and tomorrow.

## `status` (type: `array`):

Keep only live, finished or scheduled matches. Empty keeps all. 'live' alone reads what's on court now, whatever the date says.

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

Keep only these tours. Empty keeps all. Team competitions give the ties between teams; their single matches are listed under ATP or WTA.

## `matchType` (type: `string`):

Singles, doubles or both.

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

Matches mode: keep only matches with these players. Players mode: the players to look up. A surname, with the first name if you like ('Sinner', 'Coco Gauff', 'J. Sinner'), or a Flashscore player link.

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

Matches mode: keep only these tournaments (part of the name, e.g. 'Beijing', or a tournament link). Tournaments mode: the tournaments to read, by name ('Wimbledon') or Flashscore tournament link; a link to one season ('…/wimbledon-2024/') reads that season.

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

Matches mode: exact matches by Flashscore match link or 8-character match id, live and upcoming ones included. When given, the date and filters are not used.

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

Aces, double faults, first and second serve, return points, break points saved and converted, games and points won, for the whole match and for each set. ATP, WTA and Challenger matches have them; ITF matches don't.

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

Every game's points, the server, breaks, break points, set points and match points, and tiebreaks point by point.

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

Match-winner odds from every bookmaker Flashscore lists, with the opening price: the average, the best and each bookmaker's price. For finished matches the price is the closing one.

## `includeAllOddsMarkets` (type: `boolean`):

Also set winners, total games over/under, handicaps, correct score and odd/even, per bookmaker. Turns Odds on.

## `includeHeadToHead` (type: `boolean`):

Past meetings of the two players and each player's last 10 matches with results, counting only what came before this match.

## `includePlayerRankings` (type: `boolean`):

Add each player's current ATP or WTA ranking to the match: the singles ranking for singles, the doubles ranking for doubles.

## `onlyChanges` (type: `boolean`):

For scheduled runs: output only matches that are new since the last run of the same search, or whose status, score, live points or odds changed. Unchanged matches are not output or charged. Max results caps what each run outputs; the rest come in the next runs. Each search keeps its own history.

## `historyName` (type: `string`):

Optional. Name of the store that remembers earlier runs. Empty gives each search its own; set the same name on several schedules to share one.

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

Players mode: how many of each player's latest matches to add (up to about 40 singles are available). 0 returns the profile only.

## `includePlayerProfiles` (type: `boolean`):

Players mode: height, weight, birth date, playing hand and highest ranking, from TennisExplorer.

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

Tournaments mode: years to read, such as 2024. Empty reads the current season, including matches still to come.

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

Rankings mode: which lists to read.

## `maxResults` (type: `integer`):

The most matches to return (per ranking list in Rankings mode). When a day has more, ATP, WTA and team events come first, then Challenger, WTA 125 and exhibitions, then ITF, each group live matches first, then by start time. Tournaments mode gives the main draw first, latest round first; Players mode shares the number among the players.

## `proxy` (type: `object`):

Optional. The sources answer ordinary requests, so no proxy is needed.

## Actor input object example

```json
{
  "mode": "matches",
  "date": "yesterday",
  "days": 1,
  "status": [],
  "tours": [],
  "matchType": "singles",
  "players": [],
  "tournaments": [],
  "matchUrls": [],
  "includeStatistics": true,
  "includePointByPoint": false,
  "includeOdds": true,
  "includeAllOddsMarkets": false,
  "includeHeadToHead": false,
  "includePlayerRankings": true,
  "onlyChanges": false,
  "maxMatchesPerPlayer": 20,
  "includePlayerProfiles": true,
  "seasons": [],
  "rankings": [
    "atp",
    "wta"
  ],
  "maxResults": 20
}
```

# Actor output Schema

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

No description

## `statistics` (type: `string`):

No description

## `odds` (type: `string`):

No description

## `players` (type: `string`):

No description

## `rankings` (type: `string`):

No description

## `allData` (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 = {
    "date": "yesterday",
    "includeStatistics": true,
    "includeOdds": true,
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("akhil_rajesh/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 = {
    "date": "yesterday",
    "includeStatistics": True,
    "includeOdds": True,
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("akhil_rajesh/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 '{
  "date": "yesterday",
  "includeStatistics": true,
  "includeOdds": true,
  "maxResults": 20
}' |
apify call akhil_rajesh/tennis-scraper --silent --output-dataset

```

## MCP server setup

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