Tennis Odds Dataset - ATP & WTA Closing Odds, Results & Elo avatar

Tennis Odds Dataset - ATP & WTA Closing Odds, Results & Elo

Pricing

from $0.70 / 1,000 matches

Go to Apify Store
Tennis Odds Dataset - ATP & WTA Closing Odds, Results & Elo

Tennis Odds Dataset - ATP & WTA Closing Odds, Results & Elo

ATP and WTA results with closing odds in tennis-data.co.uk's column names (B365W/L, MaxW/L, AvgW/L, opening average, fair probability), next to Jeff Sackmann's match columns and pre-match Elo. By season or date range, bookmakers of your country. Export as CSV.

Pricing

from $0.70 / 1,000 matches

Rating

0.0

(0)

Developer

CrawlPlant

CrawlPlant

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Independent tool, not affiliated with, endorsed by or connected to tennis-data.co.uk, Jeff Sackmann, Tennis Abstract, Flashscore, the ATP, the WTA, the ITF or any bookmaker. It reads the public match and odds data that flashscore.com shows to every visitor.

Closing odds next to the result, one row per match, in the column names of tennis-data.co.uk. Every row is a played ATP, WTA, Challenger or ITF singles match in the layout of Jeff Sackmann's atp_matches / wta_matches files (winner and loser, rank, seed, hand, height, age, score, round, minutes, serve statistics, pre-match Elo) with the closing prices appended: B365W / B365L, MaxW / MaxL, AvgW / AvgL, OpenAvgW / OpenAvgL, ProbW / ProbL, BookmakerCount and OddsCountry. Code that reads those columns keeps working.

Explore the same tennis research workflows in our example repository. These recipes currently call the broader Flashscore Tennis Scraper or Match Dataset Actor; they are companion examples, not direct calls to this specialized Actor.

Follow the Python setup and .env guide with your own APIFY_TOKEN, or browse the complete catalog and AI assistant instructions. Actor runs follow Apify pricing; the quickstart explains per-run spending limits.

Why this one

  • The columns you already use. B365W / B365L (bet365 closing prices of the winner and the loser), MaxW / MaxL (best price across the bookmakers), AvgW / AvgL (average), OpenAvgW / OpenAvgL (average at the opening), ProbW / ProbL (win probability without the bookmaker margin), BookmakerCount, OddsCountry.
  • Result and odds in one row. No join between a results file and an odds file: the score, rank, serve statistics and Elo sit next to the prices.
  • Your bookmakers. Odds come from the bookmakers licensed in the country you pick (oddsCountry): about 20 in the UK, plus Germany, Poland, Italy, Spain, France, the US, Australia and others.
  • Elo included. Both players' Elo before the match, to test your edge against the market.
  • Pay for odds only where they exist. The odds price is charged only on matches that carry odds, never on the rest.
  • ATP, WTA, Challenger and ITF. Whole seasons or the last few days.
  • Current. This week's matches are in the dataset within the hour.
  • See it live. The size of the database and the Elo leaders of both tours, from the same database your runs read: crawlplant.com/tennis-odds-dataset.

What can you use it for?

  • Betting models: test a model against closing prices, the benchmark for a tennis edge.
  • Market research: how closing prices moved from the opening average, favourites' hit rate by tour and surface.
  • Replacing a stale file: refresh your results-and-odds table weekly with one scheduled task.
  • AI agents: structured results with closing odds as JSON or CSV.

Quick start

  1. Click Try for free with the default input (ATP and WTA results of the last 60 days with their closing odds, oldest first, up to 200 matches).
  2. Set Years for whole seasons, or From / To day for a date range; pick Tours and Bookmakers of country.
  3. Export the dataset as CSV: the columns come in Jeff Sackmann's order, the odds columns last.

Copy to your AI assistant

Paste this into ChatGPT, Claude or any agent so it knows how to use the Actor:

crawlplant/tennis-odds-dataset on Apify: ATP / WTA / Challenger / ITF singles results in the columns of Jeff Sackmann's
atp_matches files + match_id, tour, winner_elo, loser_elo + closing odds in tennis-data.co.uk's columns: B365W, B365L,
MaxW, MaxL, AvgW, AvgL, OpenAvgW, OpenAvgL, ProbW, ProbL (fair win probability), BookmakerCount, OddsCountry.
Input: years (e.g. [2024, 2025]; empty = the dates), dateFrom / dateTo (e.g. "-7" and "today"), tours (atp, wta,
challenger-men, challenger-women, itf-men, itf-women), oddsCountry (GB default; DE, PL, US, AU...), maxItems (default 200).
Price: $1.00 per 1,000 matches plus $1.50 per 1,000 matches that have odds on the Free plan.

Ready-to-use examples

1. ATP and WTA results of the last 60 days with closing odds, oldest first (up to 200 matches, $0.50 at most; the default)

{ "dateFrom": "-60", "dateTo": "today", "tours": ["atp", "wta"] }

2. A whole ATP season with closing odds (4,285 matches in 2025, up to $10.71)

{ "years": [2025], "tours": ["atp"], "maxItems": 5000 }

3. The first 3,000 Challenger matches of the 2025 season with closing odds (up to $7.50)

{ "years": [2025], "tours": ["challenger-men"], "maxItems": 3000 }

4. Last week's ATP and WTA closing odds from German bookmakers (up to 500 matches, $1.25 at most)

{ "dateFrom": "-7", "dateTo": "today", "tours": ["atp", "wta"], "oddsCountry": "DE", "maxItems": 500 }

5. One day of WTA results with closing odds (up to 200 matches, $0.50 at most)

{ "dateFrom": "yesterday", "dateTo": "yesterday", "tours": ["wta"] }

How to…

Download tennis closing odds with results

Run the default input for the last 60 days (example 1), or give years for whole seasons (examples 2 and 3). Set maxItems above the number of matches you expect: rows come oldest first.

Get the odds of another country's bookmakers

Set oddsCountry to a two-letter code (example 4). OddsCountry in each row says whose bookmakers the prices are from.

Keep a results-and-odds table current

Schedule a task with dateFrom -7 and dateTo today weekly and upsert the rows by match_id.

Input options

OptionDefaultDescription
years[]Seasons, e.g. [2024, 2025] (from 1990); empty = the days below
toursatp, wtaatp, wta, challenger-men, challenger-women, itf-men, itf-women
dateFrom-60First day when years is empty: 2026-01-01, yesterday, -7
dateTotodayLast day, inclusive; empty = only the From day
oddsCountryGBWhose bookmakers the odds come from
maxItems200Maximum matches in total

Odds columns

ColumnDescription
B365W, B365Lbet365 closing price of the match winner and the loser
MaxW, MaxLBest closing price across the bookmakers
AvgW, AvgLAverage closing price
OpenAvgW, OpenAvgLAverage price at the opening
ProbW, ProbLWin probability of the winner and the loser without the bookmaker margin
BookmakerCountHow many bookmakers priced the match
OddsCountryThe country whose bookmakers these are

Every other column is Jeff Sackmann's: tourney_id, tourney_name, surface, draw_size, tourney_level, tourney_date, match_num, winner_* and loser_* (id, seed, entry, name, hand, ht, ioc, age, rank, rank_points), score, best_of, round, minutes, the w_* / l_* serve statistics, plus match_id, tour, winner_elo and loser_elo. A match without odds has the odds columns empty.

How much does tennis closing odds data cost?

Pay per result: platform usage is included. A match is one price; the closing odds are a second price charged only on the matches that have odds.

EventNo discount (Free plan)Bronze (Starter)Silver (Scale)Gold (Business)
Match (per 1,000)$1.00$0.90$0.80$0.70
Closing odds (per 1,000)$1.50$1.35$1.20$1.05
Actor start (per run)$0.00005$0.00005$0.00005$0.00005
Example on the Free planRowsCost
Default run: the last 60 days, up to 200 matchesup to 200up to ~$0.50
Last week, ATP + WTA, up to 500 matchesup to 500up to ~$1.25
A full ATP season (4,285 matches in 2025)4,285~$4.29 + $1.50 per 1,000 with odds, up to ~$10.71

Set a maximum cost per run in the run options to stop a large run at your budget.

Run it through the API

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('crawlplant/tennis-odds-dataset').call({ dateFrom: '-7', dateTo: 'today', tours: ['atp', 'wta'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);

Python:

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawlplant/tennis-odds-dataset").call(run_input={"years": [2025], "tours": ["atp"], "maxItems": 5000})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["tourney_name"], row["winner_name"], row["loser_name"], row["MaxW"], row["MaxL"])

Use with AI agents

The Actor works as a tool in the Apify MCP server for Claude, ChatGPT, Cursor and others:

https://mcp.apify.com?tools=crawlplant/tennis-odds-dataset

Try "which ATP favourites at the closing price lost last week?".

Use it when you need results with closing odds in tennis-data.co.uk's columns.

Not for live scores or the odds of matches not yet played (use the Flashscore Tennis Scraper).

More tennis data

FAQ

Does every match have odds?

No. Matches without odds have the odds columns empty, and you are not charged the odds price for them.

How far back does it go?

Results from 1990. Odds exist for the matches the bookmakers priced; ask for a season with years and compare BookmakerCount to see how well it is covered.

Which date range do I give for one day?

Set dateFrom and dateTo to the same day (example 5; the default dateTo is today). With dateFrom -7 and dateTo today you get the last 8 days.

The data is public sporting results read without logging in, at a polite pace. How you use and publish them is your responsibility, so check the source's terms for your use case.

Questions, a missing field or a source you need? Open an issue on this Actor: we reply within a day. If it saved you time, a short review helps others find it.

Privacy

The data is about professional players' public sporting results and the prices bookmakers showed for them. Each run sends the developer anonymous feature-usage statistics (the options used, never the players you asked for); your Apify account id is replaced by a one-way hash.