Tennis Results, Fixtures, Live Scores & Rankings avatar

Tennis Results, Fixtures, Live Scores & Rankings

Pricing

$6.00 / 1,000 record scrapeds

Go to Apify Store
Tennis Results, Fixtures, Live Scores & Rankings

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

Abhinav Gupta

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 hours ago

Last modified

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 maxTournaments is for.
  • Rankings return up to 500 players per tour in a single request. Player mode costs one search plus one request per 30 matches.
  • dates overrides dayOffsets, 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 schedule with statusFilter: "inprogress" if you would rather have the whole day's context.