Documentation / Guides

Data freshness

The GreyhoundAPI race lifecycle from scheduled to complete, honest delay metrics, and how to build consumers around results_received_at.

Results reach the pipeline anywhere from minutes to hours after the off — occasionally longer. Rather than pretend otherwise, the API tells you exactly where every race stands.

The lifecycle

scheduled → off → results_pending → complete, with void and abandoned as terminal exceptions. Every race carries a freshness block:

"status": "complete",
"freshness": {
  "first_seen":       "2026-07-07T05:12:10Z",
  "results_received": "2026-07-08T21:03:40Z",
  "results_delay_s":  1060
}

off, results_pending & complete

Greyhound races run in around 30 seconds, so a race stays off only for the brief window it is actually running. Once it has jumped and a short settling period has passed with no final result, the API reports results_pending — the race has run and its result is being processed — and it becomes complete the moment the full finishing order is published. This lets you tell a race that is still to run (scheduled) apart from one that has run and is awaiting its result (results_pending) without inferring anything from the clock yourself. It behaves identically for Great Britain and Australia.

results_pending reflects that a race has run; the speed at which the final result then lands depends on the upstream feed and is reported honestly through the freshness block above and GET /v1/status.

Provisional vs final results

The upstream feed sometimes publishes the winner first and fills the minor placings in shortly after, so a race can read complete before every placing is settled. The result block therefore carries a result_status: provisional while placings are still arriving, and final once every dog that ran has a finishing position. Poll until result_status is final if you need the settled order; the same field is on GET /v1/races/{id}/status.

Build for it

Treat results_received as the event time of a result, not the off-time — that is what GET /v1/results/latest orders by and what the WebSocket stream emits on. A consumer that keys on off-time will believe late results are missing; one that keys on receipt time is always consistent with the pipeline. Live pipeline health is public at GET /v1/status.