# ATP and WTA Tennis Rankings Scraper (`cleanscrape/tennis-rankings-scraper`) Actor

Current ATP and WTA tennis rankings from Flashscore: singles, doubles, the race to the finals and doubles team races. Rank, points, movement, country and player links. Filter by player or country. From $1 per 1,000 entries.

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

## Pricing

from $0.80 / 1,000 ranking entries

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

## ATP and WTA Tennis Rankings Scraper

Download the current ATP and WTA tennis rankings from Flashscore as CSV, Excel or JSON. Every entry has the rank, ranking points, last week's rank and the movement, the country, and a link to the player.

Eight lists are available:

| List | What it ranks | Size (Oct 2026) |
| --- | --- | ---: |
| ATP singles rankings | Men, 52-week ranking | 2,296 players |
| WTA singles rankings | Women, 52-week ranking | 1,547 players |
| ATP singles race | Men, this season (race to the ATP Finals) | 2,255 players |
| WTA singles race | Women, this season (race to the WTA Finals) | 373 players |
| ATP doubles rankings | Men's doubles, one entry per player | 2,801 players |
| WTA doubles rankings | Women's doubles, one entry per player | 1,800 players |
| ATP doubles team race | Men's doubles teams this season | 500 pairs |
| WTA doubles team race | Women's doubles teams this season | 159 pairs |

Take the top 100, a whole list, or only the players or countries you follow. A list takes a few seconds; all eight in full take under a minute.

It is built for fantasy and betting models, tennis media and federations, coaches tracking their players, and anyone who needs ranking data in a spreadsheet or an app. No Flashscore account, cookies or API key is needed. This is an independent tool, maintained by CleanScrape, and not affiliated with Flashscore, the ATP or the WTA.

### Start with a small run

The form opens with the ATP and WTA singles rankings, top 100 each. Start it as it is to see the output, then change the lists.

1. In **Ranking lists**, choose one or more lists.
2. Set **Entries per list**: 10 for the top 10, 100 for the top 100, 5000 for the whole list.
3. Optional: fill in **Only these players** or **Only these countries**.

Open the **Rankings** view on the Output tab, then export to CSV, Excel or JSON.

### Examples

The top 100 of both singles rankings:

```json
{ "rankings": ["atp", "wta"], "maxEntries": 100 }
```

Every list in full, for a weekly snapshot:

```json
{ "rankings": ["atp", "wta", "atp-race", "wta-race", "atp-doubles", "wta-doubles", "atp-doubles-race", "wta-doubles-race"], "maxEntries": 5000 }
```

Where some players stand in the ranking and in this season's race:

```json
{ "rankings": ["atp", "atp-race", "wta", "wta-race"], "players": ["Jannik Sinner", "Carlos Alcaraz", "Coco Gauff", "Iga Swiatek"] }
```

Every Spanish and American player in the singles rankings:

```json
{ "rankings": ["atp", "wta"], "countries": ["ESP", "USA"], "maxEntries": 5000 }
```

### Choose a ready-to-run example

Each example opens with its input filled in. Change the lists, players or countries and run it.

| Example | What it does |
| --- | --- |
| [ATP and WTA top 100 rankings](https://apify.com/cleanscrape/tennis-rankings-scraper/examples/atp-wta-top-100-rankings) | The current top 100 of both singles rankings with points, movement and country. 200 entries, $0.20. |
| [Where Sinner and Alcaraz stand in the ranking and the race](https://apify.com/cleanscrape/tennis-rankings-scraper/examples/player-ranking-and-race-position) | Two players' ATP ranking and race position. Type your own players. About $0.008. |
| [All US players in the ATP and WTA rankings](https://apify.com/cleanscrape/tennis-rankings-scraper/examples/tennis-rankings-by-country) | Every American in both singles rankings (386 entries on Oct 19, 2026). Type another country or code. About $0.39. |
| [ATP and WTA doubles team race standings](https://apify.com/cleanscrape/tennis-rankings-scraper/examples/doubles-team-race-rankings) | Every pair in both doubles team races with both partners. About 660 pairs, $0.66. |

### Players and countries

**Players:** type a name or paste a Flashscore player link, one per line.

- Names match in any order, without accents and regardless of case: `Jannik Sinner`, `sinner` and `Sinner Jannik` all find the same player, and `Swiatek` finds Świątek.
- A single surname finds everyone with that surname. Type the full name or paste the link to be exact.
- Links from any Flashscore site work, with or without `https://`.

**Countries:** country names or the three-letter codes used by the ATP and WTA, one per line. `ESP`, `Spain`, `USA`, `United States`, `GBR`, `UK`, `Czechia` and `CZE` all work.

- Flashscore lists Russian and Belarusian players under the country **World** (they play without a national flag). Type `World` to get them. A search for Russia finds nothing, and the run says so.

An entry is kept when it matches any of your players or any of your countries. A doubles pair is kept when either partner matches. With players or countries, the whole list is searched, and **Entries per list** caps how many matches are saved from each list.

If a player or country is not in any of the chosen lists, the run message names it, for example *Not found in the chosen lists: Roger Federer.* The other entries are still saved.

### What each entry contains

| Column | Meaning |
| --- | --- |
| Rank | Position in the list. Tied entries share a rank |
| Name | Player name as Flashscore writes it, usually surname first. Doubles teams: both partners, separated by `/` |
| Country | The player's country. Doubles teams: both countries. `World` means no national flag |
| Points | Ranking points |
| Previous rank | Rank in the previous edition. Empty for a new entry |
| Rank change | Places gained since the previous edition: positive moved up, negative moved down |
| Ranking list, Ranking name, Tour, Discipline, Race | Which list the entry comes from |
| Ranking date | Date of the ranking edition (YYYY-MM-DD) |
| Player ID, Player link | Flashscore player ID and page. Empty for doubles teams; see Players |
| Players | Each player of the entry with name, ID, country and link: one for players, two for teams. In CSV these are the `players/0/…` and `players/1/…` columns |
| Collected at | When the list was read (UTC) |

One entry in JSON:

```json
{
  "rankingList": "atp-race",
  "rankingName": "ATP singles race",
  "tour": "atp",
  "discipline": "singles",
  "race": true,
  "rankingDate": "2026-10-19",
  "rank": 2,
  "previousRank": 2,
  "rankChange": 0,
  "points": 7950,
  "name": "Sinner Jannik",
  "country": "Italy",
  "playerId": "6HdC3z4H",
  "playerUrl": "https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/",
  "players": [{ "name": "Sinner Jannik", "playerId": "6HdC3z4H", "country": "Italy", "playerUrl": "https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/" }],
  "sourceUrl": "https://www.flashscore.com/tennis/rankings/atp-race/",
  "collectedAt": "2026-10-23T08:08:10.011Z"
}
```

A doubles team entry has `"name": "Dabrowski Gabriela / Luisa Stefani"`, `"country": "Canada / Brazil"` and both partners under `players`.

Every run also saves a **Run report** with each list's edition date, how many entries it has, how many matched your filters, how many were saved, and why the run stopped. Open it from the Output tab.

### Pricing

You pay for each list that loads and for each saved entry:

| What is charged | Price |
| --- | --- |
| Ranking entry saved | $1.00 per 1,000 entries |
| Ranking list loaded | $0.002 per list |

For example:

| Run | Cost |
| --- | ---: |
| One player in the ATP singles ranking (1 list, 1 entry) | $0.003 |
| Four players in the ATP and WTA rankings and races (4 lists, 8 entries) | $0.016 |
| Top 100 of the ATP and WTA singles rankings (2 lists, 200 entries) | $0.20 |
| All eight lists in full (8 lists, about 11,700 entries) | about $11.75 |

A list is charged when it loads, also when none of its entries match your players or countries; the run message then says how many lists were charged. Nothing is charged for input that can't run, for a list Flashscore did not return, or when the run stops before a list loads. Apify plan discounts apply to both prices: 10% on Bronze, 15% on Silver and 20% on Gold and higher.

Set a spending limit under Run options for large runs. The run stops cleanly before it reaches the limit and keeps everything saved so far.

### Schedule it

The ATP and WTA publish new rankings every week, usually on Monday. Create a task with your lists and players, then add a schedule (for example every Monday at 12:00 UTC) to collect each new edition. Each entry has the **Ranking date**, so weekly runs build a history you can chart.

### Use it from an API or an AI agent

Run it from your code with the Apify API or a client library. For example, with `curl` (replace the token with your own):

```bash
curl -X POST "https://api.apify.com/v2/acts/cleanscrape~tennis-rankings-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rankings": ["atp", "wta"], "maxEntries": 10}'
```

Or with Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("cleanscrape/tennis-rankings-scraper").call(run_input={
    "rankings": ["atp", "atp-race"],
    "players": ["Jannik Sinner", "Carlos Alcaraz"],
})
for entry in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(entry["rankingName"], entry["rank"], entry["name"], entry["points"])
```

It also works as a tool in Claude, Cursor and other AI assistants that support MCP, through Apify's MCP server. Add this server and sign in with your Apify account when asked:

```
https://mcp.apify.com?tools=cleanscrape/tennis-rankings-scraper
```

Then ask in plain words, for example: "Where are Jannik Sinner and Carlos Alcaraz in the ATP ranking and the race this week?" The assistant runs the Actor in your Apify account and reads the results. The prices are the same as in Console.

### Match results and statistics

For match results, statistics, point-by-point, form and head-to-head, use the [Flashscore Tennis Scraper for Match History and Stats](https://apify.com/cleanscrape/tennis-match-data). Both use the same Flashscore player IDs, so rankings and matches can be joined on `playerId`.

### Common questions

#### How current are the rankings?

They are the edition Flashscore shows when the run starts, usually Monday's official ranking. The **Ranking date** column says which edition you have.

#### Can I get past rankings?

No. Flashscore shows the current edition only. A weekly schedule builds your own history from now on.

#### Are live or projected rankings included?

No. The lists are the published editions.

#### Why does a doubles team race have pairs while doubles rankings have players?

That is how the tours rank them. The doubles rankings rank each player on their own results with any partner. The team races rank fixed pairs for the season finals.

#### Is there an official ATP or WTA rankings API?

Not a free public one that we know of. The ATP and WTA show the rankings on their own websites. This Actor reads the same rankings from Flashscore's public pages and gives them to you as a table, CSV or JSON.

#### Do I need a Flashscore account?

No. The rankings are public. No account, cookies or API key is used.

#### Can I export to Excel or Google Sheets?

Yes. Export the dataset as Excel (XLSX) or CSV from the Output tab, or connect Google Sheets through an Apify integration.

#### Is it legal to scrape tennis rankings?

The Actor reads public pages that anyone can open without an account, at a gentle pace, and it does not get around bot checks. Rankings are facts about public sporting results. Check the rules that apply to how you use and publish the data. This is not legal advice.

#### How much does it cost?

$1 per 1,000 entries plus $0.002 per list. The top 100 of both singles rankings costs $0.20. See **Pricing** above.

### Good to know

- Times are UTC.
- The ATP doubles team race lists up to 500 pairs, as Flashscore publishes it.
- If Flashscore changes its data feed or refuses requests, the run stops with a clear message instead of saving empty or wrong rows.

### More tools from CleanScrape

- [Flashscore Tennis Scraper](https://apify.com/cleanscrape/tennis-match-data): tennis results, statistics, point-by-point and head-to-head
- [Kick Sponsor Tracker](https://apify.com/cleanscrape/kick-sponsor-tracker): which Kick streamers promote which brands, with codes and broadcast hours
- [Whatnot Scraper](https://apify.com/cleanscrape/whatnot-scraper): Whatnot listings with prices and seller stats, and live shows
- [Whatnot Seller Tracker](https://apify.com/cleanscrape/whatnot-seller-tracker): top sellers per category, items sold, sales per day and followers over time
- [TikTok Shop Product Scraper](https://apify.com/cleanscrape/tiktok-shop-product-scraper): US TikTok Shop prices, sellers and ratings
- [Bilibili Scraper](https://apify.com/cleanscrape/bilibili-scraper): Bilibili videos, danmaku, comments and creators
- [App Store Reviews & Google Play Reviews Scraper](https://apify.com/cleanscrape/app-store-reviews-scraper): reviews from both app stores in one table
- [Google Trends Scraper API](https://apify.com/cleanscrape/google-trends-scraper): search interest over time, by region, related queries and trending searches
- [Map Your Show Exhibitor List Scraper](https://apify.com/cleanscrape/event-exhibitor-monitor): trade show exhibitor lists and booth changes
- [Shopify Product Reviews Scraper API](https://apify.com/cleanscrape/shopify-reviews-scraper): Judge.me and Okendo reviews from Shopify product links
- [Google News Scraper and RSS Feed Reader](https://apify.com/cleanscrape/google-news-scraper): headlines from Google News and publisher feeds
- [Google Jobs Scraper](https://apify.com/cleanscrape/google-jobs-scraper): job listings with salaries and apply links
- [Pinterest Scraper API](https://apify.com/cleanscrape/pinterest-scraper): keyword search, public pin links and board previews; search results may lack a pin link
- [Google Hotels Scraper](https://apify.com/cleanscrape/google-hotels-scraper): hotel prices and booking offers for your dates
- [Meta Threads Scraper](https://apify.com/cleanscrape/threads-scraper): public Threads posts from accounts or post links
- [Likee Scraper API](https://apify.com/cleanscrape/likee-scraper): Likee videos and comments
- [Casino Bonus Checker](https://apify.com/cleanscrape/casino-bonus-checker): the casino bonus each affiliate and review site shows, with promo codes, 18+ notices and affiliate IDs
- [Career Page Jobs Scraper for Greenhouse, Lever and Ashby](https://apify.com/cleanscrape/career-site-jobs-scraper): open jobs from company career pages, with salaries and new or closed jobs per company
- [Video Frame Extractor for Scene Changes and Thumbnails](https://apify.com/cleanscrape/video-frame-extractor): still images from video files at scene changes, intervals or timestamps, with contact sheets

### Support

Questions or a reproducible problem: use the Issues tab or email contact.cleanscrape@gmail.com with the run ID.

If the Actor was useful, an honest review on its Store page helps other people find it.

# Actor input Schema

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

Each list is charged once when it loads ($0.002), plus each saved entry. The doubles team races rank pairs, so one entry there is one pair.

## `maxEntries` (type: `integer`):

The top N of each list, for example 10 or 100. 5000 takes the whole list (ATP singles has about 2,300 ranked players). With players or countries, the whole list is searched and this caps the matches saved per list.

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

Player names or Flashscore player links, one per line, for example Jannik Sinner, Swiatek or https://www.flashscore.com/player/sinner-jannik/6HdC3z4H/. Names match in any order, without accents. A surname alone finds everyone with that surname. Leave empty for the top of each list.

## `countries` (type: `array`):

Country names or three-letter codes, one per line, for example Finland, ESP, USA, United Kingdom, CZE. Flashscore lists Russian and Belarusian players under World. An entry is kept when it matches any player or any country above.

## Actor input object example

```json
{
  "rankings": [
    "atp",
    "wta"
  ],
  "maxEntries": 100,
  "players": [],
  "countries": []
}
```

# Actor output Schema

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

One row per ranking entry: rank, name, country, points, movement and player links.

## `report` (type: `string`):

Readable run report: each list's edition date, entries, matches and why the run stopped.

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

The same run summary as JSON, for code and AI agents.

# 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 = {
    "rankings": [
        "atp",
        "wta"
    ],
    "maxEntries": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleanscrape/tennis-rankings-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 = {
    "rankings": [
        "atp",
        "wta",
    ],
    "maxEntries": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("cleanscrape/tennis-rankings-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 '{
  "rankings": [
    "atp",
    "wta"
  ],
  "maxEntries": 100
}' |
apify call cleanscrape/tennis-rankings-scraper --silent --output-dataset

```

## MCP server setup

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