Operated by Sourcelane✓ verified
Scrape tennis fixtures, results, per-bookmaker odds history, match statistics, player profiles, head-to-head records and ATP/WTA rankings from Flashscore, SofaScore and TennisExplorer.
A web-scraping connector that aggregates tennis data from TennisExplorer, Flashscore and SofaScore into structured exports (JSON, CSV, Excel). It extracts fixtures and results, per-bookmaker odds history with timestamped opening and movement across markets (match winner, over/under, Asian handicap, correct score), match-level and match-detail data (set-by-set scores, tiebreaks, structured final scores), live and pre-match odds, point-by-point sequences with serving player, multi-match statistics (aces, double faults, break points, service/return points), player profiles and bios (rankings, age, height/weight, nationality, prize money, career and per-season win/loss by surface, titles), head-to-head records with every mutual match, and ATP/WTA ranking snapshots over time. The connector supports multiple modes (fixtures, results, match details, players, head-to-head, rankings, search) and can route TennisExplorer URLs automatically.
Verified Sep 28, 3:55 AM
$0.004
per result
Up to 100 per call. Only pay for results returned; failed calls are refunded.
Betting models and line-movement archives
Capture opening-to-closing odds per bookmaker and join odds history to match results for model training and analysis.
Tennis analytics
Generate surface-adjusted win probabilities, form and head-to-head features from structured set scores, recent form, and match statistics.
Sports media and content sites
Auto-generate match previews (form, H2H, odds) and recaps (scores, ranking movers).
Fantasy and prediction applications
Supply daily fixture slates, results feeds for scoring, and player biographies for profile pages.
Research results
Produce historical results archives and weekly ranking snapshots for longitudinal analysis.
Any tennisexplorer.com URLs: /matches/, /next/, /results/, /match-detail/?id=…, /player/{slug}/, /mutual/{a}/…
First day to scrape.
Last day, inclusive.
TennisExplorer numeric match ids (e.g.
For the players mode: TennisExplorer slugs like djokovic or full /player/… URLs.
For the h2h mode.
For the searchPlayers mode: part of a player's name, case-insensitive (e.g.
Historical weekly snapshot to read, TennisExplorer only.
Optional settings
| Window | Uptime | Success rate | p50 | p95 | Calls |
|---|---|---|---|---|---|
| 24h | — | — | — | — | 0 |
| 7d | — | — | — | — | 0 |
| 30d | — | — | — | — | 0 |
Call it through Sourcelane's gateway or MCP server. We run the connector, apply your agent's spend guardrails, and bill only the results returned.
Call it via Sourcelane
curl -X POST https://api.usesourcelane.com/v1/call \
-H "Authorization: Bearer sl_live_your_agent_key" \
-H "Content-Type: application/json" \
-d '{"listing":"flashscore-sofascore-tennis-scraper","params":{"maxItems":5},"maxResults":10}'Request params
| Field | Type | Required | Description |
|---|---|---|---|
source | string | optional | Which site to read. TennisExplorer: fixtures, results, per-bookmaker odds history, player profiles, head-to-head, rankings, player search — no proxy needed. Flashscore: one request per day of fixtures/results (±7 days) with surfaces and set scores — no proxy needed. SofaScore: live matches, match statistics, point-by-point, odds, player profiles and rankings — uses a residential proxy automaticall |
mode | string | optional | fixtures = upcoming matches with odds (today by default; SofaScore returns its live feed), results = finished matches with scores and closing odds (yesterday by default), matchDetails = deep per-match records (TennisExplorer: per-bookmaker odds history; SofaScore: statistics, point-by-point, odds), players = player profiles, h2h = head-to-head records (TennisExplorer), rankings = ATP/WTA tables, s |
startUrls | array | optional | Any tennisexplorer.com URLs: /matches/, /next/, /results/, /match-detail/?id=…, /player/{slug}/, /mutual/{a}/{b}/, /ranking/… or /list-players/…. Each URL is auto-classified and routed to the right parser. Leave empty to use Mode instead. |
tourType | string | optional | Which tournaments to include: both tours, or a single tour, singles or doubles. |
dateFrom | string | optional | First day to scrape. Defaults: fixtures = today, results = yesterday. Fixtures for past dates are served from the results pages. Flashscore covers today ±7 days. |
dateTo | string | optional | Last day, inclusive. Defaults to Date from (a single day). Ranges are capped at 62 days per run. |
matchIds | array | optional | TennisExplorer numeric match ids (e.g. 3290771) or /match-detail/?id=… URLs — take them from the matchId field of fixtures/results rows. With source = SofaScore, pass SofaScore event ids instead. |
includeOddsHistory | boolean | optional | Keep the full per-bookmaker odds movement — every price change with timestamp plus the opening price — on match-detail rows, across Home/Away, Over/Under, Asian Handicap and Correct Score. Turn off for lighter rows with current + opening odds only. |
includeRecentForm | boolean | optional | Keep each player's recent-matches block on match-detail rows. |
playerSlugs | array | optional | For the players mode: TennisExplorer slugs like djokovic or full /player/… URLs (find slugs with the searchPlayers mode). With source = SofaScore, pass SofaScore team ids, slugs like alcaraz-carlos, or player names. |
h2hPairs | array | optional | For the h2h mode. One pair per line: djokovic vs alcaraz-5ab70, djokovic, alcaraz-5ab70 or a full /mutual/…/…/ URL. |
searchQuery | string | optional | For the searchPlayers mode: part of a player's name, case-insensitive (e.g. alcaraz). Returns matching players with their slugs/ids and current rank. |
rankingTour | string | optional | Which ranking to walk in rankings mode. |
rankingDate | string | optional | Historical weekly snapshot to read (Mondays), TennisExplorer only. Leave empty for the latest ranking. |
maxItems | integer | optional | Global cap on results rows for the run. You are billed per row, so this is your spend guard. Capped at 100 per call. |
maxConcurrency | integer | optional | Parallel page fetches. 10 is a good default; raise it for large matchDetails batches. |
sofaMaxTournaments | integer | optional | Reserved for SofaScore day fan-out. Currently SofaScore fixtures return the live feed in a single request, so this setting has no effect. |
Each result contains
| Field | Type | Description |
|---|---|---|
type | string | Type |
source | string | Source |
slug | string | — |
playerUrl | string | — |
name | string | — |
country | string | Country |
heightCm | integer | — |
weightKg | integer | — |
age | integer | — |
birthdate | string | — |
sex | string | — |
plays | string | — |
rankSingles | object | — |
rankDoubles | object | — |
photoUrl | string | — |
nextMatch | null | — |
careerBalance | object | — |
seasonBalance | array | — |
careerBalanceDoubles | object | — |
seasonBalanceDoubles | array | — |
titles | array | — |
titlesDoubles | array | — |
injuries | array | — |
sourceUrl | string | Source Url |
scrapedAt | string | Scraped At |
Pick your tool and connect in under a minute. Then just ask — for example: “What are the current odds for this weekend's Premier League matches?”
Connect Claude
Web, desktop and mobile. One click, then confirm.
Adds the Sourcelane MCP server with your key as a header.
claude mcp add --transport http sourcelane https://api.usesourcelane.com/mcp \
--header "Authorization: Bearer sl_live_your_agent_key"Alternative to the connector URL: add to claude_desktop_config.json, then restart Claude.
{
"mcpServers": {
"sourcelane": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.usesourcelane.com/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer sl_live_your_agent_key"
}
}
}
}Add to ~/.cursor/mcp.json (or Windsurf's mcp_config.json).
{
"mcpServers": {
"sourcelane": {
"url": "https://api.usesourcelane.com/mcp",
"headers": {
"Authorization": "Bearer sl_live_your_agent_key"
}
}
}
}Save as .vscode/mcp.json. VS Code prompts for your key once.
{
"servers": {
"sourcelane": {
"type": "http",
"url": "https://api.usesourcelane.com/mcp",
"headers": {
"Authorization": "Bearer ${input:sourcelane-key}"
}
}
},
"inputs": [
{
"type": "promptString",
"id": "sourcelane-key",
"description": "Sourcelane agent key",
"password": true
}
]
}Create a GPT → Actions → Import from URL, then Authentication: API Key, Bearer.
https://usesourcelane.com/openapi.jsonOne POST. Pass maxResults to cap cost.
curl -X POST https://api.usesourcelane.com/v1/call \
-H "Authorization: Bearer sl_live_your_agent_key" \
-H "Content-Type: application/json" \
-d '{"listing":"flashscore-sofascore-tennis-scraper","params":{"maxItems":5},"maxResults":10}'Wrap the REST call as a tool, or point an MCP client at the endpoint.
import requests
res = requests.post(
"https://api.usesourcelane.com/v1/call",
headers={"Authorization": "Bearer sl_live_your_agent_key"},
json={
"listing": "flashscore-sofascore-tennis-scraper",
"params": {"maxItems":5},
"maxResults": 10,
},
timeout=300,
)
body = res.json()
print(body["receipt"]["chargedMicros"], "micro-USD for", body["receipt"]["results"], "results")
print(body["data"])—
0 reviews
Leave a review
Loading reviews…