---
title: "What the results field coverage actually is"
method: GET
path: "/v1/racing/results/coverage"
tags: ["Racing"]
---

# What the results field coverage actually is

`GET /v1/racing/results/coverage`

## Request

- Base URL: `https://api.puntersedge.online`
- URL: `https://api.puntersedge.online/v1/racing/results/coverage`
- Auth: API key in header `X-API-Key`

Cost: 1 credit. The results store's own measurement of its FULL-FIELD coverage, per
Sydney day, category and venue — the aggregate answer to the question `field_status`
answers per race on /v1/racing/results.

`runners: null` on its own can mean several
different things: a fill pass that has not run yet (`pending`), a pass that has been and
gone while the collector keeps re-attempting the row (`overdue`), a row past its
collector's retry horizon so that no scheduled pass still selects it (`unavailable`), a
racing code no collector exists for (`unsupported` — since 2026-10-04 only foreign races an
AU book listed; AU harness and both NZ codes, 1,254 of the 5,577 stored results as at
2026-09-10, are collected from TAB New Zealand from that day), and a race that did not run
(`not_applicable`). Counting them separately is what lets you decide between polling,
reconciling and giving up, without paging the results themselves.

Every count comes from the same function that sets `field_status` on each race, applied
to the rows in the window at request time, so this summary and the races it summarises
can never disagree. Nothing holds a race in `pending` indefinitely: `pending` ends at the
normal pass, `overdue` ends at the collector's own candidate horizon.

READ THE PERCENTAGES CAREFULLY. `complete_pct` and `supported_complete_pct` are NULL, not
0.0, when their denominator is 0 — an empty window, or one holding only codes we do not
collect. A `days=1` window is empty for the first hours of every Sydney day, and a monitor
that treated a fabricated 0.0 as real coverage would page every night. `collectable` is
published alongside them so 0-of-0 is never mistaken for 0-of-many.

Days are AUSTRALIAN EASTERN calendar days (Australia/Sydney), the same day a meeting is
advertised under, and `to_day` is today in Sydney — a part day whose races are mostly
still `pending`, which is normal and not a gap. Read `by_day` for the day-by-day picture
and `venues_incomplete` for the venue-days that are genuinely short.

`archive_races_without_result` looks from the other side: AU and NZ races in the
closing-line archive, in this window and at least three hours old, that have no result row
at all (`archive_races_in_window` is its denominator). They are not in `races`, which counts
stored results only. `archive_races_result_unlinked` is the part of that count whose result
does exist under another race_id — reachable by venue, date and start time, not by race_id.

Two things the field states cannot say on their own: whether the RESULT is in (each category
and day row carries `result_final`, independent of the field), and whether a late field is
late because its source is refusing our collector (`field_sources_refused`, and
`overdue_source_refused` on each row, a subset of `overdue`).

Sibling endpoint: /v1/racing/closing-lines/coverage does the same job for the price
archive.

## Query parameters

- `days` integer: Sydney days to count, ending with today (a part day).

## Headers

- `X-API-Key` string
- `X-RapidAPI-Proxy-Secret` string

## Response `200`

Successful Response

- ResultsCoverageOut
  - `as_of` string, required: When these counts were computed (UTC).
  - `days` integer, required: How many Sydney days the window spans, ending today.
  - `from_day` string, required: First Sydney date counted (inclusive).
  - `to_day` string, required: Last Sydney date counted — today in Sydney, so it is a PART day and its races are mostly `pending`.
  - `coverage_from` string, nullable: Start time of the earliest result retained anywhere in the store, the same value /v1/racing/results puts on every row. ONE GLOBAL VALUE: it is the oldest Australian card, and it is not when any other lane began — South African results, for instance, start months later. Read `results_floors` for the per-lane answer.
  - `results_floors` object[]: From when a RESULT exists at all, per country and category, MEASURED from the store rather than typed (2026-10-17): `country`, `category`, `from` (the date of the earliest stored result for that lane, the race's OWN date — so a Great Britain, Ireland or South Africa lane is named by its own card, not by the Sydney day it fell on; `from_day` and `to_day` above are Sydney days, which is a different question) and `results` (how many it holds). This is the figure to read before settling or scoring a lane. It is NOT `coverage_from`, which is one global value — the earliest result anywhere, currently an Australian card — and so says nothing about when a newer lane began. It is NOT `field_floors` either: that is when the FULL FIELD began, which can be later than the result. Australian thoroughbreds have results from 2026-08-15 and fields only from 2026-09-01, so neither value can be inferred from the other. A lane absent from this list has no result in the store at any date: races in it are priced and archived but cannot be settled here, which is true of every country outside Australia, New Zealand, Great Britain, Ireland and South Africa.
  - `field_floors` object[]: Machine-readable twin of `field_scope` (2026-10-15): one row per country and category that has a full-field collector — `country`, `category`, `field_source` (the machine value `field_source` carries on /v1/racing/results), `source_name` and `from` (the earliest Sydney card a stored field exists for, measured). Codes outside this list hold placegetters only.
  - `races` integer, required: Every stored result in the window, all codes and all states. races == complete + pending + overdue + unavailable + unsupported + not_applicable, always.
  - `complete` integer, required: Races carrying a `runners` field.
  - `pending` integer, required: A collector exists and the pass that normally fills the race has not been yet.
  - `overdue` integer, required: That pass has been and gone with no field written, but the collector still re-attempts the row. NOT a terminal state — see `field_status` on /v1/racing/results for the horizons.
  - `unavailable` integer, required: Past the collector's own retry horizon: no scheduled pass still selects the row.
  - `unsupported` integer, required: No collector has ever existed for the code.
  - `not_applicable` integer, required: The race did not run (abandoned, postponed or transferred) and has no field — nothing to collect, not a gap.
  - `collectable` integer, required: races - unsupported - not_applicable: the races in this window that could carry a field at all. It is the denominator of `supported_complete_pct`, published so that a null percentage is readable as 0-of-0 rather than guessed at.
  - `complete_pct` number, nullable: complete / races as a percentage, across the whole window including codes that can never carry a field. NULL — not 0.0 — when `races` is 0. An empty window has no coverage figure, and 0.0 there is a fabricated number that reads as total failure: a `days=1` window called between Sydney midnight and the day's first result is empty on most days (the median first result of a Sydney day lands at 10:50 local), so this is an ordinary case and not a corner.
  - `supported_complete_pct` number, nullable: complete / collectable: the figure to read if you only care about the codes we collect fields for. The raw `complete_pct` is dragged down by stored races in codes that had no collector before 2026-10-04 (AU harness and both NZ codes, 1,254 rows as at 2026-09-10). An AU harness result still carrying the 2026-09-29..10-04 pre-race board copy (`origin: board`) counts as complete AND collectable here, so on such a window separate them with `by_category`. NULL — not 0.0 — when `collectable` is 0, which happens on an empty window or one holding only foreign races. If you alert on this figure, treat null as 'no data' and never as 'zero coverage'.
  - `by_category` object[], required: One row per country + category over the window: {country, category, field_source, races, complete, pending, overdue, unavailable, unsupported, not_applicable}, which sum to `races`, plus four keys added 2026-10-19 that are NOT part of that sum: `result_final` (races whose result is final — placings, and dividends where the book publishes them, are in; this is independent of the full field), `overdue_source_refused` (the part of `overdue` whose source is currently refusing our collector, see `field_sources_refused`), `oldest_overdue_age_h` (hours since the start of the oldest `overdue` race, null when none) and `refused_since` (UTC, set while this row's source refuses us). Since 2026-10-20 each row also carries `result_completeness` {provisional, final_placings, complete_full_field, not_run}, a separate partition that also sums to the row's `races`.
  - `by_day` object[], required: One row per Sydney day + country + category, newest first, with the same counts. This is the day-by-day answer to 'is yesterday finished yet'.
  - `venues_incomplete` object[], required: Venue-days still missing a field in a code we DO collect: {day, venue, venue_id, category, country, settled} plus every counter above (races, complete, pending, overdue, unavailable, unsupported, not_applicable), which sum to `races` exactly. Ordered worst first: most `unavailable`, then the biggest outstanding shortfall, then oldest day. `settled` is true when nothing on that venue-day can still fill (no `pending`, no `overdue`) — that is the difference between a genuine terminal gap and a card simply still in progress, and without it a day mid-fill outranks a real one. A venue-day is listed when complete + not_applicable < races: an abandoned card has nothing to collect and is NOT a shortfall. A venue-day whose only gap is `unsupported` is deliberately absent — it would be most of the list and it is already counted above. Capped at 200 entries; `venues_incomplete_truncated` says when the cap bit.
  - `venues_incomplete_truncated` boolean
  - `field_scope` string, required: Prose: which codes are collected, from when, and what the never-collected codes are.
  - `archive_races_in_window` integer: AU and NZ closing-line archive races that started in this window at least 3 hours ago.
  - `archive_races_without_result` integer: Of archive_races_in_window, races with no result row at all: a price history with nothing to settle it against. Not counted in `races`, which counts stored results only.
  - `archive_races_result_unlinked` integer, nullable: Of archive_races_without_result, races for which a result DOES exist but under a different race_id (matched on category, a start within two minutes and the venue's first word — 'Mt Gambier' = 'Mount Gambier'). A join on race_id misses them; a join on venue, date and start time finds them. The rest of archive_races_without_result have no result at all — typically a race abandoned after it was priced, or a meeting the results feed never published. Added 2026-10-19; null when not computed.
  - `result_completeness` object: Added 2026-10-20: the window's races by RESULT completeness — `provisional`, `final_placings`, `complete_full_field`, `not_run`, the `completeness.state` values on /v1/racing/results. A SECOND partition of the same races, alongside the field states: provisional + final_placings + complete_full_field + not_run == races, always, and every `by_category` and `by_day` row carries the same object summing to its own `races`. `complete_full_field` is final AND carrying a field, so it can be smaller than `complete` (which counts a field on any row).
  - `field_sources_refused` object[]: Full-field sources currently refusing our collector (2026-10-19): one row per source with `field_source`, `source_name`, `http_status`, `refused_since` (the first refused run of the current streak, UTC) and `checked_at` (the latest run). Races of that source whose fill fell inside the refusal stay `overdue` and then `unavailable` and say so in `field_note`; their placings and deductions are unaffected. Empty when every source is serving.

## Other responses

- `401`: Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors
- `402`: Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing
- `422`: Validation Error
- `429`: Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits
- `500`: Unexpected server error. Safe to retry with backoff.

---

[API](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api.md) · [All operations](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api/llms.txt) · [OpenAPI document](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api/revisions/f35b6aab1946?raw)
