Tennis Scores: ATP, WTA and Challenger Results avatar

Tennis Scores: ATP, WTA and Challenger Results

Pricing

from $1.00 / 1,000 matches

Go to Apify Store
Tennis Scores: ATP, WTA and Challenger Results

Tennis Scores: ATP, WTA and Challenger Results

Daily tennis results for analytics, dashboards, research and media apps. ATP, WTA and Challenger singles and doubles with set scores and tiebreaks, plus automatic failover to backup sources.

Pricing

from $1.00 / 1,000 matches

Rating

0.0

(0)

Developer

Quill Data

Quill Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Categories

Security

Limited permissions

Share

Tennis Scores: ATP, WTA and Challenger Results with Source Failover

Daily tennis scoreboards as clean dataset rows: one row per match, with set-by-set games, tiebreak points, status and winner. Built for sports analytics, dashboards, research projects and media apps that need a steady feed of public results.

The Actor reads one primary scoreboard and keeps going when it breaks. If the primary errors, is rate limited, times out, changes its format, or returns nothing for a date, the run switches to backup sources automatically and marks every row it filled that way.

What you get

  • Tours: ATP, WTA and ATP Challenger. Singles and doubles.
  • Match states: scheduled, live (with the current set), finished, retired, walkover, cancelled.
  • Scores: games per set, tiebreak points, sets won, a score line such as 6-7 4-6, winner, match duration where published.
  • Players: public name, nationality and ranking when the source shows them. No other personal data.
  • Optional match stats (aces, double faults, break points, serve points) when the primary source publishes them.
  • Provenance on every row: which source served it and whether a backup was used.

Coverage by source

SourceToursDoublesLiveTiebreaksRoundStatsRequests per date
365scores (primary)ATP, WTA, Challengeryesyesyesyesyes, optional1 (+1 per match for stats)
livescore (backup 1)ATP, WTA, Challengeryesyesyesnono1
espn (backup 2)ATP, WTAyesyesyesyesno2
wta (backup 3)WTA onlyyespartialloser points only, winner side derivedyesno1 + one per WTA event that week

Challenger results come only from 365scores or livescore. If both are down, Challenger rows are missing for that date and the log says so. The WTA backup has no match stats, and stats in general exist only on 365scores rows.

How failover works

  1. Sources are tried in the order of sources (default 365scores, livescore, espn, wta).
  2. When the primary serves a date, no backup is contacted at all (unless crossCheck is on).
  3. When it fails, backups fill the tours they cover, one after another, until every requested tour is covered or the list ends.
  4. Rows from a backup carry fallback_used: true and a short fallback_reason, e.g. 365scores: HTTP 429.

Triggers: HTTP errors and 5xx after retries, HTTP 429, timeouts, invalid JSON, a changed payload shape (parse errors or more than 20% of rows failing validation), and an empty scoreboard or no rows for the requested tours.

Input

FieldDefaultNotes
datestoday (UTC)YYYY-MM-DD, at most 7 dates
circuitsATP, WTA, ChallengerDoubles boards map onto the same tour
sources365scores, livescore, espn, wtaOrder is priority. The first source is primary. Later sources are backups
includeDoublestrueSet false to keep singles only
statusesscheduled, live, finishedWalkovers and retirements count as finished
includeStatsfalse365scores only. One extra request per live or finished match that publishes stats
maxMatches2001–2000, across all dates
playerNamesemptyCase-insensitive substring on either player
requestDelaySecs2Minimum 1 second from one request to the next
maxRequestsPerRun15010–1000. Hard cap on HTTP requests in one run across all sources (stats requests included)
timezoneUTCSent as timezoneName on 365scores
crossCheckfalseCompare finished scores with the first backup that covers a selected tour
simulateFailureemptyTesting only. Named sources fail before any request
healthCheckfalseCheck sources and skip the dataset. No charge
healthCheckDateyesterday UTCYYYY-MM-DD used when healthCheck is true

Input example

{
"dates": ["2026-10-21"],
"circuits": ["ATP", "WTA", "Challenger"],
"statuses": ["finished"],
"includeDoubles": true,
"maxMatches": 200
}

Output example

A real row from a cloud test run on 2026-10-22:

{
"match_id": "4878233",
"source": "365scores",
"date_requested": "2026-10-21",
"start_time_utc": "2026-10-21T03:03:33Z",
"circuit": "Challenger",
"discipline": "singles",
"tournament": "Cali",
"tournament_id": 6943,
"round": "Round of 32",
"status": "finished",
"status_text": "Ended",
"player1": {
"name": "Federico Coria",
"id": 47314,
"country": "Argentina",
"ranking": 746
},
"player2": {
"name": "Nicolas Mejia",
"id": 51765,
"country": "Colombia",
"ranking": 115
},
"sets_won_p1": 0,
"sets_won_p2": 2,
"set_scores": [
{
"set": 1,
"p1": 6,
"p2": 7,
"tiebreak_p1": 4,
"tiebreak_p2": 7,
"duration": "01:11"
},
{
"set": 2,
"p1": 4,
"p2": 6,
"tiebreak_p1": null,
"tiebreak_p2": null,
"duration": "49'"
}
],
"score_text": "6-7 4-6",
"winner": 2,
"current_set": null,
"match_duration": "02:00",
"stats": null,
"match_url": "https://www.365scores.com/en/tennis/match/cali/federico-coria-nicolas-mejia/4878233",
"scraped_at": "2026-10-22T15:07:09Z",
"fallback_used": false,
"fallback_reason": null,
"verified_by": null,
"crosscheck": null
}

Extra fields:

  • source: the source that served the row.
  • fallback_used and fallback_reason: whether a backup supplied the row, and why the earlier sources were skipped.
  • verified_by and crosscheck: filled only when crossCheck is on. crosscheck is match, mismatch or not_found; verified_by lists the backup that agreed.

Fields a source does not publish are null. match_id, source, date_requested and scraped_at are always set.

Health check

Set "healthCheck": true to test every source on a recent finished date (healthCheckDate, default yesterday UTC). The run pushes no rows and charges nothing. It saves a report under the key HEALTH_REPORT in the default key-value store, and its status line reads like health: 365scores PASS, livescore PASS, espn PASS, wta PASS. The run fails if any checked source fails.

The same check runs outside Apify:

python scripts/health_check.py --date 2026-10-21

Exit code 0 means all sources passed. For monitoring, start the Actor once a day from an Apify schedule with {"healthCheck": true}, or call the script from cron.

Pricing

Pay per event: $0.001 per match row. Nothing is charged for health checks, for dates where every source failed, or for empty results. A failed stats request still returns the match, with stats set to null.

Request etiquette

Each source has its own queue: one request at a time, at least 1–2 seconds apart plus a random pause, and backups stay idle while the primary works. HTTP 429 honors Retry-After (one retry when it is 30 seconds or less), server errors get two retries with growing pauses, and 403 is never retried. maxRequestsPerRun caps the total requests of a run.

Data sources

Scores come from public JSON scoreboards published by 365Scores, LiveScore, ESPN and the WTA. No login, key or browser is used. Each publisher has its own terms of use, and some of them restrict automated access or commercial reuse; you are responsible for how you use the data. This Actor is not affiliated with or endorsed by 365Scores, LiveScore, ESPN, the WTA or the ATP.

Also from Quill Data

Limits

  • Live scores are a snapshot at run time. Schedule the Actor for regular updates.
  • Up to 7 dates per run, UTC calendar days.
  • Round names are not available from the livescore backup.