Tennis Odds Dataset - ATP & WTA Closing Odds, Results & Elo
Pricing
from $0.70 / 1,000 matches
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
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.
Related runnable examples
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
- 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).
- Set Years for whole seasons, or From / To day for a date range; pick Tours and Bookmakers of country.
- 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'satp_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
| Option | Default | Description |
|---|---|---|
years | [] | Seasons, e.g. [2024, 2025] (from 1990); empty = the days below |
tours | atp, wta | atp, wta, challenger-men, challenger-women, itf-men, itf-women |
dateFrom | -60 | First day when years is empty: 2026-01-01, yesterday, -7 |
dateTo | today | Last day, inclusive; empty = only the From day |
oddsCountry | GB | Whose bookmakers the odds come from |
maxItems | 200 | Maximum matches in total |
Odds columns
| Column | Description |
|---|---|
B365W, B365L | bet365 closing price of the match winner and the loser |
MaxW, MaxL | Best closing price across the bookmakers |
AvgW, AvgL | Average closing price |
OpenAvgW, OpenAvgL | Average price at the opening |
ProbW, ProbL | Win probability of the winner and the loser without the bookmaker margin |
BookmakerCount | How many bookmakers priced the match |
OddsCountry | The 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.
| Event | No 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 plan | Rows | Cost |
|---|---|---|
| Default run: the last 60 days, up to 200 matches | up to 200 | up to ~$0.50 |
| Last week, ATP + WTA, up to 500 matches | up to 500 | up 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 ApifyClientclient = 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
- Flashscore Tennis Scraper: every match of any day with odds from about 20 bookmakers, head-to-head, form, rankings, player statistics and Elo lists.
- Tennis Live Scores: matches in play now and any day's scores, ATP, WTA, Challenger and ITF.
- Tennis Match History: a player's whole career, match by match, with Elo and serve statistics.
- ATP & WTA Tennis Rankings: the current lists, every weekly list back to 1973 (ATP) and 2001 (WTA), and the player lists.
- ATP & WTA Tennis Match Dataset: whole seasons in Jeff Sackmann's CSV columns.
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.
Is it legal?
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.