API reference / Racing
GET /v1/racing/formEvery runner in one race with its recent runs, from our own results
Every runner in one race with its recent runs from our own settled AU thoroughbred results, in one call: the field's form, not one horse's. **Naming the race.** `race_id` from /v1/racing/next-to-go, /events, /acceptances or /results is exact. Failing that, `venue` + `meeting_date` (the AET meeting date) + `race_number`; two races sharing those three answer 409 `race_ambiguous` and cost nothing. **The field.** While the race is open the runners come from the live card (`card_source: live`): saddlecloth, barrier, jockey, trainer and allotted weight as the books and Racing Australia's acceptances publish them, with a horse the card has since scratched kept in the field and marked `scratched: true`. Once the race has been run and the live card purged, the field is the settled result's (`card_source: results`). **The runs.** Under each runner, its newest `runs` runs (default 10, at most 20) out of the same store /v1/racing/horses/runs reads -- our own collected results plus the history collected behind them -- and a starts, wins and places summary over every run held. Each run carries date, venue, race, distance, class, track condition, saddlecloth, barrier, position, margin, official SP, weight, jockey, trainer and field size, and since 29 September 2026 the race's winning time and last-600m time, its total prize money and the place money this runner won (the winner's `time_s` is the race time; RA publishes no other runner's time). ONLY RUNS BEFORE THIS RACE'S START are included (`form_as_at`), so a race already run answers with what was knowable at the jump and never with its own result. A runner with no run held is still in the field, with `runs: []` and `runs_total: 0`; `source.coverage_from` is the floor of the store, and nothing earlier exists here. **Identity.** Runners are gathered on `horse_ref` (`pe:<name>`), the fold every thoroughbred surface publishes. `runner_ref` is the Racing Australia code the card carries for this entry, the join to /v1/racing/next-to-go and /v1/racing/acceptances, not a horse identity: the same horse usually carries a different code at each meeting. Not a career record: this is what we hold, honestly bounded, and it grows with every meeting we collect. For Racing Australia's own form page (career splits, sectionals, price paths) use /v1/racing/horses/form, one horse at a time. A race we cannot find is a free 404, a race we hold no field for a free 404, an unknown query parameter a free 422. Thoroughbreds only; greyhounds have /v1/racing/greyhounds/form. Cached 10 minutes; the store refreshes hourly.
X-API-Key
3 credits
curl 'https://api.puntersedge.online/v1/racing/form' \
-H 'X-API-Key: YOUR_KEY'
| Name | In | Type | Required | Description |
|---|---|---|---|---|
race_id |
query | string | no | The race_id from /v1/racing/next-to-go, /events, /acceptances or /results. The primary form; use venue + meeting_date + race_number only when you do not hold it. |
venue |
query | string | no | Venue name as the feeds spell it (case-insensitive). Needs meeting_date and race_number. |
meeting_date |
query | string | no | AET meeting date, YYYY-MM-DD. |
race_number |
query | string | no | |
runs |
query | integer | no | Most recent runs to return per runner. The stats cover every held run regardless. |
Status codes: 200, 401, 402, 404, 409, 422, 429, 500. Response bodies are JSON; the full schema is in /openapi.json.
200 application/json
— this call costs 3 credits.
Field names and types are as the API returns them; values are a real sample, trimmed to a few items.
{
"race_id": "ca43a1a8-f58e-491e-bc88-5d556c7bf1f7",
"venue": "Grafton",
"race_number": 2,
"start_time": "2026-09-29T03:35:00Z",
"meeting_date": "2026-09-29",
"race_name": "Book A Christmas Party @ Crjc Maiden",
"distance_m": 1006,
"track_condition": "Soft (6)",
"race_status": "final",
"card_source": "results",
"form_as_at": "2026-09-29T03:35:00Z",
"runs_per_runner": 10,
"runners_total": 13,
"runners_with_runs": 10,
"runners": [
{
"number": 1,
"name": "Dream Invader",
"horse_ref": "pe:dreaminvader",
"runner_ref": "ra:NDI0MTMzNzM3MTI",
"barrier": 5,
"jockey": "Ben Looker",
"trainer": "Allan Kehoe",
"weight_kg": 59.0,
"scratched": false,
"runs_total": 1,
"stats": {
"starts": 1,
"wins": 0,
"places": 1,
"win_pct": 0.0,
"place_pct": 100.0
},
"runs": [
{
"date": "2026-09-13",
"start_time": "2026-09-13T04:30:00Z",
"venue": "Coffs Harbour",
"race_number": 3,
"distance_m": 1014,
"race_name": "MORSE LEGACY SUPER MAIDEN HANDICAP",
"track_condition": "Soft (5)",
"number": 1,
"box": 5,
"position": 3,
"status": "ran",
"abnormal": null,
"margin": "1.8L",
"time_s": null,
"sp": 13.0,
"sp_note": null,
"dead_heat": false,
"trainer": "Allan Kehoe",
"jockey": "Ms Olivia Chambers",
"field_size": 10,
"weight_kg": null,
"carried_kg": null,
"race_class": null,
"race_time_s": null,
"last_600m_s": null,
"prize_total": null,
"prize_won": null,
"runner_ref": "ra:MTc4OTQ0ODYyNzI",
"horse_ref": "pe:dreaminvader",
"result_id": "e5566b7e-eb0a-46a9-aefc-637a9a447d99",
"origin": "results"
}
]
},
{
"number": 2,
"name": "Exo Murano",
"horse_ref": "pe:exomurano",
"runner_ref": "ra:NDIxOTYxMDY2NDA",
"barrier": 8,
"jockey": "Archie McColm",
"trainer": "Stephen & Jordan Lee",
"weight_kg": 59.0,
"scratched": false,
"runs_total": 2,
"stats": {
"starts": 1,
"wins": 0,
"places": 0,
"win_pct": 0.0,
"place_pct": 0.0
},
"runs": [
{
"date": "2026-09-21",
"start_time": "2026-09-21T04:10:00Z",
"venue": "Grafton",
"race_number": 2,
"distance_m": 1015,
"race_name": "CRJC AGM 25 NOVEMBER COUNTRY BOOSTED MAIDEN PLATE",
"track_condition": "Soft (5)",
"number": 13,
"box": null,
"position": null,
"status": "scratched",
"abnormal": null,
"margin": null,
"time_s": null,
"sp": null,
"sp_note": null,
"dead_heat": false,
"trainer": "Stephen & Jordan Lee",
"jockey": null,
"field_size": 12,
"weight_kg": null,
"carried_kg": null,
"race_class": null,
"race_time_s": null,
"last_600m_s": null,
"prize_total": null,
"prize_won": null,
"runner_ref": "ra:Mjk2NTcxMDEzMjA",
"horse_ref": "pe:exomurano",
"result_id": "09d4a64e-3c05-498c-abb5-dd95f0bb812f",
"origin": "results"
},
{
"date": "2026-09-10",
"start_time": "2026-09-10T04:35:00Z",
"venue": "Lismore",
"race_number": 3,
"distance_m": 1110,
"race_name": "LISMORE FLOOR COVERINGS CG&E MAIDEN PLT",
"track_condition": "Soft (5)",
"number": 18,
"box": 2,
"position": 6,
"status": "ran",
"abnormal": null,
"margin": "7.98L",
"time_s": null,
"sp": 51.0,
"sp_note": null,
"dead_heat": false,
"trainer": "Stephen & Jordan Lee",
"jockey": "Ms Siabh Rigley",
"field_size": 10,
"weight_kg": null,
"carried_kg": null,
"race_class": null,
"race_time_s": null,
"last_600m_s": null,
"prize_total": null,
"prize_won": null,
"runner_ref": "ra:MTM1MzM5OTQ2NTA",
"horse_ref": "pe:exomurano",
"result_id": "1e4e3591-2f0f-41d6-b0f9-8caea3a92dad",
"origin": "results"
}
]
}
],
"source": {
"feed": "puntersedge",
"region": "AU",
"sport": "thoroughbred",
"coverage_from": "2026-08-09",
"coverage_to": "2026-09-29",
"collectors": [
"racing_australia"
],
"refreshed_hourly": true
}
}
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 timestampPOST /v1/racing/clv — Score bets against the closing line (CLV)GET /v1/racing/events — Upcoming race listGET /v1/racing/greyhounds/form — Greyhound form history for one dog, from our own resultsGET /v1/racing/greyhounds/stats — Greyhound record by track, distance, box or grade, from our own resultsPOST /v1/racing/horses/backfill — Queue a batch of horses for paced form collectionThe free tier needs no credit card, and the sandbox endpoints need no key at all.
Get a free API key Quickstart