When did a feed last complete an import?
GET /api/v2/source-health reports, for each registered broadcast feed in a market, the latest accepted import and how the most recent run ended. It is live. An import is a record that data was received and processed; it is not independent verification of any listing.
Request
GET /api/v2/source-health?market=GB&sport_ids=1
x-api-key: fg_YOUR_SECRET_KEYcurl --get 'https://worldsportsapi.com/api/v2/source-health' \
-H "x-api-key: $SPORT_API_KEY" \
--data-urlencode 'market=GB' \
--data-urlencode 'sport_ids=1'| Parameter | Required | Meaning |
|---|---|---|
market | Yes | A publicly supported market code, such as GB. See /api/v2/markets. |
sport_ids | No | Repeat for up to 100 positive 32-bit sport IDs. Only feeds that cover one of them are returned. |
Same key, origin and allowance rules as the other v2 reads. Errors: 401 or 403 for the key or origin; 404 if the market is not publicly supported or v2 reads are off; 422 for a missing market or invalid sport_ids; 429 over your allowance; 503 with Retry-After while activation is paused.
The answer is a list with one row per registered broadcast feed in the market. No matching feed returns [], which means freshness is unknown, never fresh: a sport with no registered feed in the market has no row, and you should say you cannot tell, not show a default time. Source names, URLs, configuration and error details are never returned. Instants are absolute and carry an offset; convert them to your viewer’s timezone for display.
[
{
"source_class": "listings",
"attribution": null,
"enabled": true,
"sport_ids": [
1
],
"last_completed_at": "2026-10-14T03:04:12Z",
"captured_at": "2026-10-14T03:00:41Z",
"coverage_start": "2026-10-14",
"coverage_end": "2026-10-28",
"last_attempt_at": "2026-10-14T03:00:02Z",
"latest_outcome": "complete",
"unresolved_items": 0,
"stale_after_hours": 36
},
{
"source_class": "schedule",
"attribution": null,
"enabled": true,
"sport_ids": [
1
],
"last_completed_at": "2026-10-14T03:03:50Z",
"captured_at": "2026-10-14T03:00:20Z",
"coverage_start": "2026-10-14",
"coverage_end": "2026-11-14",
"last_attempt_at": "2026-10-14T03:00:03Z",
"latest_outcome": "partial",
"unresolved_items": 64,
"stale_after_hours": 36
}
]Fields
| Field | Type | Meaning |
|---|---|---|
source_class | schedule, aggregator, listings, community, editorial or null | The kind of source, not its name. Null when none is assigned. |
attribution | string or null | A provider name, only where a licence requires naming it. Null for every feed today. |
enabled | boolean | The feed is switched on. A disabled feed keeps its last import. |
sport_ids | integer list | The sports the feed covers in this market. |
last_completed_at | instant with offset, or null | When the latest completed import finished. Null if there has been none. Never a fetch or cache time. |
captured_at | instant with offset, or null | When the source was acquired for that import. |
coverage_start, coverage_end | date or null | The window that import declared. |
last_attempt_at | instant with offset, or null | When the feed’s latest run of any outcome started. Null if it has no runs. |
latest_outcome | enum, below | How the latest run ended. |
unresolved_items | integer, 0 or more | Items awaiting review from the import that latest_outcome describes; from the last completed import when the latest run published nothing. |
stale_after_hours | integer, 1 or more | Hours after last_completed_at at which to treat the feed as stale. 36 unless the feed’s ingestion schedule sets a different freshness window. |
A completed import is a run the API accepted, that was not a preview, and that finished completed or completed_with_errors. It counts however many items it left in review: review items are unresolved references and fixtures, and they do not make the rest of the import unpublished.
Outcome of the latest run
| Value | Meaning |
|---|---|
complete | Accepted, finished completed, nothing in review. |
partial | Accepted, finished completed_with_errors: some records failed and the rest were published. Takes precedence over needs_review. |
needs_review | Accepted, finished completed, and unresolved_items is above zero. |
failed | The run failed, was rejected, or finished without an accepted result. last_completed_at still shows the previous import, if any. |
preview_only | The latest run was a preview and published nothing. last_completed_at still shows the last real import, if any. |
running | The latest run is received or processing. |
none | The feed has no runs. |
Compare now − last_completed_at with stale_after_hours; the API returns no stale flag. A feed whose last_completed_at is null is unknown, not stale. A partial or needs_review feed with a recent last_completed_at is current but may have listings awaiting review. Say so without calling the feed late.
source_class values: schedule (read directly from a published fixture list or broadcast schedule), aggregator (a sports data service compiling many competitions), listings (a TV guide or EPG), community (crowd-maintained or open data) and editorial (checked or entered by people).
Five events, and what each does not mean
“Updated” can describe five different events. Only one of them is what last_completed_at records. If you show a time to people, name the event, for example “listings imported at 03:04”, and avoid “updated” or “verified”.
| Event | What it is | What it does not mean | Where you see it |
|---|---|---|---|
| Scheduled refresh | A feed is due to be fetched on its routine, which is normally about once a day. | That a fetch happened or succeeded, that anything changed, or a time you can rely on. Extra runs happen, and some days are missed. | Not reported. last_attempt_at shows when a run actually started. |
| Completed import | A run the API accepted, not a preview, finished completed or completed_with_errors. | That any fixture or listing changed (the data can be identical), that every listing was published or checked (see unresolved_items), or that your page shows it yet. | last_completed_at and captured_at. |
| Data change | A fixture or listing actually changed: a kickoff moved, a channel was added. | That an import happened. An import can bring no change. | Not published for fixtures. /fixtures/merges and /channels/changes report only merges and channel catalogue changes. |
| Page build | A website or app generated its pages, with the health it held at that moment. | That the API was asked at that moment, or that the page is current now. | Your own build log. The API has no knowledge of it. |
| App fetch | Your client requested data from the API and got an answer. | That the underlying data is new: a fetch of old data is still a fetch. | Your own “fetched at” time. |
Status
Live: /api/v2/source-health answers for GB and IE, with the fields above. Built, off: the “Source updates” display on Where Is Match pages, which reads this endpoint. It is available per market when enabled and is currently off for GB and IE. See the 14 October release note.