Tennis Scraper
Pricing
from $5.89 / 1,000 record scrapeds
Tennis Scraper
All-in-one tennis data API: live scores, tournament schedules, point-by-point, seasons, and player rankings with Elo ratings from SofaScore and Tennis Abstract.
Pricing
from $5.89 / 1,000 record scrapeds
Rating
0.0
(0)
Developer
ParseBird
Maintained by CommunityActor stats
1
Bookmarked
1
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Tennis Scraper
Scrape live tennis scores, tournament schedules, point-by-point match data, and player rankings with Elo ratings — one all-in-one tennis scraper API combining SofaScore and Tennis Abstract.
| Six modes in a single Actor: live ATP/WTA scores with set-by-set breakdowns and odds, tournament discovery by date, point-by-point progression, tournament seasons and prize-money/chronology details, and player profiles combining SofaScore rankings with Tennis Abstract Elo ratings and recent-match stats. |
Copy to your AI assistant
Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.
parsebird/tennis-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/tennis-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Required input: mode (string enum: "liveMatches", "tournaments", "pointByPoint", "tournamentSeasons", "tournamentDetails", "playerDetails"; default "liveMatches"). Mode-specific inputs (fields for other modes are accepted and ignored): maxMatches (integer, liveMatches, 0=all live matches), date (string "YYYY-MM-DD", tournaments), matchId (positive integer, pointByPoint — get from liveMatches/tournamentDetails results), tournamentId (positive integer, tournamentSeasons/tournamentDetails — get from tournaments/liveMatches results), seasonId (positive integer, tournamentDetails, optional — get from tournamentSeasons, omit for newest season), playerId (positive integer, playerDetails — get from match participant IDs in liveMatches/tournamentDetails results). Output fields vary by mode: liveMatches returns id/slug/status/tournamentName/homePlayerName/awayPlayerName/score(home,away,sets[])/odds/url; tournaments returns tournamentId/tournamentName/category/groundType/date; pointByPoint returns matchId/sets[](games[](points[])); tournamentSeasons returns seasonId/name/year; tournamentDetails returns seasonId/hostCity/numberOfCompetitors/totalPrizeMoney/matches[]; playerDetails returns fullName/country/handedness/currentRank/eloRank/eloRating/recentResults[](dominanceRatio,acePercentage). Full actor spec: fetch build via GET https://api.apify.com/v2/acts/parsebird~tennis-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations
What does Tennis Scraper do?
This Actor is an all-in-one tennis data API — it replaces separately maintaining a SofaScore live-score scraper and a Tennis Abstract stats scraper with one Actor and one mode parameter. It renders SofaScore's internal API through a real browser (SofaScore blocks plain HTTP requests at the network-fingerprint level) and combines it with Tennis Abstract's public Elo ratings and match-history reports.
- 🎾 Live ATP/WTA scores — every match in progress right now, with set-by-set scores, serve side, and moneyline odds
- 📅 Tournament discovery — find every tournament (Grand Slam down to ITF) scheduled on any date
- 🏓 Point-by-point data — full game-by-game, point-by-point progression for a specific match
- 🏆 Tournament seasons & details — every historical season of a tournament, plus host city, prize money, competitor count, and match chronology for a given season
- 👤 Player profiles — ranking, handedness, height, turned-pro year, prize money, Elo/hElo/cElo/gElo ratings from Tennis Abstract, and recent match results with dominance ratio and ace percentage
- ⏱️ Scheduling — run any mode on a timer via Apify Scheduler for live monitoring or daily digests
- 🔌 API access — trigger runs and pull results programmatically via the Apify API or client libraries
- 📊 Flexible export — download results as JSON, CSV, or Excel, or query them via API
What data can you extract from SofaScore and Tennis Abstract?
| Field | Available in | Description |
|---|---|---|
homePlayerName / awayPlayerName / score.sets | liveMatches | Live match participants and set-by-set score |
odds | liveMatches | Moneyline odds (fractional and decimal) |
tournamentName / tournamentId / category | tournaments | Tournament identity and tour (ATP/WTA/ITF) |
sets[].games[].points[] | pointByPoint | Point-by-point progression within each game and set |
seasonId / name / year | tournamentSeasons | Every historical season of a tournament |
hostCity / numberOfCompetitors / totalPrizeMoney / matches | tournamentDetails | Season metadata and match chronology |
currentRank / handedness / eloRank / eloRating | playerDetails | SofaScore ranking plus Tennis Abstract Elo rating |
recentResults[].dominanceRatio / .acePercentage | playerDetails | Serve/return dominance and ace rate per recent match |
Input parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
mode | string | Yes | liveMatches | liveMatches, tournaments, pointByPoint, tournamentSeasons, tournamentDetails, or playerDetails |
maxMatches | integer | No | 0 (all) | Cap on results for liveMatches |
date | string | For tournaments | — | YYYY-MM-DD date to discover tournaments |
matchId | integer | For pointByPoint | — | SofaScore match ID |
tournamentId | integer | For tournamentSeasons/tournamentDetails | — | SofaScore tournament ID |
seasonId | integer | No | newest | Season ID for tournamentDetails |
playerId | integer | For playerDetails | — | SofaScore player ID |
proxy | object | No | Apify residential proxy | Connection settings |
Fields not used by the selected mode are accepted and silently ignored — you can leave one full input object configured and just switch mode between runs.
Output example
Live match (mode: "liveMatches")
{"id": 16385412,"slug": "coco-gauff-karolina-muchova","status": "3rd set","tournamentName": "Wimbledon","homePlayerName": "Karolina Muchova","awayPlayerName": "Coco Gauff","score": {"home": 2,"away": 1,"sets": [{ "set": 1, "home": 6, "away": 2, "durationSeconds": 2357 },{ "set": 2, "home": 1, "away": 6, "durationSeconds": 2127 }]},"odds": {"home": { "fractional": "3/1", "decimal": 4.0 },"away": { "fractional": "2/9", "decimal": 1.22 }}}
Player profile (mode: "playerDetails")
{"id": 206570,"fullName": "Jannik Sinner","country": "Italy","handedness": "Right-handed","currentRank": 1,"eloRank": 1,"eloRating": 2331.9,"recentResults": [{"date": "2026-06-29","tournament": "Wimbledon","surface": "Grass","result": "W","opponentName": "Alexander Zverev","score": "6-7(7) 7-6(2) 6-3 6-4","dominanceRatio": 1.237,"acePercentage": 11.0}]}
Download results in JSON, CSV, or Excel directly from the Apify Console, or pull them programmatically via the API.
Use cases
- Live-score widgets and dashboards — poll
liveMatcheson a schedule to power a live tennis scoreboard - Odds monitoring — track moneyline odds movement across live matches for betting or trading analysis
- Tournament coverage — pull
tournamentsfor a date to build a daily "what's on" digest across ATP, WTA, and ITF events - Match analysis — use
pointByPointto reconstruct momentum swings, break-point sequences, and serve patterns for a specific match - Player research and scouting — combine
playerDetails' SofaScore ranking with Tennis Abstract Elo and recent-match dominance ratio for form analysis - Historical research — walk
tournamentSeasonsandtournamentDetailsto build a season-by-season archive of a tournament's champions and results
How to use Tennis Scraper
- Go to the Tennis Scraper page on Apify Store
- Click Try for free — new users get a free trial to test the Actor before paying
- Pick a mode from the dropdown — the form preselects
liveMatches - Fill in the field that mode needs (
datefor tournaments,matchIdfor point-by-point,tournamentId/seasonIdfor tournament details,playerIdfor player details) — get IDs by chaining from a previous run's results - Click Start — the Actor renders SofaScore's own API in a real browser and enriches player data with Tennis Abstract's Elo ratings
- When the run finishes, download your data as JSON, CSV, or Excel, or fetch it via the API
Use with the Apify API
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("parsebird/tennis-scraper").call(run_input={"mode": "liveMatches","maxMatches": 20,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{item['homePlayerName']} vs {item['awayPlayerName']} — {item['status']}")
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('parsebird/tennis-scraper').call({mode: 'playerDetails',playerId: 206570,});const { items } = await client.dataset(run.defaultDatasetId).listItems();items.forEach((item) => {console.log(`${item.fullName} — ATP #${item.currentRank}, Elo rank #${item.eloRank}`);});
See the Apify API documentation for full reference, or the Actor's API tab for ready-to-run request snippets in more languages. Both mode: "liveMatches" and mode: "tournaments" return multiple dataset rows in one run; pointByPoint, tournamentDetails, and playerDetails return one row with nested detail.
How much does it cost to scrape tennis data?
This Actor uses Pay-per-event pricing — you only pay for records actually returned, with no separate platform rental fee.
| Event | Price per event (Free plan) | Price per 1,000 |
|---|---|---|
record-scraped | $0.00699 | $6.99 |
record-scraped is charged once per dataset row: one live match, one tournament, the point-by-point match record, one season, one tournament-details record, or one player-details record. Paid plans get a lower per-event rate ($6.79/1,000 on Bronze, $6.49/1,000 on Silver, $5.89/1,000 on Gold). Start with the free trial and a low maxMatches to preview results before scaling up.
FAQ
Why does this Actor need a browser instead of a simple API call? SofaScore blocks non-browser HTTP clients at the network-fingerprint level — the same request that returns real data from a browser returns a 403 from a plain HTTP library. This Actor renders every SofaScore request in a real headless browser, pinned to a country-specific residential proxy, to get through reliably.
Where do the Elo ratings come from?
SofaScore doesn't publish Elo ratings. playerDetails cross-references Tennis Abstract's publicly published ATP/WTA Elo ratings report by player name to attach eloRank, eloRating, and peak-Elo fields alongside the SofaScore profile.
Why is recentResults sometimes shorter than expected, or empty?
Recent match history comes from Tennis Abstract's own per-player match archive. It only covers tour-level ATP/WTA matches with complete stats recorded — very new pros, retired players, or players outside Tennis Abstract's coverage may return an empty recentResults array while the rest of the profile still populates from SofaScore.
How do I get a playerId, matchId, or tournamentId?
Chain them from other modes: liveMatches and tournamentDetails return match participant IDs (use as playerId) and match IDs (use as matchId); tournaments and liveMatches return tournamentId; tournamentSeasons returns seasonId. The default input example includes real, working sample IDs (Wimbledon, a real Wimbledon match, and Jannik Sinner) to try each mode immediately.
What happens if I set fields for a mode I'm not using?
They're accepted and ignored. Only the field(s) required by the selected mode are validated when the run starts — you can keep one input object configured with every field filled in and just change mode between runs.
Can I schedule recurring runs?
Yes. Use Apify's Scheduler to run liveMatches every few minutes for live monitoring, or tournaments daily for a fixtures digest.
Can I access results via API? Yes. Every run's dataset is available through the Apify API and client libraries (Python, JavaScript) — see the Actor's API tab for ready-made snippets, and Apify's integrations for Zapier, Make, and Google Sheets connections.
Is it legal to scrape tennis data with this Actor? Yes, for publicly available data. Both SofaScore and Tennis Abstract publish their match, tournament, and player data on pages that don't require a login. You're responsible for complying with each site's Terms of Service for your specific use case — see Apify's blog post on the legality of web scraping for general background.
Something not working? Open an issue on the Actor's Issues tab in Apify Console — the ParseBird team monitors it directly.
Related Actors
More sports and monitoring Actors from ParseBird:
- SofaScore Scraper — live scores, lineups, statistics, and odds across every sport SofaScore covers, not just tennis
- Tennis Abstract Player Match Scraper — a player's full ATP/WTA match history with per-match serve/return stats, without the SofaScore live-score layer
- HTTP Request Actor — general-purpose API/webhook integration