Tennis results are a good dataset and a slightly awkward one: four tours, two formats, matches that stop halfway, and a calendar day that depends on who is asking. Most of this guide is about the last two.
One entity type per run
Results, schedule, players and rankings are separate runs. They have genuinely different fields — a ranking row has a position and points, a match row has two players and a scoreline — and mixing them would give every row the union of four schemas with most columns empty.
| entityType | Rows | Typical size |
|---|---|---|
results | Finished matches for a date range | 150–600 per day |
schedule | Upcoming and in-progress matches | ~200 per day |
players | Profiles, optionally with history | 1 per player |
rankings | ATP or WTA tables | 50 per page |
Step 1 — set the date range
dateFrom and dateTo take YYYY-MM-DD or a relative form: today, yesterday, -7d, +3d. The relative forms are what make a scheduled daily run a fixed input rather than something that has to be templated.
Days are cut at 00:00 UTC, always. That is not a default you can change, and there is a reason — the same date returned 227 matches once and 269 the next time.
Step 2 — choose the tours
ATP singles, ATP doubles, WTA singles and WTA doubles. Leaving all four selected is the cheapest option, because it is a single request per day rather than one per tour — the site returns them together.
Step 3 — decide about detail and odds
includeOdds is also off by default, for a different reason: scores are facts and odds are somebody's licensed product.
Step 4 — run it
{
"entityType": "results",
"dateFrom": "2026-08-01",
"dateTo": "2026-08-07",
"tours": ["atp-single", "atp-double", "wta-single", "wta-double"],
"includeMatchDetail": false,
"maxItems": 5000
}maxItems is a hard cap on delivered rows and defaults to 10,000. For a backfill it has to be raised, and there is a pricing reason to raise it generously rather than in steps — what a season costs.
Reading the output
Every row carries status, which is completed, retired or walkover. The source labels none of those — it is derived, and about 4.6% of matches are affected.
Player names come from the underlying attribute rather than the visible label, which matters on the 17.4% of rows that are doubles — why the visible name is truncated. The full field reference covers the rest.
What a run costs
$0.0015 per row for the first 10,000 rows of a run and $0.0003 after that, plus a $0.0024 surcharge per match when detail is enabled. A week of results is about $4. Failed requests are never charged; they go to the ERRORS record instead.
Four mistakes that waste a run
Leaving `maxItems` at 10,000 for a backfill. It is a hard cap, and it stops the run exactly where the cheaper price tier was about to start.
Enabling match detail for a whole season. One extra request per match, on 148,000 matches, is a different kind of run.
Running one tour at a time. All four in one request costs one request; four runs cost four.
Treating an unfinished match as a completed one. Roughly one match in twenty is not completed, and the scoreline alone does not say so.



