Tennis Scraper – Results, Odds, H2H & ATP/WTA Rankings
Pricing
from $2.00 / 1,000 matches
Tennis Scraper – Results, Odds, H2H & ATP/WTA Rankings
Scrape tennis results, fixtures and betting odds from TennisExplorer: set scores, opening and closing odds from 15 bookmakers, H2H, player stats and ATP/WTA rankings. ATP, WTA, Challenger, ITF. No login.
Pricing
from $2.00 / 1,000 matches
Rating
0.0
(0)
Developer
Smoldesk Studios
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape tennis results, upcoming matches and betting odds for every ATP, WTA, Challenger, ITF and UTR match, from TennisExplorer. Each match comes with set-by-set scores and tiebreaks, seeds, round and surface, closing odds with implied probabilities, and whether the favourite or the underdog won. Turn on match details for opening and closing odds from 10–15 bookmakers, the head-to-head record, and both players' ranking, age, height and playing hand. Also scrapes player profiles (win/loss by year and surface) and ATP/WTA rankings. Results go back to the early 2000s (odds from about 2009). No login, no API key, no browser.
What you can use it for
- Betting models and backtests: years of results with closing odds, opening odds and odds movement per bookmaker, in one table.
- Daily results and fixtures feeds: schedule the Actor with
yesterday→+2and get every finished and upcoming match each morning. - Value and line-movement tracking: compare opening vs closing odds, best vs average price, and the bookmaker margin per match.
- Player and surface analysis: win/loss per surface and season, H2H history, upsets by round or ranking gap.
- Tennis apps, newsletters and AI agents: clean JSON with a one-line
summaryper match.
How to scrape tennis results and odds
- Create a free Apify account and open this Actor.
- Pick what to scrape:
- Start date / End date for every match on those days (
2026-10-17,yesterday,-7,+2). - Match types (ATP/WTA singles or doubles, mixed) and Tournament levels (tour, Challenger, ITF, UTR, team cups / club leagues / exhibitions) to narrow it down. Add words to Tournament name contains (
Wimbledon) or Player name contains (Sinner). - Or paste Tournament URLs for a whole draw, Player URLs for a profile plus their season, or Match URLs.
- Tick Rankings for ATP / WTA singles, doubles or race lists.
- Start date / End date for every match on those days (
- Turn on Match details if you need every bookmaker's odds, H2H and player bios. Add Odds movement history and Over/Under, Asian Handicap and Correct Score odds for the full betting picture.
- Click Start. A day of matches takes a few seconds.
- Download the results as JSON, CSV or Excel, or read them through the Apify API.
- Use Schedule to run it every day. With start date
yesterdayand end date+2you always get the latest results plus the next fixtures.
Tips
- For large backfills, leave match details off first (one page per day, ~400 matches); add details only for the matches you model.
- Use Match status: Played for results only, or Upcoming for fixtures with odds.
- Max matches and the run's maximum cost both stop the run cleanly. You only pay for saved results.
Output: match
{"type": "match","matchId": "3350891","url": "https://www.tennisexplorer.com/match-detail/?id=3350891","date": "2026-10-17","startTime": "13:10","startTimeUtc": "2026-10-17T11:10:00Z","status": "finished","tour": "ATP","matchType": "singles","level": "tour","tournament": "Shanghai","tournamentUrl": "https://www.tennisexplorer.com/shanghai/2026/atp-men/","tournamentCountry": "CN","round": "semifinal","surface": "hard","player1": "Jodar R.","player1Url": "https://www.tennisexplorer.com/player/jodar/","player1Seed": "12","player2": "Medvedev D.","player2Url": "https://www.tennisexplorer.com/player/medvedev-e0d2d/","player2Seed": "5","winner": "Jodar R.","winnerSide": "player1","score": "6-3 6-4","setsPlayer1": 2,"setsPlayer2": 0,"sets": [{ "player1": 6, "player2": 3, "tiebreak": null },{ "player1": 6, "player2": 4, "tiebreak": null }],"oddsPlayer1": 2.57,"oddsPlayer2": 1.51,"impliedProbPlayer1": 0.3701,"impliedProbPlayer2": 0.6299,"bookmakerMargin": 0.0514,"favorite": "player2","upset": true,"h2hPlayer1Wins": null,"h2hPlayer2Wins": null,"source": "daily","summary": "Jodar R. (12) beat Medvedev D. (5) 6-3 6-4 — Shanghai semifinal on hard, 2026-10-17 13:10 CET/CEST. Closing odds 2.57 vs 1.51 (upset).","scrapedAt": "2026-10-18T10:40:00Z"}
level:tour(ATP/WTA tour, Grand Slams, Finals),challenger,itf,utrorteam-exhibition(Davis Cup, United Cup, Laver Cup, club leagues such as the Bundesliga, exhibitions).status:finished,retired,walkover,scheduled(no result yet) ornoResult(past match with no score, e.g. cancelled).tiebreak: points of the player who lost the tiebreak (7-6(4)). Doubles match tiebreaks show as the third set (10-7).implied…are the closing odds with the bookmaker margin removed.upset= the player with the higher odds won.- For finished matches the winner is always
player1. For upcoming matches the order is the site's home/away order.
Extra fields with match details
{"player1FullName": "Jodar Rafael","player1Details": {"photoUrl": "https://www.tennisexplorer.com/res/img/player/fXkcYoya-bJuw1oYE.jpeg","singlesRank": 13,"birthDate": "2006-09-17","heightCm": null,"weightKg": null,"plays": "right","turnedPro": null},"player2FullName": "Medvedev Daniil","h2h": {"player1Wins": 1,"player2Wins": 0,"matches": [{ "year": 2026, "tournament": "Shanghai", "winner": "Jodar", "loser": "Medvedev", "score": "6-3 6-4", "surface": "Hard", "round": "semifinal", "matchId": "3350891" }]},"oddsSummary": {"bookmakers": 15,"player1Average": 2.565,"player2Average": 1.507,"player1Best": 2.63,"player2Best": 1.56,"player1OpeningAverage": 2.371,"player2OpeningAverage": 1.532},"bookmakerOdds": [{ "bookmaker": "10Bet", "player1": 2.55, "player2": 1.48, "player1Opening": 2.5, "player2Opening": 1.5, "openedAt": "2026-10-16T13:30:00Z" },{ "bookmaker": "1xBet", "player1": 2.61, "player2": 1.52, "player1Opening": 2.58, "player2Opening": 1.53, "openedAt": "2026-10-16T12:42:00Z" }]}
- Odds movement history adds
player1History/player2Historyto each bookmaker: every change with its UTC time. - Other markets adds
markets.overUnder(total sets / games lines),markets.handicap(set and game handicaps) andmarkets.correctScore, one row per bookmaker and line. - Doubles:
player1Team/player2Teamlist both players with their bios.
Output: player
{"type": "player","name": "Jodar Rafael","url": "https://www.tennisexplorer.com/player/jodar/","country": "Spain","birthDate": "2006-09-17","age": 20,"plays": "right","singlesRank": 13,"singlesRankHighest": 11,"doublesRank": 353,"doublesRankHighest": 344,"photoUrl": "https://www.tennisexplorer.com/res/img/player/fXkcYoya-bJuw1oYE.jpeg","singlesRecord": [{ "year": "career", "totalWins": 105, "totalLosses": 39, "clayWins": 29, "clayLosses": 12, "hardWins": 55, "hardLosses": 22, "indoorsWins": 18, "indoorsLosses": 4, "grassWins": 2, "grassLosses": 1 },{ "year": 2026, "totalWins": 56, "totalLosses": 17, "clayWins": 19, "clayLosses": 4, "hardWins": 31, "hardLosses": 11, "indoorsWins": 3, "indoorsLosses": 1, "grassWins": 2, "grassLosses": 1 }]}
The player's singles matches for the chosen seasons are saved as match records (source: "player") with round, surface, score and odds.
Output: ranking
{"type": "ranking","ranking": "ATP singles","rankingDate": "2026-10-05","rank": 1,"movement": 0,"player": "Sinner Jannik","playerUrl": "https://www.tennisexplorer.com/player/sinner-8b8e8/","country": "Italy","countryCode": "IT","points": 11000}
Input examples
Yesterday's ATP and WTA singles results with every bookmaker's odds:
{"startDate": "yesterday","matchTypes": ["atp-single", "wta-single"],"matchStatus": "finished","includeMatchDetails": true}
A full season of tour-level and Challenger results for backtesting:
{"startDate": "2025-01-01","endDate": "2025-12-31","matchTypes": ["atp-single"],"levels": ["tour", "challenger"]}
Whole draws, a player's seasons and the top 200:
{"tournamentUrls": ["https://www.tennisexplorer.com/wimbledon/2025/atp-men/"],"playerUrls": ["https://www.tennisexplorer.com/player/sinner-8b8e8/"],"playerSeasons": ["2025", "2026"],"rankings": ["atp-singles", "wta-singles"],"rankingTopN": 200}
Pricing
Pay per result. No monthly fee, and Apify's free plan credit covers your first runs.
| What | Price | Per 1,000 |
|---|---|---|
| Match (score, round, surface, closing odds, implied probability) | $0.002 | $2.00 |
| Match details (all bookmakers' odds, H2H, player bios, optional odds history and markets) | +$0.003 | +$3.00 |
| Player profile | $0.003 | $3.00 |
| Ranking row | $0.0005 | $0.50 |
| Run start | $0.00005 | – |
Example: one full day of every match (~400) costs about $0.80. A whole ATP singles season of tour + Challenger results, qualifying included (~14,000 matches), costs about $28, or about $70 with every bookmaker's odds and H2H. If a match page can't be loaded, its details are not charged.
Use with AI (LangChain / LlamaIndex / CrewAI)
Every match has a summary line, so the dataset drops straight into an LLM or RAG pipeline. With LangChain (pip install langchain-apify):
from langchain_apify import ApifyWrapperfrom langchain_core.documents import Documentapify = ApifyWrapper() # reads APIFY_API_TOKENloader = apify.call_actor(actor_id="smoldesk/tennis-scraper",run_input={"startDate": "-7", "endDate": "yesterday", "matchTypes": ["atp-single"], "levels": ["tour"]},dataset_mapping_function=lambda v: Document(page_content=v.get("summary") or "",metadata={k: v.get(k) for k in ("date", "tournament", "round", "surface", "winner", "score", "url")},),)docs = loader.load()
Already have a run? Use ApifyDatasetLoader(dataset_id="<run's dataset ID>", dataset_mapping_function=...). LlamaIndex: ApifyActor from llama-index-readers-apify. CrewAI / Claude / MCP clients: add the Actor as a tool through the Apify MCP server: https://mcp.apify.com?actors=smoldesk/tennis-scraper.
Limitations
- Not a live-score feed. Scores appear once a match is finished. A match in progress shows as
scheduleduntil then. - Retirements are inferred: the site has no retirement label, so a match whose last set was not finished is marked
retired. A player who retires right after completing a set in a best-of-five match can show asfinished. - H2H is the record at the time you scrape, not at the time of the match.
- Round and surface come from the tournament draw page. Team cups, club leagues, round-robin events and some ITF "Futures" groups have no round on the site, so
roundis empty there. In a full 2025 season of ATP tour + Challenger singles, 2% of matches had no round. - Times are the site's Central European time (
startTime) and converted to UTC (startTimeUtc). Old matches often have no start time. - Odds are the prices the site lists (mostly European bookmakers). Coverage is thin before about 2009 and for low-level ITF matches.
FAQ
Is there a free tennis odds API? Not really: the official ATP/WTA data and most odds APIs are paid. This Actor reads the public TennisExplorer pages, so you pay only per result.
Can I get historical tennis results with odds? Yes. Set a date range (results go back to the early 2000s, odds to about 2009) or paste tournament URLs from past years.
Does it include Challenger and ITF matches? Yes: ATP, WTA, Challenger, ITF/Futures and UTR Pro Tennis Series, singles and doubles, plus team cups, club leagues and exhibitions. Filter with Tournament levels (a 2025 ATP singles run had ~3,900 tour, ~10,400 Challenger and ~2,200 team/exhibition matches).
How do I get only one tournament, like Wimbledon? Paste its tournament URL, or set dates plus Tournament name contains: Wimbledon.
Do I need a login, cookies or proxies? No. It works from Apify's servers without a proxy. Residential proxies are never needed.
Is it legal to scrape tennis results? Results and odds are public facts shown without a login. Check the site's terms and your local rules for your use case, especially for betting. This Actor is not affiliated with TennisExplorer, the ATP or the WTA.
Feedback
Found a bug or missing a field? Open an issue in the Issues tab. If the Actor saved you time, a short review on this page helps other people find it.
More Actors from Smoldesk Studios
- Google Ads Transparency Scraper: every ad a competitor runs on Google Search, YouTube and Shopping — creatives, landing pages, countries, EU impressions and new-ad alerts
- Weibo Scraper: keyword and hashtag search, posts, comments, profiles and the hot-search board from China's biggest microblog, no login
- Bilibili Scraper: videos, stats, danmaku, comments and creators from China's video site, no login
- Google Hotels Scraper: hotel prices for your dates in any currency, ratings, review aspects and booking-site prices, worldwide
- Google Trends Scraper: interest over time, by region and city, related queries and Trending now — no API key
- Telegram Channel Scraper: public channel posts, views, reactions and subscribers
- Substack Scraper: newsletters, subscriber counts and posts
- Shopify Store Analyzer: apps, contacts and products of any Shopify store
- Career Site Jobs Scraper: live jobs from 13,000+ company career sites (Greenhouse, Lever, Workday, Ashby) with salary and seniority
- SEEK, JobStreet & JobsDB Scraper: jobs and salaries across Australia and Southeast Asia