Tennis Results, Fixtures, Live Scores & Rankings
Pricing
$6.00 / 1,000 record scrapeds
Tennis Results, Fixtures, Live Scores & Rankings
Ask by date, date range or player name - no internal IDs. Ranges reach finished tournaments, not just today's. Set-by-set scorelines assembled; head-to-head and recent form as flat columns with win percentages. ATP and WTA rankings with movement. Tour level and singles/doubles as columns.
Pricing
$6.00 / 1,000 record scrapeds
Rating
0.0
(0)
Developer
Abhinav Gupta
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 hours ago
Last modified
Categories
Share
Every tennis match on any date — finished results, today's order of play, tomorrow's fixtures — with set-by-set scores already assembled, plus live matches, the full ATP and WTA rankings, and any player's match history by name.
Why this one
No internal IDs. Give it a date, or a player's name. The most-used tennis
scraper on this Store requires you to supply SofaScore's own matchId,
tournamentId, seasonId or playerId before it will return anything, which
means finding those ids somewhere else first. Here, "Carlos Alcaraz" is a
valid input.
Any date, not just right now. Ask for yesterday's results, today's card and tomorrow's fixtures in one run. Most tennis scrapers only return matches that happen to be in progress when you press go, which is useless for anything you want to run on a schedule. The source has no date feed at all — matches are reachable only by walking the tournaments currently running — and doing that walk for you is most of what this Actor is.
A readable scoreline. The source returns games as period1 through
period5 on each side, plus a separate live point value, and leaves you to pair
them up. You get scoreline: "6-4, 3-6, 7-5", homeSetsWon, awaySetsWon, and
the raw per-set arrays if you want to compute your own.
Tour and format as real columns. tourLevel is ATP, WTA, Challenger, ITF
Men or ITF Women; isDoubles is a boolean. Neither exists in the source — the
tour is buried in a category name and doubles is implied by a team type — and
both are the first things anyone filters on.
Flat rows. Tournament, round, surface, both players with country and ranking, status and start time, all at the top level. No nested objects to unwrap before a CSV export makes sense.
Ranking movement. rankingChange is computed from the current and previous
ranking, positive for places gained. The source gives you both numbers and no
difference.
Head-to-head as columns, not a blob. Turn on includeHeadToHead and every
match carries h2hMeetings, h2hHomeWins, h2hAwayWins and a derived
h2hHomeWinPct. The source nests this as a duel object keyed to the home and
away sides of whichever fixture you came in through; here it is four numbers you
can sort and filter on. Roughly half of matches have a record — the source
returns nothing at all for a first meeting rather than zeros, and doubles pairs
usually have none, so null means "no record", not "zero wins".
Date ranges reach finished events. dateFrom and dateTo take a window
rather than a list, and it is not limited to what is running right now — a
completed tournament from an earlier month is retrievable, because the whole
tournament list is walked and each one's season is matched on year before any
page is fetched. Leave either end empty to mean today. Explicit dates still
win over a range, and a range wins over dayOffsets.
A wide range costs more, and honestly: more tournaments have to be examined, so
raise maxTournaments if a long window comes back short. A window returns its
most recent end first, so when maxItems runs out it is the earlier days that
are missing — and the run summary reports which days were actually covered
rather than leaving a partial answer looking like a complete one. If nothing in
the window matched a season at all, the run says that too, instead of reporting
a successful empty result.
Recent form as columns too. includeRecentForm adds each player's recent
results as a readable streak plus the numbers underneath it: homeForm /
awayForm ("WLWWW", newest first), FormPlayed, FormWins and a derived
FormWinPct for each side. It is built from each player's own match feed, so
the match in hand is never counted as its own prior form, and unfinished
matches and walkovers are dropped rather than scored as losses. The percentage
is worked out over what actually counted, which FormPlayed states, so a short
record is never silently scored as a full one.
Optional depth, priced honestly. Head-to-head, recent form, match statistics, bookmaker odds markets and full point-by-point are each off by default because each one costs an extra request per match. Turn on only what you need.
Input
Yesterday, today and tomorrow, ATP and WTA singles only:
{"mode": "schedule","dayOffsets": [-1, 0, 1],"tourFilter": ["ATP", "WTA"],"matchFormat": "singles","maxItems": 500}
Completed results for specific dates:
{"mode": "schedule","dates": ["2026-08-20", "2026-08-21"],"statusFilter": "finished"}
One player's form and what is next:
{ "mode": "player", "playerQuery": "Carlos Alcaraz", "matchesPerPlayer": 20 }
Matches in progress right now:
{ "mode": "live", "maxItems": 100 }
Rankings:
{ "mode": "rankings", "tour": "both", "minRanking": 100 }
Output
A match — the same shape in schedule, live and player modes:
{"matchId": "16888857","tournament": "ITF M15 Arad Men","category": "ITF Men","tourLevel": "ITF Men","isDoubles": false,"round": "Semifinals","surface": "Clay","homePlayer": "Robert Guna","awayPlayer": "Iannis Miletich","homeRanking": null,"scoreline": "3-3","homeSetsWon": 0,"awaySetsWon": 0,"homeSetGames": [3],"awaySetGames": [3],"homePoint": "40","awayPoint": "30","statusType": "inprogress","statusDescription": "1st set","startTime": "2026-08-22T07:09:48.000Z","matchDate": "2026-08-22"}
In player mode each row also carries queriedPlayer and queriedPlayerId.
A ranked player:
{"tour": "ATP","ranking": 1,"playerName": "Jannik Sinner","country": "Italy","points": 13450,"previousRanking": 1,"rankingChange": 0,"bestRanking": 1,"tournamentsPlayed": 18}
Compared to the alternatives
Checked 25 Aug 2026, and worth verifying yourself before trusting any of it.
- The highest-usage tennis Actor here needs internal ids as input. This one takes names and dates.
- The second-highest has not been updated in over three months. Scrapers rot quietly — a stale one usually still returns rows, just wrong ones.
- Several cover one source each: Tennis Abstract only, TennisExplorer only, point-by-point only. This covers live, scheduled, completed, rankings and player history from one schema.
- Head-to-head and recent form are here as flat columns. Where competitors return the source's nested duel and form objects, this returns numbers you can sort on, plus the derived win percentages nobody else computes.
Who this is for
- Modellers and traders who need completed results by date and live match state
- Sports media and newsletters reporting results and previewing the day's card
- Researchers tracking ranking movement and head-to-head form over a season
- Fantasy and prediction products needing scores and player metadata
Notes
- Runs are capped at 2000 records, or 300 when statistics, odds or point-by-point are switched on, because those cost a request per match.
- Schedule mode walks the tournaments running now, so its cost scales with
tournaments rather than dates: asking for three days costs the same as one.
ATP and WTA together are usually a handful of tournaments; adding Challenger
and ITF multiplies that, which is what
maxTournamentsis for. - Rankings return up to 500 players per tour in a single request. Player mode costs one search plus one request per 30 matches.
datesoverridesdayOffsets, and at most 14 dates run at once.- Live mode returns only matches in progress at that moment. Coverage is
broadest during European and Asian daytime and thin overnight, which is a
property of the tennis calendar rather than the Actor. Use
schedulewithstatusFilter: "inprogress"if you would rather have the whole day's context.