Documentation / Guides

Changelog

What changed and when: new endpoints, fields and platform features. Additive changes only within v1.

Dates are UTC. Within v1 the contract only gains fields — nothing documented here is removed or renamed without a version bump. Machine-readable spec: OpenAPI 3.1.

2026-08-20 — The free sandbox now covers every track

  • The sandbox key was scoped to three tracks — Romford and Nottingham in GB, Sandown Park in AU. That restriction is gone: a free key now reaches every GB and AU track in the API, the same list a live key sees.
  • Nothing else about the free tier changed. It still covers the race and track endpoints only, still serves races between 24 hours and 7 days old, and is still capped at 60 requests a minute and 500 a day. The limit on a free key is when, not where.
  • Why: the track restriction was costing more than it protected. Someone evaluating the API almost always wants to look up a course they already know, and if that course was not one of the three they had no way to tell whether the data existed at all — a missing track and an empty response look identical from outside. The data window is what separates the free tier from the paid one, and it is untouched.
  • If you hold a sandbox key, no action is needed and nothing you have already built will break — this only widens what your existing key resolves. Requests for tracks that previously returned 403 upgrade_required now return data.
  • The sandbox notice attached to every free-key response no longer claims a track limit, and the sandbox scope is now declared in one place that the gate, the notice and the published documentation all read — so what the pricing page says the free key covers is what the API enforces.

2026-08-19 — Owner statistics — including which yards an ownership actually wins with

  • New endpoint GET /v1/owners/{owner_id}/stats. Owners had two endpoints against the trainers' four; this closes most of that gap. Strike rate for one ownership split by track, distance, trap, grade and going, over a rolling window.
  • The split unique to this endpoint is by_trainer — runs, wins and strike rate for every yard the ownership has runners with. It answers a question no other endpoint can: not how the dogs are doing, but which trainers the ownership is getting results from. A syndicate with three yards can see which one is earning its keep.
  • Accepts months (default 12, maximum 60) and track_id to restrict every split to a single track.

2026-08-19 — Trainer statistics — strike rate by track, distance, trap and grade

  • New endpoint GET /v1/trainers/{trainer_id}/stats. GET /v1/trainers/{trainer_id}/results returns what happened; this returns what tends to happen. Splits cover track, distance, trap, grade and going, each with runs, wins, places, strike rate and place rate.
  • The question it exists to answer is "how does this yard do at this track". Previously that meant paging through every result and counting by hand. It is now one call, or one call with track_id to narrow every split to a single course.
  • Bounded to a rolling window — months, default 12, maximum 60. This is deliberate: a busy yard has thousands of runners in a year, and an unbounded career scan on every request would be slow for every caller, not just the one asking.

2026-08-19 — Dog statistics — career splits by distance, trap, track, grade and going

  • New endpoint GET /v1/dogs/{dog_id}/stats. Five splits over a dog's whole career, each with runs, wins, places, win percentage and place percentage, plus an overall block carrying first and last run dates.
  • by_distance also returns best_time_s and avg_time_s. Those two fields appear nowhere else, and that is on purpose: a time averaged across mixed trips is not a rough figure, it is a meaningless one. A dog running 268m in 16s and 500m in 29s has an "average" that describes neither. Rather than ship the fields everywhere with a caveat, they are omitted wherever distance varies.
  • by_going is banded — fast, slightly fast, standard, slightly slow, slow — rather than grouped on the raw going allowance. Grouping on the raw value split a 59-run career across ten buckets of three or four runs each, none large enough to read anything into. The underlying values are still returned in going_values, so nothing is hidden.
  • Completed runs only: reserves and withdrawals are excluded throughout. A split with no runs is omitted rather than returned as zero, so an absent trap means the dog has never boxed there — not that it has run and never won.

2026-08-19 — The REST surface is now 38 endpoints — three of them on Live Plus

  • Three additions take the API from 35 endpoints to 38: dog, trainer and owner statistics. No existing endpoint changed shape, and no field was removed — everything already built against v1 keeps working.
  • All three are in the OpenAPI schema, the Postman collection and the "Run it live" console automatically, because the documentation and the router are generated from the same registry.
  • The three statistics endpoints are part of Live Plus. Live keys reach the other 35 and receive 403 upgrade_required on these, with a message naming the endpoint and pointing at the plan comparison — no silent failure and no empty payload.
  • Why these three: they return pre-aggregated splits computed across the whole archive, which is materially more expensive per call than returning rows. Putting them with the higher plan keeps the base plan fast and gives the upgrade something concrete behind it.
  • The endpoint count shown across the site is now counted from that registry rather than written into the copy, and it is tier-aware — the pricing table reads 35 for Live and 38 for Live Plus from the same source the gate uses, so the two cannot drift apart. It had been hardcoded in six places, which is how a number quietly goes stale.

2026-08-10 — Documentation redesign — colour-coded requests and responses, and a rebuilt "Run it live"

  • Every request example and JSON response across the documentation is now syntax-highlighted — keys, strings, numbers and booleans each in their own colour — making payloads far easier to scan. It applies to all 35 endpoint pages, the guides and the quickstart.
  • Redesigned code panels: the five request examples (cURL, PHP, JavaScript, React and Python) sit in one card whose language tabs form the panel header with a single copy button, and the sample Response now sits under a header showing a green 200 OK status and its content type.
  • The "Run it live" console was rebuilt: your key, the parameters and the Run button are grouped into one card, and the live result mirrors the documented Response — a header whose status chip is colour-coded by outcome (green for 2xx, amber for 4xx, red for 5xx), the request line with timing, rate-limit remaining and request id, and the response body syntax-highlighted. It re-colours correctly on every run.

2026-08-10 — Page numbers in list meta: next_page, prev_page & totals on the first page

  • meta.next_page and meta.prev_page: every page-based list response now includes the next and previous page numbers (null at the ends) alongside the existing page, per_page, total and total_pages — a pager has what it needs without computing offsets.
  • The first page of a list now carries the page picture without opting into ?page=: a default call (no cursor) to the race, racecard and result lists returns page, per_page, total, total_pages and next_page, so you learn the total size of a result set from the first request. Cursor continuations stay lean, returning only count and next_cursor.

2026-08-10 — Webhooks, richer race status & a fresher tracks list

  • Webhooks for push delivery: subscribe an HTTPS endpoint to result.received, race.status_changed and card.updated for GB, AU or both, and stop polling. Deliveries are signed (HMAC-SHA256 in an X-GAPI-Signature header), retried with backoff, and at-least-once with an X-GAPI-Delivery id for de-duplication. Manage them yourself in the dashboard under Webhooks — add an endpoint, choose events and regions, get a signing secret shown once, and send a test delivery. A new Webhooks guide covers the payloads and verification.
  • New race lifecycle status results_pending: once a race has jumped and a short settling period has passed with no final result, it reports results_pending instead of remaining on off, so you can tell a race still to run apart from one that has run and is awaiting its result. It applies to GB and AU, and appears across the race endpoints and GET /v1/races/{id}/status.
  • New result_status field on the result block and GET /v1/races/{id}/status: provisional while placings are still arriving, final once every dog that ran has a finishing position — so a winner-only result is distinguishable from a settled one. Documented in Data freshness.
  • GET /v1/tracks now lists only tracks raced on in the last two weeks across GB and AU, rather than the all-time roster, so the list reflects tracks currently in rotation. Individual track lookups (get-track, track-races, track-stats) are unchanged and still resolve any track by id.
  • Fixed the /status day counters — races and results today, and the results-delay percentiles — to count by race day and exclude synthetic sample data, so they reflect real racing accurately.

2026-08-01 — Live Plus Launched

  • New payment tier added for Live Plus which gives increased request rate.

2026-07-29 — Page-number pagination on list endpoints

  • List endpoints now accept a 1-based page parameter alongside cursors — for example ?page=2&limit=100 — and add meta.page, meta.per_page, meta.total and meta.total_pages to the response.
  • Cursors are unchanged and remain the recommended approach for large or streaming exports; a page-number response also returns a next_cursor, so you can start with page numbers and switch to cursors for a full pull.
  • The Pagination guide now documents both approaches side by side.

2026-07-27 — Status Page updated and Chat support added

  • Status page expanded to offer deeper insight of the current upstream inner workings.
  • Chat support added on-site.

2026-07-09 — Status page, dashboard usage & the live stream endpoint

  • Public status page at /status: an overall banner plus live per-component health for the results pipeline, the WebSocket stream and the REST API — each with a rolling 90-day uptime chart.
  • Pipeline freshness on the status page: results today, results in the last 24 hours, the latest result received, and the median and p95 results delay.
  • Account dashboard gains an API usage view — a 90-day daily request heatmap, a 30-day request bar chart, and a breakdown of the endpoints you hit.
  • Billing on the dashboard: plan status, your renewal date and invoice history, with a link straight to the Stripe billing portal.
  • WebSocket stream reachable at wss://greyhoundapi.com:8443/v1/stream (proxied by Cloudflare); a live key still allows up to two concurrent connections.

2026-07-08 — v1 — full surface, self-serve accounts, docs console

  • All 35 REST endpoints live: racecards, races, results, meetings, dogs, trainers, owners, tracks, breeding, Betfair market summaries and platform endpoints.
  • Self-serve accounts: sign in with Google, free sandbox key in seconds, live plan at $99/month with Stripe checkout and billing portal.
  • Key lifecycle from the dashboard — create, label, rotate with a 24-hour overlap, revoke. Keys are shown once and stored hashed.
  • "Run it live" console on every endpoint page: real requests from your browser with your own key.
  • OpenAPI 3.1 export at /openapi.json, generated from the same registry that drives the documentation and the API router.
  • Postman collection at /postman-collection.json (Postman v2.1 — also imports into Insomnia and Bruno): all 35 endpoints grouped by section, X-API-Key auth pre-wired to an {{apiKey}} variable, and a saved example response on every request.
  • Errors guide documents the full code set, including method_not_allowed and the pre-launch-only not_implemented.
  • WebSocket stream for live results, status and card channels, with a 15-minute replay window and up to two connections per live key.

2026-07-04 — Access tiers, rate limits & wider track coverage

  • Two access tiers: a free sandbox and a single live plan. The sandbox is scoped to the race & track endpoints over a rolling 7-day window at 500 requests a day.
  • Per-key rate limiting: a per-minute ceiling and a daily quota, with the live plan raised well above the sandbox.
  • GB + AU track coverage: race and track listings across the major British and Australian venues, each with its own distances.

2026-07-01 — Documentation hub

  • Thirty-five endpoint pages with parameters, five-language request examples and canonical response payloads.
  • Guides: getting started, authentication, pagination, rate limits, errors, timezones, data freshness, sandbox, WebSocket stream.
  • Interactive head-to-head demo on the sandbox page built from real documented payloads.

2026-06-25 — Platform foundation

  • Registry-driven v1 API: a single registry drives the request router, the documentation and the OpenAPI spec, so they never drift apart.
  • Core data model for Great Britain and Australia greyhound racing: tracks, meetings, races, runners and results, all under one consistent JSON envelope with request ids.
  • API keys stored as SHA-256 hashes; every request authenticates with the X-API-Key header, and unknown or revoked keys are rejected consistently.