API reference / Racing
GET /v1/racing/track-conditionsTrack condition, weather and rail: current state and today's change log
Per meeting: the CURRENT official track condition, weather and rail position (Racing Australia, AU thoroughbred meetings, refreshed every two hours) and the day's CHANGE LOG — every transition we observed, with the previous value beside the new one, when it was seen and which feed saw it. **Two kinds of change row, told apart by `source`.** `racing_australia` rows come from RA's own meeting page, so they are the official rating and carry the rail; bookmaker rows (`betright`, `ladbrokes_au`, ...) come from a book's race page moving between two of our polls and carry `race_id`. A book row can land minutes before RA re-publishes, and a book's spelling ("Soft (6)") differs from RA's ("Soft 6"); the log compares normalised values per feed, so the same rating spelled two ways never appears as a change, and a book that merely lags another produces no row. **Baselines.** The first RA row for a meeting has every `prev_*` null: it is the state when we first read the page (about two days out), not a change. Bookmaker rows are only ever written for a genuine transition, so they always carry a `prev_track_condition`. **Coverage.** Official state is AU thoroughbred only — RA publishes nothing for greyhounds or harness, so those meetings appear here only when a book reported a change, with `current` labelled by that book. New Zealand meetings likewise. **One entry per meeting, whatever each feed calls it** (2026-09-10). RA welds the sponsor into its own venue key ('Picklebet Park Warwick') and the books send the bare town ('Warwick'), so the same card used to arrive here twice — once official with the rail and once as a bookmaker shell with the change history. Spellings are now folded onto one meeting by venue_id, by the sponsor word-subset rule, and (for a course inside a parent racecourse, e.g. the books' 'Randwick' against RA's 'Kensington') by venue_site, each fold refusing to act unless exactly one candidate meeting qualifies and every change row on the bookmaker key is positively categorised thoroughbred. `merged_from` lists every raw venue_norm folded in and `official_venue_norm` names RA's spelling, so a join on either old string still finds the meeting, and `venue` selects it by any of them. A merged entry is published under RA's spelling, because a bookmaker's can be ambiguous about which course of a complex ran ('sandown' for a Sandown HILLSIDE card) and `venue_id` must never name the wrong track; where RA's spelling is not yet a venue-registry entry its `venue_id` is that spelling's slug ('picklebet-park-warwick'), which is unmapped rather than wrong. **Mixed `current`.** `current` is built field by field: RA's official block wherever RA published a value, a book filling only a field RA left null, and RA's own later row superseding either. `current.sources` names the feed behind each value field and `current.field_as_of` when it was observed; the block-level `source` reads `mixed` when more than one feed is behind the block, and the block-level `as_of` is the OLDEST of the per-field instants, so neither overstates what the block knows. `changes` keeps every row from both feeds in one sequence. **`going` / `going_rating`** sit beside `track_condition` (and `prev_going` / `prev_going_rating` beside `prev_track_condition`) as the same vocabulary /v1/racing/horses/form publishes, so 'Soft 6', 'Soft (6)' and 'Good4' need one parser and not three. The raw string is unchanged. The live endpoints carry the same signal per race as `track_condition_changed_at` — the instant of the latest logged transition for that race's meeting — so a poller reading /v1/racing/changes need not call this to know something moved; call this for the sequence. `date` before 7 days ago or malformed is a free 422.
X-API-Key
1 credit
curl 'https://api.puntersedge.online/v1/racing/track-conditions' \
-H 'X-API-Key: YOUR_KEY'
| Name | In | Type | Required | Description |
|---|---|---|---|---|
date |
query | string | no | Meeting day, Australia/Sydney, YYYY-MM-DD. Defaults to today. Up to 7 days back. |
venue |
query | string | no | One meeting, case-insensitive ('Belmont', 'sandown hillside'). Omit for every meeting on the day. |
Status codes: 200, 401, 402, 422, 429, 500. Response bodies are JSON; the full schema is in /openapi.json.
200 application/json
— this call costs 1 credit.
Field names and types are as the API returns them; values are a real sample, trimmed to a few items.
{
"date": "2026-09-10",
"meetings": [
{
"category": "horse",
"changes": [
{
"category": "horse",
"going": "Good",
"going_rating": 4,
"observed_at": "2026-09-09T04:16:29Z",
"rail": "True",
"source": "racing_australia",
"track_condition": "Good 4",
"weather": "Windy"
},
{
"category": "horse",
"going": "Good",
"going_rating": 4,
"observed_at": "2026-09-10T02:36:58Z",
"prev_going": "Good",
"prev_going_rating": 3,
"prev_track_condition": "Good3",
"race_id": "race_123",
"source": "betgold",
"track_condition": "Good4"
}
],
"current": {
"as_of": "2026-09-10T02:17:24Z",
"field_as_of": {
"penetrometer": "2026-09-10T02:17:24Z",
"rail": "2026-09-10T02:17:24Z",
"track_condition": "2026-09-10T02:17:24Z",
"track_type": "2026-09-10T02:17:24Z",
"weather": "2026-09-10T02:17:24Z"
},
"going": "Good",
"going_rating": 4,
"penetrometer": "5.63",
"rail": "True",
"source": "racing_australia",
"sources": {
"penetrometer": "racing_australia",
"rail": "racing_australia",
"track_condition": "racing_australia",
"track_type": "racing_australia",
"weather": "racing_australia"
},
"track_condition": "Good 4",
"track_type": "Turf",
"weather": "Windy"
},
"merged_from": [
"picklebet park warwick",
"warwick"
],
"official_venue_norm": "picklebet park warwick",
"venue": "picklebet park warwick",
"venue_id": "picklebet-park-warwick",
"venue_norm": "picklebet park warwick",
"venue_site": "picklebet-park-warwick"
}
],
"note": "…"
}
GET /v1/racing/acceptances — Full-day AU thoroughbred acceptance card: every meeting, race and runnerGET /v1/racing/best-odds — Best racing price per runner across booksGET /v1/racing/changes — Races and prices that changed since a timestampGET /v1/racing/events — Upcoming race listGET /v1/racing/greyhounds/form — Greyhound form history for one dogGET /v1/racing/greyhounds/stats — Greyhound record by track, distance, box or gradePOST /v1/racing/horses/backfill — Queue a batch of horses for paced form collectionDELETE /v1/racing/horses/backfill/{job_id} — Cancel the horses a job has not collected yetThe free tier needs no credit card, and the sandbox endpoints need no key at all.
Get a free API key Quickstart