API reference / Racing
GET /v1/racing/horses/runsOne thoroughbred's runs in our own settled results
Every run we hold for one AU thoroughbred, newest first, out of our own settled results. THIS IS NOT A CAREER RECORD. Each run here is a race WE collected and settled: the same rows /v1/racing/results serves, flattened one-per-horse. The store begins at the first complete card on `source.coverage_from` and `source.coverage_to` is the latest race in it, so `runs_total` is this horse's record SINCE THAT DATE, not its lifetime. The same run never changes once written, so the record only grows — build a longer history forward from here. WHY YOU WOULD USE IT INSTEAD OF /v1/racing/horses/form. That endpoint is Racing Australia's own form page: deeper (career splits, sectionals, position-in-running, the price path to SP) but dependent on RA serving us the page. Since 2026-09-21 RA's edge answers every fresh form read with a human-verification challenge, so horses we have not already stored cannot be read at all, and we do not automate that challenge. This endpoint has no such dependency — it reads only what we already hold — and it is the honest answer to "what do you have on this horse today". Use both: form for depth when RA lets us in, runs for availability always. RESOLVING `horse` — PASS THE NAME, OR ITS `horse_ref`. A name is folded to letters and digits (the trailing country parenthetical stripped first) and must match in full — the same rule /v1/racing/horses/form applies, so one name resolves identically on both. `pe:custo`, the `horse_ref` published on every thoroughbred runner, placing, live-board entry and archive row, is the same fold already done and resolves to exactly the same runs. A Racing Australia horsecode (`ra:MjgwNjM0ODg2NDA`, or the bare code) is accepted too, but it pins ONE results entry rather than a horse: measured 2026-09-21, our 10,092 stored runner rows carry 9,872 distinct codes over 7,326 names, so the same horse generally carries a different code at each meeting and a code filter usually returns a single meeting's runs. `runner_refs` lists every code published under the name; more than one is normal. The other side of grouping on a name is that a registered name reused by two horses returns the union of both. A horse we hold no run for is a 404 and costs nothing; an unknown query parameter is a 422 and costs nothing. READING A RUN. `position` is the finishing place, null when the horse did not start (`status` is `scratched`) or started and did not finish — `abnormal` is then RA's own reason cell, verbatim and from no closed list. `sp` is the official starting price and `sp_note` RA's favouritism marker; null `sp` means unknown, never zero. `margin` is RA's own text in lengths. `time_s` is the WINNER's time only: RA prints one time per race, in its race header, and no per-runner time in the results table, so since 29 September 2026 a position-1 run carries the race time and every other run's `time_s` is null. Every run of a race also carries the race-level `race_time_s` and `last_600m_s` (RA's header, seconds) and `prize_total`, and each placed run its `prize_won` off RA's prize line (dead heats share the places they tie for; 0 outside the paid places); all four are null on runs stored before that date until the meeting is re-read, and before 29 September no run carried any time (0 of 17,344 stored runs, measured 2026-09-28). `trainer` and `jockey` are the ones of that day, which is what the result published — `profile.trainer` on the form endpoint is the CURRENT trainer. `field_size` counts the horses that ran. `weight_kg` is the allotted weight and `carried_kg` the weight actually carried when RA printed one (a claim under it, or an overweight rider over it); `race_class` is RA's own leading conditions term ('Maiden', 'BenchMark 64'). All three are kept since 28 September 2026 and null on runs stored before then until that meeting is re-read. `result_id` joins back to /v1/racing/results, except on `origin: history` and `origin: tabtouch` runs, whose synthetic 'hist:...' id joins to nothing. `stats` is computed over every held run, not just the `limit` returned, and counts only starts (`status: ran`). Cached 10 minutes per query; the store itself refreshes hourly at :59.
X-API-Key
3 credits
curl 'https://api.puntersedge.online/v1/racing/horses/runs?horse=YOUR_HORSE' \
-H 'X-API-Key: YOUR_KEY'
| Name | In | Type | Required | Description |
|---|---|---|---|---|
horse |
query | string | yes | Horse NAME (matched on letters and digits, case- and punctuation-insensitive, whole name), or the `horse_ref` any thoroughbred surface publishes ('pe:custo') — either gathers the whole record, and they resolve identically. A Racing Australia horsecode from `runner_ref` ('ra:MjgwNjM0ODg2NDA' or the bare code) is accepted too, but it pins one results entry, usually one meeting's runs, not the horse. |
limit |
query | integer | no | Most recent runs to return. |
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 3 credits.
Field names and types are as the API returns them; values are a real sample, trimmed to a few items.
{
"horse": "Belle Reine",
"name_key": "bellereine",
"horse_ref": "pe:bellereine",
"runner_refs": [
"ra:Mjk3NDcwNzQ4OTY",
"ra:NDIzMjQxMjA5OTI"
],
"runs_total": 3,
"runs": [
{
"date": "2026-09-29",
"start_time": "2026-09-29T03:35:00Z",
"venue": "Grafton",
"race_number": 2,
"distance_m": 1006,
"race_name": "Book A Christmas Party @ Crjc Maiden",
"track_condition": "Soft (6)",
"number": 12,
"box": 11,
"position": 5,
"status": "ran",
"abnormal": null,
"margin": "3.02L",
"time_s": null,
"sp": 91.0,
"sp_note": null,
"dead_heat": false,
"trainer": "Ethan Ensby",
"jockey": "Ms Violet Soulsby",
"field_size": 12,
"weight_kg": 55.0,
"carried_kg": 53.0,
"race_class": "Maiden",
"race_time_s": 59.27,
"last_600m_s": 35.84,
"prize_total": 27000,
"prize_won": 825.0,
"runner_ref": "ra:NDIzMjQxMjA5OTI",
"horse_ref": "pe:bellereine",
"result_id": "d01a811c-0b45-41c9-86c8-35b06d46e07f",
"origin": "results"
},
{
"date": "2026-09-21",
"start_time": "2026-09-21T04:50:00Z",
"venue": "Grafton",
"race_number": 3,
"distance_m": 1190,
"race_name": "BOOK A CHRISTMAS PARTY @ CRJC MAIDEN HANDICAP",
"track_condition": "Soft (5)",
"number": 10,
"box": null,
"position": null,
"status": "scratched",
"abnormal": null,
"margin": null,
"time_s": null,
"sp": null,
"sp_note": null,
"dead_heat": false,
"trainer": "Ethan Ensby",
"jockey": null,
"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:Mjk3NDcwNzQ4OTY",
"horse_ref": "pe:bellereine",
"result_id": "3ca2049e-4339-45fd-bb36-3c34a52aad71",
"origin": "results"
},
{
"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": 17,
"box": null,
"position": null,
"status": "scratched",
"abnormal": null,
"margin": null,
"time_s": null,
"sp": null,
"sp_note": null,
"dead_heat": false,
"trainer": "Ethan Ensby",
"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:Mjk3NDcwNzQ4OTY",
"horse_ref": "pe:bellereine",
"result_id": "09d4a64e-3c05-498c-abb5-dd95f0bb812f",
"origin": "results"
}
],
"stats": {
"starts": 1,
"wins": 0,
"places": 0,
"win_pct": 0.0,
"place_pct": 0.0
},
"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/form — Every runner in one race with its recent runs, from our own resultsGET /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 resultsThe free tier needs no credit card, and the sandbox endpoints need no key at all.
Get a free API key Quickstart