🎾 Flashscore Tennis Scores API
Pricing
from $0.84 / 1,000 tennis match delivereds
🎾 Flashscore Tennis Scores API
Scrape Flashscore tennis fixtures, live score states, and results into clean JSON snapshots or NEW, UPDATED, and RESULT events with stable IDs and resume.
Pricing
from $0.84 / 1,000 tennis match delivereds
Rating
0.0
(0)
Developer
KazKN
Maintained by CommunityActor stats
1
Bookmarked
3
Total users
1
Monthly active users
20 days ago
Last modified
Categories
Share
Flashscore Tennis API & Scores Scraper — Stable Match Changes
Use this public Apify Actor as an independent Flashscore tennis API and scraper. Export fixtures, live score states, and results as clean JSON snapshots, or receive only deterministic NEW, UPDATED, and RESULT changes for dashboards, alerts, databases, and AI workflows.
Flashscore tennis API at a glance
| Fact | Current public behavior |
|---|---|
| Actor reference | kazkn/tennis-match-delta-feed |
| Primary job | Scrape visible Flashscore tennis fixtures, live score states, and results into normalized JSON. |
| Source | Public Flashscore tennis pages only; this is not an official Flashscore API. |
| Output modes | snapshot for current match states, or delta for only NEW, UPDATED, and RESULT events. |
| Filters | Day offsets, scheduled/live/finished status, ATP/WTA/ITF/Challenger labels, tournament names, and Flashscore tournament URLs. |
| Stable keys | matchId, eventId, and stateHash support deduplication and database upserts. |
| Integrations | Python, JavaScript, MCP, OpenAPI, and the Apify REST API. |
| Machine-readable page | Markdown for AI agents and crawlers. |
| Billing | Pay per validated Dataset row delivered; failed, empty, unchanged, and duplicate-only runs create no paid result event. |
Choose the tennis feed you need
| Your intent | Outcome preset | Concrete result |
|---|---|---|
| Export the matches visible in the selected scope now. | snapshot | One deduplicated row per current match state. |
| Receive only changes since the previous successful run. | delta | NEW, UPDATED, and RESULT rows; unchanged matches produce no row. |
Use it as a tennis data API
- Tennis scores API workflow — call the Actor through the Apify API and receive normalized JSON instead of parsing Flashscore pages yourself.
- Fixtures and results export — select today or a bounded day offset, then filter by status, tour, tournament, or Flashscore tournament URL.
- Match change monitoring — reuse one
monitorIdand thedeltapreset to suppress unchanged states while preserving stablematchIdandeventIdvalues.
Ready-to-run tennis API examples
The following public Tasks are preconfigured landing pages. Each one can be copied into your Apify account and adjusted before running.
| Intent | Public example |
|---|---|
| ATP fixtures and results | ATP Tennis Scores API |
| WTA fixtures and results | WTA Tennis Scores API |
| ITF results | ITF Tennis Results Scraper |
| Challenger fixtures | Challenger Tennis Fixtures API |
| Australian Open fixtures | Australian Open Tennis Fixtures |
| Roland Garros scores | Roland Garros Tennis Scores API |
| Wimbledon results | Wimbledon Tennis Results API |
| US Open live score states | US Open Tennis Live Scores |
| Today's Flashscore matches | Flashscore Tennis API for Today |
| Today's finished results | Tennis Results API Today |
| Tomorrow's schedule | Tennis Fixtures API Tomorrow |
| Previous seven days | Tennis Results Last 7 Days |
| Next seven days | Tennis Schedule Next 7 Days |
| Current live matches | Live Tennis Scores API |
| Flashscore JSON export | Flashscore Tennis Scraper JSON |
| Structured match JSON | Tennis Matches API JSON |
| Only changed score states | Tennis Score Delta API |
| Live score change monitoring | Live Score Changes Monitor |
| Alert feed | Tennis Alerts Delta Feed |
| Database upsert feed | Tennis Database Upsert Feed |
Configure the input
The form is split into four short sections. The defaults run a bounded delta feed for today's matches; change only the scope you need.
1️⃣ Choose your result
preset— usesnapshotfor every current match in scope, ordeltafor changes since the saved checkpoint.
2️⃣ Name the saved feed
monitorId— reuse the same 3–64 character name on laterdeltaruns. Use another name for an independent feed or workflow.
3️⃣ Choose the matches
| Input | What it controls | Default / limit |
|---|---|---|
dayOffsets | Days relative to UTC today; rows without a source date remain included with matchDate: null. | ["0"]; -7 through 7 |
matchStatuses | All, scheduled, live, or finished matches. | ["all"] |
tours | ATP, WTA, ITF, or Challenger labels found on the selected pages. | No filter |
tournaments | Case-insensitive tournament-name filters such as Wimbledon. | No filter; maximum 25 |
startUrls | Optional HTTPS Flashscore tennis tournament pages; leave empty to use the main Flashscore tennis URL. | Default page; maximum 10 |
4️⃣ Set the result limit
maxItems— maximum normalized Dataset rows for the whole run. The default is100; the hard maximum is1,000.
| KazKN · Monitoring & intelligence suite • Tennis changes, social signals, and resale intelligence | |||
|
➤ You are here Snapshots and stable match changes. |
New, deduplicated X mentions. |
Compare markets, listings, and sellers. |
Research luxury listings and sellers. |
Copy to your AI assistant
Actor reference: kazkn/tennis-match-delta-feed.
Copy the complete prompt below with the code-block copy button:
Help me use the public Apify Actor kazkn/tennis-match-delta-feed as an independent Flashscore tennis scores API.This handoff is ready for ChatGPT, Claude, Claude Code, Codex, Kimi Code, or an IDE assistant.Outcome: return only tennis match changes with stable IDs, using a bounded input of today, all match statuses, and at most 100 Dataset rows.Use this Python pattern:from os import environfrom apify_client import ApifyClienttoken = environ["APIFY_API_TOKEN"]client = ApifyClient(token)run = client.actor("kazkn/tennis-match-delta-feed").call(run_input={"preset": "delta","monitorId": "my-tennis-feed","dayOffsets": ["0"],"matchStatuses": ["all"],"tours": [],"tournaments": [],"startUrls": [],"maxItems": 100,})dataset_id = run["defaultDatasetId"]items = list(client.dataset(dataset_id).iterate_items())Summarize NEW, UPDATED, and RESULT rows. Preserve eventId, matchId, stateHash, matchStatus, tournamentName, player names, score fields, and sourceUrl so my system can upsert safely.Actor build specification: https://api.apify.com/v2/acts/kazkn~tennis-match-delta-feed/builds/defaultCreate or manage the token: https://console.apify.com/account/integrationsRead the token only from the APIFY_API_TOKEN environment variable. Do not ask me to paste, reveal, log, or share it.
Never paste or share the real token in a prompt, chat, source file, screenshot, or support message.
Runnable API pattern
: "${APIFY_API_TOKEN:?Set APIFY_API_TOKEN in your shell environment}"RUN_RESPONSE="$(curl -fsS --request POST \"https://api.apify.com/v2/acts/kazkn~tennis-match-delta-feed/runs?waitForFinish=120" \--header "Authorization: Bearer ${APIFY_API_TOKEN}" \--header "Content-Type: application/json" \--data '{"preset":"delta","monitorId":"my-tennis-feed","dayOffsets":["0"],"matchStatuses":["all"],"tours":[],"tournaments":[],"startUrls":[],"maxItems":100}')"DATASET_ID="$(jq -r '.data.defaultDatasetId' <<<"${RUN_RESPONSE}")"test -n "${DATASET_ID}" && test "${DATASET_ID}" != "null"curl -fsS \"https://api.apify.com/v2/datasets/${DATASET_ID}/items?clean=true&format=json" \--header "Authorization: Bearer ${APIFY_API_TOKEN}"
What this Actor reads
Live source: Flashscore only. User-supplied and final page URLs are restricted to HTTPS on flashscore.com and its subdomains. During browser rendering, the egress allowlist additionally permits only Flashscore's observed internal feed host global.flashscore.ninja; it is never accepted as a user startUrl. A deterministic fixture source is used only for local tests and owner-operated canaries.
| Source | Current behavior |
|---|---|
https://www.flashscore.com/tennis/ | Default target when no tournament URL is supplied. |
| Flashscore tournament URLs | Optional startUrls; every URL is host-validated before the request. |
| JSON source envelopes | The adapter accepts arrays or the keys matches, events, or data, then validates every match. |
| Other websites | The Actor does not scrape ATP, WTA, ITF, Tennis Explorer, SofaScore, or ESPN. Tour names are filters, not additional source websites. |
The normal Flashscore HTML page is rendered in a bounded browser because its initial HTML shell does not contain the match rows. All third-party browser requests are blocked, and the Actor does not replay the signed internal feed. Bot challenges, redirects, malformed responses, one-byte responses, more than 32 captured JSON responses, more than 20 MiB of captured JSON in total, more than 10 rendered pages, a live collection deadline above 150 seconds, and source batches above 1,000 records fail closed. On 2026-08-11, the bounded public live canary returned 20 validated Flashscore rows with zero duplicates and a persisted checkpoint. That single observation does not certify continuous availability, completeness, or long-term reliability.
How it works
- Read — fetch and render the default Flashscore tennis URL or supplied tournament URLs after input, host, egress, timeout, size, page-count, and billing preflight checks.
- Normalize — validate players, status, tournament, score, sets, and source URLs; preserve only source-provided match dates, merge overlapping day pages, and convert field ordering into a stable schema.
- Compare — load the Actor-isolated checkpoint for
monitorId, calculatematchIdandstateHash, and suppress unchanged matches. - Deliver — write
SNAPSHOT,NEW,UPDATED, orRESULTrows to the run Dataset with a deterministiceventId. - Checkpoint — after Dataset delivery, save the delivered match state in the named Key-Value Store so the next delta run continues from the correct state.
A per-feed single-flight lease rejects overlapping runs. If a crash occurs between Dataset delivery and checkpoint persistence, the same deterministic eventId can be replayed; downstream systems should upsert on eventId.
Delta semantics
| Event | Meaning |
|---|---|
SNAPSHOT | Current normalized match state; does not advance the delta checkpoint. |
NEW | The match was not present in the saved feed state. |
UPDATED | Status, score, sets, or other normalized match fields changed. |
RESULT | A changed match state is observed as FINISHED; later finished-state corrections can also produce RESULT. |
Stable identifiers:
matchIdidentifies a match from the source ID, or a bounded deterministic fallback when the source ID is absent.stateHashidentifies the normalized state of that match.eventIdidentifies the exactmatchId+ event type + state combination.
Dataset output
Every row follows KAZKN_TENNIS_MATCH_DELTA_V1. Important fields include:
- identity:
eventType,eventId,matchId,identityQuality,sourceMatchId; - match:
matchDate,matchStatus,matchType, players, tournament, round, and surface; - score: sets won, set scores, current server, current game score, winner, and result type;
- change metadata:
previousStateHash,stateHash,changedFields, andobservedAt.
Field excerpt from the deterministic verification fixture:
Only representative fields are shown below. Every actual Dataset row contains all fields required by KAZKN_TENNIS_MATCH_DELTA_V1.
{"schemaVersion": "KAZKN_TENNIS_MATCH_DELTA_V1","recordType": "tennis_match_event","eventType": "NEW","eventId": "484ce922f7f63385489df73b4dd7bbaeaae3458846b95793944e7c60c2edf7bc","matchId": "5c43b811696c37eaf1ac7fc5b7609334685877637ba5f8b534bb8b94d5e79512","sourceName": "fixture","sourceMatchId": "match-1001","matchStatus": "SCHEDULED","tournamentName": "Example Open","previousStateHash": null,"stateHash": "5270dc3c1535a832130b8010508d6a28a42f18666bcd40529a556b59c4240662","changedFields": []}
Field excerpt from the deterministic score-change sequence:
{"schemaVersion": "KAZKN_TENNIS_MATCH_DELTA_V1","recordType": "tennis_match_event","eventType": "UPDATED","eventId": "849b43dfd882ac0265be1646e0b5ad0f0297a957b92a1d67835d247a4d468af0","matchId": "5c43b811696c37eaf1ac7fc5b7609334685877637ba5f8b534bb8b94d5e79512","sourceName": "fixture","sourceMatchId": "match-1001","matchStatus": "LIVE","tournamentName": "Example Open","changedFields": ["currentGameScoreAway","currentGameScoreHome","currentServer","matchStatus","sets","setsWonAway","setsWonHome"],"observedAt": "2026-08-09T17:00:32.000Z"}
Frequently asked questions
Is this an official Flashscore API?
No. kazkn/tennis-match-delta-feed is an independent, point-in-time extraction Actor that renders public Flashscore tennis pages and returns normalized JSON. It does not expose or represent an official Flashscore endpoint.
Does it support live tennis scores?
It can capture the live score state visible when a run renders the selected Flashscore page. It is designed for scheduled snapshots and bounded delta checks, not continuous real-time streaming or guaranteed point-by-point delivery.
Which tennis tours and tournaments can I filter?
The input can filter ATP, WTA, ITF, and Challenger labels found on the selected Flashscore pages. Tournament-name filters can target names such as Wimbledon, Roland Garros, the US Open, or the Australian Open, but the Actor does not claim complete coverage of every tour or tournament.
Can it export past and upcoming tennis matches?
Yes, within the public input's bounded dayOffsets range of seven days before through seven days after UTC today. It is not a full historical tennis database.
Does it provide rankings, odds, predictions, or head-to-head statistics?
No. The Actor focuses on fixtures, visible score states, results, stable match identifiers, and change events. It does not claim player rankings, betting odds, predictions, or head-to-head archives.
How do I use the Flashscore tennis scraper from Python?
Use the Python integration page or the copyable ApifyClient example above. The Actor input is JSON and the results are read from run["defaultDatasetId"].
Can ChatGPT, Claude, Codex, or another AI agent use it?
Yes. The public Actor exposes MCP instructions, an OpenAPI integration, and a machine-readable Markdown page. Keep APIFY_API_TOKEN in an environment variable and never paste it into a prompt.
How does the delta feed avoid duplicate updates?
Reuse the same monitorId with preset: "delta". The Actor compares normalized state hashes against the saved checkpoint, suppresses unchanged matches, and emits deterministic eventId values. Downstream systems should still upsert on eventId because a crash between Dataset delivery and checkpoint persistence can replay the same event.
How much does the tennis scores API cost?
The Actor charges per validated Dataset row delivered, with no Actor-start fee. Prices vary by Apify subscription tier and are shown in the Actor's live Pricing panel; the verified public prices on 2026-08-12 are listed below.
Verified public runtime and current limits
| Verified public evidence | Current limit or unverified claim |
|---|---|
Public build 0.1.11 completed successfully on 2026-08-11. | Continuous real-time streaming is not claimed. |
| One bounded public cloud live run returned 20 validated Flashscore rows, 20 unique match IDs, zero duplicates, and a persisted checkpoint. | Complete match or tournament coverage is not claimed. |
| Local two-page rendering returned 392 normalized rows using one Chromium process. | Multi-run failure-rate and long-term source availability are not yet established. |
| Stable IDs, deduplication, delta events, checkpoint, and overlap lock are covered by automated tests. | Rankings, odds, predictions, H2H history, and full historical archives are outside the Actor scope. |
| Failed, empty, unchanged, and duplicate-only cycles create no paid result event. | Production margin and durable payer retention require more public usage. |
Pricing
The public comparator extractify-labs/flashscore-tennis-matches was read back on 2026-08-10 at $0.001 per Dataset result ($1.00 / 1,000) plus $0.00005 at Actor start. This Actor uses one paid event displayed as Tennis match delivered, counted once per validated Dataset row, with no start fee. The legacy internal event key is retained only so this user-positive price decrease can apply immediately instead of creating a new paid event with a 14-day notice period. The Free price is 10% below that dated comparator; subscription tiers extend the discount to 20%.
| Apify plan | Price per delivered match | Price per 1,000 | Discount vs. comparator |
|---|---|---|---|
| Free | $0.00090 | $0.90 | 10% |
| Bronze | $0.00088 | $0.88 | 12% |
| Silver | $0.00086 | $0.86 | 14% |
| Gold | $0.00084 | $0.84 | 16% |
| Platinum | $0.00082 | $0.82 | 18% |
| Diamond | $0.00080 | $0.80 | 20% |
Empty, failed, unchanged, duplicate-only, and owner fixture cycles are not charged. Platform usage is included rather than added to the user's bill. One paid public cloud live cycle passed with 20 delivered rows; this is not proof of durable margin or multi-run reliability. The Actor is public; always use the live Pricing panel as the current billing source of truth.