SofaScore Tennis Scraper: Live Scores, Stats & Odds
Pricing
from $1.50 / 1,000 dataset items
SofaScore Tennis Scraper: Live Scores, Stats & Odds
Tennis data from SofaScore for betting models and analysts: every ATP, WTA, Challenger and ITF match by day, live, tournament or player, with set and tiebreak scores, rankings and surface. Optional serve stats, point-by-point and odds. Pay only for results.
Pricing
from $1.50 / 1,000 dataset items
Rating
0.0
(0)
Developer
axly
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Tennis Scraper — Live Scores, Point-by-Point, Stats & Odds (Sofascore)
Get structured tennis data from Sofascore: every ATP, WTA, Challenger, ITF and UTR match of a day, live scores, tournament draws, a player's results and upcoming matches. Each match comes with set and tie-break scores, surface, round and both players' ATP/WTA rankings. Add match statistics, point-by-point, bookmaker odds and momentum when you need them. It also exports ATP and WTA rankings and player profiles.
Built for betting and trading models, tipsters, tennis analysts, journalists and dashboard or fantasy apps that need clean, schedulable tennis data without maintaining their own scraper.
What you get
| Field | Description |
|---|---|
matchId, url | Sofascore match id and link |
status, statusDescription | notstarted, inprogress, finished, interrupted, postponed, canceled + label (e.g. "2nd set", "Ended", "Retired") |
startTime | Scheduled start, UTC ISO-8601 |
tour, tournament, tournamentId, season, round | ATP / WTA / Challenger / ITF Men / ITF Women / UTR …, event name, round ("Round of 16", "Final") |
surface | Hardcourt indoor/outdoor, Clay, Red clay, Grass, Carpet … |
matchType | singles or doubles (doubles rows list both partners) |
player1, player2 | id, name, shortName, country, ranking (ATP/WTA, top 500), seed, url, partners |
setsWon, sets | Sets won, and each set's games with tie-break points: [{"set":2,"p1":7,"p2":6,"tiebreak":[9,7]}] |
winner, firstToServe | player1 / player2 |
currentGameScore | Live point score of the current game, e.g. ["40","15"] |
durationSeconds | Match length (tournament, player and match-URL sources; not in day lists) |
statistics | Optional. Per match and per set: aces, double faults, 1st/2nd serve %, 1st/2nd serve points won, break points saved/converted, service/return games, max points in a row, tiebreaks … |
pointByPoint | Optional. Every game in order: server, game winner, break flag, game score, point sequence ["15-0","30-0","30-15","40-15"] |
odds | Optional. Markets such as Full time, First set winner, Total games: decimal and fractional, opening and current price, winning flag |
momentum | Optional. Sofascore "tennis power" value per game |
scrapedAt | When the row was collected (UTC) |
Rankings mode rows:
rankingType, rank, previousRank, bestRank, points, previousPoints, tournamentsPlayed, playerId, name, country, updatedAt, urlname, fullName, country, ranking, tour, birthDate, birthplace, residence, heightM, weightKg, plays, turnedPro, prizeMoneyCurrentYear, prizeMoneyTotal, prizeCurrency, urlUse cases
- Betting and trading models: poll live matches every few minutes and store point-by-point, momentum and odds movement (opening vs current) for in-play models and backtests.
- Pre-match analysis: tomorrow's ATP/WTA fixtures with rankings, surface and odds; a player's recent form from their last results with full serve/return statistics.
- Research and journalism: a whole tournament's results with statistics; weekly ATP/WTA ranking snapshots for movement charts.
- Apps and dashboards: scheduled fixtures and live scores for websites, Discord/Telegram bots and fantasy games.
Input
| Field | Description |
|---|---|
mode | matches (default), rankings or players |
dates | UTC days: 2026-10-21, today, yesterday, tomorrow, +2, -3. Defaults to today when no other source is given |
liveOnly | Only matches in progress right now (a single request, ideal for frequent schedules) |
tournaments | Tournament URLs, ids or names (Wimbledon) → current season's fixtures and results |
players | Player URLs, ids or names (Jannik Sinner) → recent results and upcoming matches, or profiles in players mode |
matchIds | Match URLs or ids |
tours, matchType, statuses | Filters: tours (ATP, WTA, Challenger, ITF Men/Women, UTR Men/Women, Other), singles/doubles, match status |
includeStatistics, includePointByPoint, includeOdds, includeMomentum | Per-match details (statistics, point-by-point and momentum only exist once a match has started) |
rankings, rankingsLimit | rankings mode: atp / wta, top N (max 500) |
maxItems | Maximum rows |
proxyConfiguration | Leave the default: the actor picks working Apify Proxy IPs by itself |
Example: yesterday's ATP and WTA results with statistics and point-by-point
{"dates": ["yesterday"],"tours": ["ATP", "WTA"],"statuses": ["finished"],"matchType": "singles","includeStatistics": true,"includePointByPoint": true,"includeOdds": true,"maxItems": 100}
Example: live scores every 5 minutes
{ "liveOnly": true, "tours": ["ATP", "WTA", "Challenger"], "includeOdds": true, "maxItems": 100 }
Example output (shortened)
{"matchId": 17331293,"url": "https://www.sofascore.com/tennis/match/luciano-darderi-james-duckworth/lUpsJlyc#id:17331293","status": "finished","startTime": "2026-10-21T06:30:00Z","tour": "ATP","tournament": "Almaty, Kazakhstan","round": "Round of 16","surface": "Hardcourt indoor","matchType": "singles","player1": {"id": 39711, "name": "James Duckworth", "country": "AU", "ranking": 73, "seed": null},"player2": {"id": 308084, "name": "Luciano Darderi", "country": "IT", "ranking": 23, "seed": "2"},"winner": "player1","setsWon": [2, 0],"sets": [{"set": 1, "p1": 7, "p2": 5}, {"set": 2, "p1": 7, "p2": 6, "tiebreak": [9, 7]}],"durationSeconds": 6328,"statistics": {"all": {"aces": {"name": "Aces", "p1": 17, "p2": 6},"firstServeAccuracy": {"name": "First serve", "p1": "50/78 (64%)", "p2": "55/79 (70%)","p1Value": 50, "p1Total": 78, "p2Value": 55, "p2Total": 79}}},"pointByPoint": [{"set": 1, "game": 1, "server": "player1", "winner": "player1", "break": false,"score": [1, 0], "points": ["15-0", "30-0", "30-15", "40-15"]}],"odds": [{"market": "Full time", "period": "Match", "choices": [{"name": "1", "side": "player1", "decimal": 2.0, "initialDecimal": 2.3, "winning": true},{"name": "2", "side": "player2", "decimal": 1.8, "initialDecimal": 1.62, "winning": false}]}],"scrapedAt": "2026-10-22T08:00:00Z"}
Scheduling and integrations
Create a Schedule in Apify Console (for example every 5 minutes with liveOnly, or daily at 06:00 UTC with
dates: ["yesterday"]). Read results through the Apify API (/v2/datasets/{id}/items?format=json|csv|xlsx) or
send them on with webhooks and integrations (Google Sheets, Slack, Make, Zapier, Airbyte).
Use it from AI assistants
The actor works as a tool in AI agents through the Apify MCP server (https://mcp.apify.com): ask for "yesterday's
ATP results with statistics" or "Sinner's last 10 matches" and the agent can run it and read the dataset.
FAQ
Which matches are covered? Everything Sofascore lists for tennis: ATP, WTA, Challenger, ITF, UTR, Davis Cup, Billie Jean King Cup, exhibitions, singles and doubles. A busy day has 500+ matches.
How fresh is the data? Each run reads Sofascore at run time. Live rows show the score at that moment, so schedule the actor for continuous tracking.
Why are statistics or point-by-point empty for some matches? They only exist once a match has started, and Sofascore does not provide them for every lower-tier (ITF/UTR) match. Odds also exist before the start.
Why is a ranking empty? Rankings come from the ATP/WTA top 500 singles lists. Doubles players, UTR/ITF players
outside the top 500 and juniors have ranking: null.
Do I need a proxy? No setup needed. The default Apify Proxy setting is enough; the actor switches IPs by itself when one is blocked.
Is this legal? The actor collects publicly visible sports results and statistics. You are responsible for how you use the data and for complying with Sofascore's terms in your jurisdiction.
Something is wrong or missing? Open an issue on the actor page. Issues are read and answered.