
Website Content Crawler
scrape.ly/store/querystone/website-content-crawlerAIDeveloper tools
1 monthly user

Scrape tennis match results, upcoming matches, betting odds, tournaments and player match history from TennisExplorer. ATP, WTA, Challenger and ITF, singles and doubles. No login needed.
Get tennis match results, upcoming matches and betting odds from TennisExplorer as clean, structured data. Pick any date range and tour, or paste a tournament, player or match page, and get every match with players, set-by-set scores, tiebreaks, winner and average odds. No login, no browser, and a fraction of the usual price per match.
| Field | What it does |
|---|---|
matchType | results (finished matches) or upcoming (schedule with odds and head-to-head). |
dateFrom, dateTo | Days to scrape, YYYY-MM-DD. Empty: today and yesterday (results) or today and tomorrow (upcoming). |
tours | atp-single, wta-single, atp-double, wta-double. |
startUrls | Tournament, player, match, results or schedule pages. Replaces the dates and tours. |
maxItems | Cap on matches saved. |
tournamentLevels | main, challenger, itf, utr, other. |
tournamentNames, playerNames | Keep matches whose tournament or player name contains these words. |
includeMatchDetails | Round, surface, full names, rankings, bio, head-to-head and every bookmaker's odds. |
timezone | UTC offset for times and day boundaries (default +0). |
{
"matchType": "results",
"dateFrom": "2026-10-15",
"dateTo": "2026-10-16",
"tours": ["atp-single", "wta-single"],
"tournamentLevels": ["main"],
"maxItems": 100
}
| Field | Description |
|---|---|
matchId, matchUrl | Match id and page. |
date, time, startTimeUtc, timezone | When the match started. |
tournament, tournamentUrl, tournamentCountry | Event and its country code. |
tour, gender, matchType, level | ATP/WTA, men/women, singles/doubles, main/challenger/itf/utr/other. |
round, surface | On tournament and player pages, or with match details. |
player1, player2, player1Url, player2Url, player1Seed, player2Seed | Players (on results pages, player 1 is the winner). |
status | finished, retired, walkover, in progress or scheduled. |
winner, winnerSide, score | Winner and score from player 1's side, such as 6-7(4), 6-4, 6-4. |
resultPlayer1, resultPlayer2, setsPlayer1, setsPlayer2, sets | Sets won, games per set, and per-set tiebreak points. |
oddsPlayer1, oddsPlayer2 | Average decimal odds. |
h2hPlayer1, h2hPlayer2 | Head-to-head wins (upcoming matches and match details). |
player1FullName … player2Plays, bookmakerOdds | With match details: full names, ranking, birthdate, height, weight, playing hand, and current and opening odds per bookmaker. |
{
"matchId": "3353239",
"matchUrl": "https://www.tennisexplorer.com/match-detail/?id=3353239",
"date": "2026-10-20",
"time": "07:35",
"startTimeUtc": "2026-10-20T07:35:00Z",
"timezone": "GMT+0",
"tournament": "Almaty",
"tournamentUrl": "https://www.tennisexplorer.com/almaty/2026/atp-men/",
"tournamentCountry": "KZ",
"tour": "ATP",
"gender": "men",
"matchType": "singles",
"level": "main",
"player1": "Shimabukuro S.",
"player2": "Safiullin R.",
"status": "finished",
"winner": "Shimabukuro S.",
"winnerSide": 1,
"score": "6-7(4), 6-4, 6-4",
"resultPlayer1": 2,
"resultPlayer2": 1,
"setsPlayer1": [6, 6, 6],
"setsPlayer2": [7, 4, 4],
"sets": [
{"set": 1, "player1": 6, "player2": 7, "tiebreakPlayer1": 4, "tiebreakPlayer2": 7},
{"set": 2, "player1": 6, "player2": 4, "tiebreakPlayer1": null, "tiebreakPlayer2": null},
{"set": 3, "player1": 6, "player2": 4, "tiebreakPlayer1": null, "tiebreakPlayer2": null}
],
"oddsPlayer1": 5.44,
"oddsPlayer2": 1.14
}
Pay per match saved:
Examples: 100 results (about one day of ATP and WTA singles) cost $0.60, and 1,000 results cost $6.00 in match fees. Platform usage (compute and proxy traffic) is billed on top and is tiny for this actor: our 20-match test runs used about $0.0004 of usage, because it uses plain HTTP requests on the datacenter proxy. There is no start fee.
Is it legal to scrape TennisExplorer? The actor reads public pages that anyone can open without an account. Check the site's terms and your local laws for how you use the data.
Do I need a login or my own proxy? No. The actor works without a login, and the datacenter proxy included with the platform is enough for this site.
How many matches can I get? A busy day has several hundred matches across ATP, WTA, Challenger and ITF singles. Use a date range for history (up to 366 days per run) and Maximum matches to cap the run.
Why is a field empty? The site does not show every field everywhere: odds are missing for many lower-level matches, round and surface come from tournament and player pages or match details, and head-to-head comes from the schedule or match details. Retirements are inferred from an incomplete score.
Which time zone are the times in?
UTC by default. Pick another offset in Time zone; startTimeUtc is always in UTC.
Can I schedule it or use the API? Yes. Schedule it daily for yesterday's results or tomorrow's schedule, and read the dataset through the API or webhooks.
?annual=2025 to the URL for another year).Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
matchTypeenumOptionaldefault "results"Matches
Results returns finished matches with set scores. Upcoming returns the schedule with odds and head-to-head counts.
dateFromstringOptionalDate from
First day, YYYY-MM-DD. Leave both dates empty for today and yesterday (results) or today and tomorrow (upcoming). With only one date set, that single day is scraped.
dateTostringOptionalDate to
Last day, YYYY-MM-DD (inclusive). Up to 366 days per run.
toursarrayOptionaldefault ["atp-single","wta-single"]Tours
Which match lists to read. Each list covers every level of that tour on the site (main tour, Challenger, ITF and others).
startUrlsarrayOptionalTennisExplorer URLs
Optional. Tournament pages (https://www.tennisexplorer.com/shanghai/2026/atp-men/), player pages (https://www.tennisexplorer.com/player/zverev-6f768/), match pages (https://www.tennisexplorer.com/match-detail/?id=3349123) or results and schedule pages. When set, the dates and tours above are ignored.
maxItemsintegerOptionaldefault 20Maximum matches
Cap on matches saved in this run.
Narrow down the matches that are saved.
tournamentLevelsarrayOptionalTournament levels
Keep only these levels. Leave empty for all levels.
tournamentNamesarrayOptionalTournament names
Keep matches whose tournament name contains one of these words, such as Shanghai or Wimbledon. Case-insensitive.
playerNamesarrayOptionalPlayer names
Keep matches where one of the players' names contains one of these words, such as Zverev. Case-insensitive.
includeMatchDetailsbooleanOptionaldefault falseInclude match details
Open each match page for the round, surface, players' full names, rankings, birthdates, height, weight, playing hand, head-to-head and the odds from every bookmaker with opening odds. Billed as a match with details instead of a basic match.
timezoneenumOptionaldefault "+0"Time zone
UTC offset for match times and day boundaries, such as +0, +1 or -5. Start times are also saved in UTC.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["DATACENTER…Proxy configuration
Proxy used to load TennisExplorer pages. The datacenter proxy works well for this site.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| matchId | string | null | TennisExplorer match id. |
| matchUrl | string | null | Match detail page. |
| date | string | null | Match day, YYYY-MM-DD, in the chosen time zone. |
| time | string | null | Start time, HH:MM, in the chosen time zone. |
| startTimeUtc | string | null | Start time in UTC (ISO 8601). |
| timezone | string | null | Time zone of date and time, such as GMT+0. |
| tournament | string | null | Tournament name. |
| tournamentUrl | string | null | Tournament page. |
| tournamentCountry | string | null | Tournament country code (ISO 3166-1 alpha-2) when shown. |
| tour | string | null | ATP or WTA. |
| gender | string | null | men or women. |
| matchType | string | null | singles or doubles. |
| level | string | null | main, challenger, itf, utr or other. |
| round | string | null | Round, such as quarterfinal. Tournament and player pages, or with match details. |
| surface | string | null | Surface, such as hard or clay. Tournament and player pages, or with match details. |
| player1 | string | null | First player or pair (the winner on results pages). |
| player2 | string | null | Second player or pair. |
| player1Url | string | null | |
| player2Url | string | null | |
| player1Seed | string | null | Seed or entry note, such as 3, WC or Q. |
| player2Seed | string | null | Seed or entry note. |
| status | string | null | finished, retired (inferred from an incomplete score), walkover, in progress or scheduled. |
| winner | string | null | Winner's name. |
| winnerSide | integer | null | 1 or 2. |
| score | string | null | Score from player 1's side, such as 6-7(4), 6-4, 6-4. |
| resultPlayer1 | integer | null | Sets won by player 1. |
| resultPlayer2 | integer | null | Sets won by player 2. |
| setsPlayer1 | array | Games per set, player 1. |
| setsPlayer2 | array | Games per set, player 2. |
| sets | array | Per set: games and tiebreak points of both players. |
| oddsPlayer1 | number | null | Average decimal odds for player 1. |
| oddsPlayer2 | number | null | Average decimal odds for player 2. |
| h2hPlayer1 | integer | null | Head-to-head wins of player 1 (upcoming matches and match details). |
| h2hPlayer2 | integer | null | Head-to-head wins of player 2. |
| player1FullName | string | null | Match details: full name. |
| player2FullName | string | null | Match details: full name. |
| player1Ranking | integer | null | Match details: singles ranking. |
| player2Ranking | integer | null | Match details: singles ranking. |
| player1Birthdate | string | null | Match details: birthdate, YYYY-MM-DD. |
| player2Birthdate | string | null | Match details: birthdate, YYYY-MM-DD. |
| player1Height | integer | null | Match details: height in cm. |
| player2Height | integer | null | Match details: height in cm. |
| player1Weight | integer | null | Match details: weight in kg. |
| player2Weight | integer | null | Match details: weight in kg. |
| player1Plays | string | null | Match details: playing hand. |
| player2Plays | string | null | Match details: playing hand. |
| bookmakerOdds | array | null | Match details: current and opening odds per bookmaker. |
| scrapedAt | string | null | When the row was saved (UTC). |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Match with details | One saved match with round, surface, player bios, rankings, head-to-head and odds per bookmaker (instead of a basic match). | $0.009 |
| Match | One saved tennis match (result or upcoming). | $0.006 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('querystone/tennisexplorer-scraper').call({
"matchType": "results",
"tours": [
"atp-single",
"wta-single"
],
"maxItems": 20,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"DATACENTER"
]
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run querystone/tennisexplorer-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=querystone/tennisexplorer-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
Inputs the developer prepared for common jobs. Open one to see its input, then copy it to your account to run it as-is or adjust it.
Finished matches from 14-15 October 2026 with set scores, winner and odds.
Today's and tomorrow's ATP and WTA singles schedule with odds and head-to-head.
Shanghai 2026 results with round, surface, player rankings and bios, and odds per bookmaker.
Alexander Zverev's 2026 singles matches from his player page.
ITF results from 15 October 2026 across ATP and WTA singles and doubles.
ATP doubles results from 15 October 2026 with times in GMT+1.
Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.