TennisExplorer Scraper & New-Result Monitor - Odds & Scores avatar

TennisExplorer Scraper & New-Result Monitor - Odds & Scores

Pricing

from $5.48 / 1,000 match returneds

Go to Apify Store
TennisExplorer Scraper & New-Result Monitor - Odds & Scores

TennisExplorer Scraper & New-Result Monitor - Odds & Scores

Turn monitoring on and every later run returns only the matches it has not returned before, so you are never charged for the same match twice. Every TennisExplorer match as clean JSON: set-by-set scores with tiebreaks, decimal odds for both sides, seeds, singles and doubles, ATP and WTA. Unofficial.

Pricing

from $5.48 / 1,000 match returneds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

Share

TennisExplorer Scraper & New-Result Monitor — Odds & Scores

Turn monitoring on and every later run returns only the matches it has not returned before, so you are never charged for the same match twice.

Every match TennisExplorer publishes for a day, as one flat row: set-by-set scores with tiebreak points, decimal odds for both sides, seeds, tournament, and singles or doubles — ATP, WTA, Challenger and ITF together.

Unofficial. This Actor is not affiliated with or endorsed by TennisExplorer. It reads public pages only, and nothing that robots.txt disallows.

What it does

  • 🎾 A whole day in one request. TennisExplorer has no pagination: one day is one page. A busy day carries roughly 200–350 matches across all tours (2026-09-05: 224).
  • 📊 Odds on about 95% of matches. Decimal odds for both sides, exactly as printed (2026-09-05: 212 of 224, ranging 1.03–7.07).
  • 🔁 Monitoring mode. Remembers every match id it has returned and, on later runs, returns only the new ones. Run it on a schedule and pay only for matches you have not received yet.
  • 📅 Ten years of history. Any past day is available (2016-09-05 still returns 356 matches).
  • 👥 Singles and doubles. Doubles are teams on TennisExplorer, with their own team page — they are returned and marked, not skipped (2026-09-05: 161 singles, 63 doubles).
  • 🗓 Scheduled matches too. The matches section returns the day's card, with head-to-head records for most of it (2026-09-06: 574 of 609).

Best for

  • Betting and odds research — every finished match comes with the closing decimal price for both players, so you can rebuild a season's line history.
  • Model training and backtesting — set-by-set scores with tiebreak points, and a flag saying which side is printed first, so a model is never fed a winner it was supposed to predict.
  • Watching a tournament — turn monitoring on and each later run returns only matches it has not returned before.

How fast, and what it costs to run

Measured on this Actor on 2026-09-06 (section: results, tour: all, maxMatches: 120):

Matches returned120 across 9 tournaments
Run time4 seconds
Platform cost of that run$0.0007
Matches carrying both closing odds112 of 120 (93%)
Matches with a seed printed23 of 120 (19%)
Matches with tiebreak points broken out6 of 120 (5%)

One list page carries many matches, so a run of this size costs a fraction of a cent to execute.

What you get in every row

FieldWhat it is
matchId, matchUrlTennisExplorer's own match id and its detail page
date, startTimeLocalThe day you asked for, and the start time exactly as the site prints it
tournament, tournamentUrlThe event this match belongs to
matchTypesingle or double
player1Name / player2NameThe full name as the site spells it in the link title
player1Display / player2DisplayThe shortened name the site shows in the table
player1Slug, player1UrlThe player page, or the doubles-team page for a pair
player1Seed, player2SeedSeed where one is shown (2026-09-05: 107 of 448 sides)
player1SetsWon, player2SetsWonSets won
setsPer set: games for both sides and the tiebreak points
scoreTextThe score as one line, e.g. 3-6 7-6(3) 4-6 7-6(6) 6-3
winner, winnerNameWhich side won
playerOrderwinner-first or as-listed — see below, this matters
player1Odds, player2OddsDecimal odds, null when the page shows none
headToHeadHead-to-head record (scheduled matches only)
isCompletedWhether the match has a score yet

🔴 Read this before you model on the data: the winner comes first

On the results pages TennisExplorer prints the winner on the first line of every match. This was checked on 580 matches across two fixture days and there is not one exception.

So on a finished match:

  • player1 is the player who won, not "the home side" or "the one who served first".
  • player1Odds is therefore the odds that were on the winner, and player2Odds the odds on the loser.

Treating player1 as a neutral side will quietly bias anything you build from it. Every row says which arrangement it is in, in playerOrder: winner-first for finished matches, as-listed for matches that have not started.

What you can do with it

📈 Build a form table. Pull dateFrom to dateTo for a player and get every match with the score, the surface's tournament, and the odds at the time.

🎯 Study closing odds against results. Because the winner is first, player1Odds is the winning price on every finished match — favourite-versus-underdog splits come out of one column.

🔔 Follow results without paying twice. Turn monitoring on, run it hourly during a tournament, and each run returns only the matches that finished since the last one.

🗓 Preview a card. Set the section to matches for the day's schedule with head-to-head records before play starts.

Configure the run

A first run with the defaults reads yesterday's results across all tours:

{
"maxMatches": 50
}

One tournament, one week, singles only:

{
"tour": "atp-single",
"dateFrom": "2026-08-25",
"dateTo": "2026-09-05",
"tournaments": ["US Open"],
"maxMatches": 300
}

Monitoring, on a schedule:

{
"monitoringMode": true,
"maxDays": 3,
"maxMatches": 200
}

Or paste a day page and it wins over every field above:

{
"searchUrl": "https://www.tennisexplorer.com/results/?type=wta-single&year=2026&month=09&day=05"
}

Input reference

Every field is optional; the defaults read yesterday's results across all tours.

FieldTypeDefaultWhat it does
searchUrlstring(empty)Paste a TennisExplorer day page, e.g. https://www.tennisexplorer.com/results/?type=atp-single&year=2026&month=09&day=05 . When set, it wins: the section, tour and day in the…
sectionstringresultsresults = finished matches with scores and odds. matches = the day's card, which mixes matches not started yet with ones already finished.
tourstringallWhich table to read. On 2026-09-05 all = 224 matches = atp-single 89 + atp-double 39 + wta-single 72 + wta-double 24, so all also includes Challenger and ITF events.…
dateFromstring(empty)First day to read. Empty = yesterday for results, today for scheduled matches. There is no pagination on TennisExplorer: one day is one page, so a range is read one day at a…
dateTostring(empty)Last day to read. Empty = same as the first day. Days in the future have no results yet and come back as an empty-day row that is not charged.
maxDaysinteger0Hard cap on how many days are requested, counted from the newest. 0 = read the whole range. Monitoring runs with no dates set use 3. Reading a day is free; only returned…
maxMatchesinteger50How many matches to return. You are charged for the rows you actually receive. A busy day carries roughly 200-350 matches across all tours.
monitoringModebooleanfalseOff = return the matches of the days you asked for. On = remember every match id already returned and, on later runs, return only the ones that are new, so the same match is…
resetMonitoringStatebooleanfalseClear the remembered match ids before this run, so everything counts as new again. Use it after changing what you follow.
playersarray[]Keep a match only if one of these appears in either side's name or slug (case-insensitive, partial). Example: djokovic, swiatek. Doubles teams are matched on the team name too.
tournamentsarray[]Keep a match only if the tournament name contains one of these (case-insensitive, partial). Example: US Open, Challenger.
matchTypesarray[]Keep only singles or only doubles. Empty = both. Doubles are teams on TennisExplorer and have a team page rather than a player page.
keywordsarray[]Keep a match only if one (Any) or all (All) of these appear in the tournament name, either player's name or the score.
keywordMatchstringanyAny = at least one keyword. All = every keyword.
excludeKeywordsarray[]Drop a match if any of these appear in the same fields.
minOddsinteger0Keep a match only if at least one side is quoted at or above this. 0 = no limit. Odds are decimal (1.03 to 7.07 on 2026-09-05, median 1.56) and are present on about 95% of…
maxOddsinteger0Keep a match only if at least one side is quoted at or below this. 0 = no limit.
requireOddsbooleanfalseDrop matches with no odds shown on the page. About 5% of matches have none.
onlyCompletedbooleanfalseKeep only matches that have a score. The scheduled-matches section mixes finished and not-yet-started matches in one table.
onlyUpcomingbooleanfalseKeep only matches with no score yet.
useProxybooleanfalseOff by default: TennisExplorer answered 200 from a plain Apify datacentre address when this Actor was built (2026-09-06). If the site starts answering 403, 429 or 503, the…

What this Actor refuses to guess

TennisExplorer has two habits that quietly produce wrong data, and this Actor checks for both before it asks:

  • An impossible day answers HTTP 200. Ask for 2026-02-30 and the site redirects to today and serves today's matches. Nothing tells you the date was dropped. The day is validated before the request, and the address the site actually landed on is checked afterwards; if the date was dropped you get a no-such-search row, never today's matches labelled as yours.
  • An unknown tour is not rejected — it is ignored. Ask for type=whatever and you get every match of the day, which looks exactly like a filter that matched everything. Only the five tours the site really has are accepted.

A day with no matches, a day the site would not answer for, filters that matched nothing, and a page that could not be read each come back as their own row with the reason written out, and none of them are charged.

Pricing

Pay per result: you are charged for the match rows you actually receive. Rows that only explain why there is nothing (no-results, no-such-search, unreadable, no-filter-match, no-new-matches) are never charged.

Reading pages is free — only returned matches cost anything, so a wide date range with a small maxMatches is cheap.

Questions

Are the odds the opening or the closing price? They are the prices TennisExplorer prints next to a finished match, which are the closing prices. oddsText keeps the site's own text so you can check. 112 of the 120 matches in the run above carried both.

Why is headToHead empty? Because it is only printed on the schedule, not on the results pages. Run section: upcoming to get it. This Actor does not copy a value across sections to make a column look full.

How do I avoid training a model on the answer? Finished matches are printed winner-first on the site. Every row carries playerOrder, and it was winner-first for 120 of 120 matches in the run above. Use it, or use winner and winnerName directly — do not assume player 1 is the home side.

Do I get charged for days with no matches? No. A day with no play, a filter that matched nothing, and a page that could not be read each come back as a row with the reason, and none of them are charged.

Can I follow a single player or tournament? Yes — players and tournaments filter locally after the page is read, so the filter is applied to the rows you can see rather than to a search box that might ignore it.

How this differs from other tennis scrapers

  • It says which side is printed first. Finished matches on this site are winner-first; a scraper that maps them to home/away hands you the answer inside the features.
  • It keeps the site's own text next to the parsed values (oddsText, resultRaw, scoreText), so any number can be checked against what was printed.
  • It does not fill columns across sections. headToHead stays empty on results pages instead of being borrowed from elsewhere.
  • Empty days are explained, not billed.

Notes on the data

  • Start times are not converted. The page carries no time zone and no epoch, so the time is returned as the site prints it (23:40). Converting it would invent a fact.
  • Odds are decimal and are returned only when a number is actually printed. About 5% of matches have none; those rows have null, not 0, and filters on odds never drop them.
  • all includes more than ATP and WTA. On 2026-09-05, all = 224 = ATP singles 89 + ATP doubles 39 + WTA singles 72 + WTA doubles 24, which on that day accounted for all of it; on other days all also carries Challenger and ITF events.
  • No personal contact data. The pages carry match records only; no e-mail address or phone number appears in any row, and a test fails if one ever does.

Every number in this README is checked

The fixtures in test/fixtures/ are the real pages this Actor was built from (2026-09-06). The test suite re-counts every figure quoted above — 224, 89, 39, 356, 212, 107, 161, 63, 574, 609 — so if TennisExplorer changes its markup, the tests fail rather than the data going quietly wrong.