18+ Only  |  Gambling can be addictive — please gamble responsibly  |  Gambling Help: 1800 858 858  |  GambleAware

API reference / Racing

GET /v1/racing/horses/form

Thoroughbred form, career record and profile for one horse

One AU thoroughbred's recent form, career record and profile, parsed from Racing Australia's public horse page — the registry's own data. SOURCE AND FRESHNESS. The horse's page is read on demand and the parsed result stored (`source.fetched_at` dates it), so the first query for a horse pays a page-read to RA (typically under two seconds) and later reads are instant. A horse's form only changes when it races or trials, so the stored copy is re-read from RA only when our own results archive shows the horse has started since it was read, or when the copy is more than seven days old (a barrier trial is invisible to results, so it surfaces within a week at worst). Inside six hours it is served without even that check. A horse collected once, by you or by anyone, is therefore served from our store without another RA read for as long as it stays unraced. When RA cannot be reached and a stored copy exists, that copy is served with `source.stale: true` rather than an error. When RA is refusing reads (its bot wall) and no stored copy exists, the answer is 503 with a `Retry-After` header and fresh reads pause for that long; stored horses keep serving throughout. Only a 200 is billed — a 404, 502 or 503 costs nothing. RESOLVING `horse`. Pass the ra: code from `runner_ref` for an exact answer — it is on every /v1/racing/results runner (AU thoroughbred) and on acceptance-enriched live runners — or pass a name. Names resolve against horses seen on our own feeds: acceptances roughly three days ahead, plus every archived result runner (from 2026-09-01). A name that matches several horses (registered names are reused across eras) returns 200 with `ambiguous: true` and `candidates[]`; re-query with the runner_ref you meant. A name never seen on our feeds returns 404 even when RA knows the horse — there is deliberately no name-search against RA itself. READING A RUN. Runs come newest first: the page's recent-form table, typically the last ten starts plus barrier trials (`trial: true` — RA publishes those with $0 prize, 0kg weights and no market). `race_class` is RA's official class string ('MDN-SW', 'BM64', 'CTRY MDN'), the first place race class appears anywhere on this API. `prices` is the published price path oldest-quote-to-SP and `sp` its last entry. `margin_l` is lengths behind the winner — on the horse's own win, its winning margin. `pir` is position in running at the 800m and 400m marks where published. `placegetters` names the two nearest finishers with their own ra: codes, so one horse's page walks to its rivals'. Track names are RA's compressed codes ('W FM', 'RAND') served as published. `trainer` on a run is the trainer OF THAT DAY, joined from our own results archive — populated for runs from 2026-09-01 onward and NULL before, because RA's form table names only the current trainer (`profile.trainer`); the archive floor moves back nowhere, so the populated share grows with every meeting. THE CAREER BLOCK. RA's own summaries, not derived from the runs list: overall starts/wins/seconds/thirds, prizemoney, and per-dimension splits (first_up, second_up, firm/good/soft/heavy/synthetic; track/distance splits appear when RA renders them). These cover the whole career even where the runs list shows only recent starts. JOINING TO LIVE DATA. `runner_ref` here, on /v1/racing/results runners and on enriched live runners is the same stable identifier, so pre-race model rows join to official results and to this form history on one key. `jockey_code` and `meet_code` are RA's stable identifiers for the rider and the meeting. Cached 10 minutes per query on top of the six-hour page store.

Requires X-API-Key 3 credits

Request

curl 'https://api.puntersedge.online/v1/racing/horses/form?horse=YOUR_HORSE' \
  -H 'X-API-Key: YOUR_KEY'

Parameters

NameIn TypeRequired Description
horse query string yes Horse name, or the stable ra: code from runner_ref on results/live runners. Names match case- and punctuation-insensitively on the whole name.

Responses

Status codes: 200, 401, 402, 422, 429, 500. Response bodies are JSON; the full schema is in /openapi.json.

Example response

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.

{
  "ambiguous": false,
  "candidates": [],
  "career": {
    "prizemoney": 4875,
    "seconds": 0,
    "splits": {
      "first_up": {
        "seconds": 0,
        "starts": 2,
        "thirds": 1,
        "wins": 0
      },
      "good": {
        "seconds": 0,
        "starts": 2,
        "thirds": 1,
        "wins": 0
      }
    },
    "starts": 3,
    "thirds": 1,
    "wins": 0
  },
  "horse_name": "Zweigelt",
  "profile": {
    "age_sex": "4yo Bay Gelding",
    "colours": "Lime, Purple And Gold Braces And Armbands",
    "dam": "MEDGRINDA",
    "dob": "2022-11-01",
    "last_gear_change": "20-Aug-2026, Blinkers, First Time",
    "sire": "VINO ROSSO (USA)",
    "trainer": "Matthew Dunn",
    "trainer_location": "Murwillumbah"
  },
  "runner_ref": "ra:MTMwNDY2ODI0NA",
  "runs": [
    {
      "barrier": 9,
      "date": "2026-08-18",
      "distance_m": 1430,
      "field_size": 9,
      "going": "Soft",
      "going_rating": 7,
      "jockey": "Andrew Mallyon",
      "jockey_code": "MTQ5MjQ5OTIw",
      "margin_l": 0.76,
      "meet_code": "MTI2NzM2MDQwMA",
      "pir": [
        {
          "at_m": 800,
          "position": 7
        },
        {
          "at_m": 400,
          "position": 7
        }
      ],
      "placegetters": [
        {
          "name": "Sunset Trail",
          "position": 1,
          "runner_ref": "ra:MTMwMDQ4MDk2MA",
          "weight_kg": 58.0
        }
      ],
      "position": 4,
      "prices": [
        7.5,
        4.0,
        4.8,
        5.0
      ],
      "prize_total": 27000,
      "prize_won": 1300,
      "race_class": "MDN",
      "race_number": 4,
      "result_raw": "4th of 9",
      "sectional_distance_m": 600,
      "sectional_time_s": 37.16,
      "sp": 5.0,
      "time_s": 86.82,
      "track": "GRAF",
      "trial": false,
      "weight_kg": 58.5
    }
  ],
  "source": {
    "feed": "racing_australia",
    "fetched_at": "2026-09-01T11:20:00+00:00",
    "region": "AU",
    "sport": "thoroughbred",
    "stale": false
  }
}

Related endpoints

Try it against live data

The free tier needs no credit card, and the sandbox endpoints need no key at all.

Get a free API key Quickstart
This site contains wagering-related analysis and is intended for Australian users aged 18+. Gambling involves risk. Please gamble responsibly.