---
title: "Full-day AU thoroughbred acceptance card: every meeting, race and runner"
method: GET
path: "/v1/racing/acceptances"
tags: ["Racing"]
---

# Full-day AU thoroughbred acceptance card: every meeting, race and runner

`GET /v1/racing/acceptances`

## Request

- Base URL: `https://api.puntersedge.online`
- URL: `https://api.puntersedge.online/v1/racing/acceptances`
- Auth: API key in header `X-API-Key`

Cost: 2 credits. The day's complete AU thoroughbred card as Racing Australia
publishes it — meeting, then race, then runners in saddlecloth order — with no
dependency on any bookmaker having framed a market. Per runner: saddlecloth number,
barrier, jockey, trainer, weight, `runner_ref` (Racing Australia's code from its latest read
of the field; once race day's read has landed it is the code the results and archives carry
for the race — RA issues a new code for the same horse each day), Last-10 figures, Hcp Rating,
the trainer/raceentry codes, the `emergency` flag, and `scratched` plus a `scratching`
block (RA's own scratch time, late flag, "(Eliminated)" marker and note) for a runner
already off. Per race: official name, local start time, distance, the conditions line
verbatim, class, prize total and per-place breakdown, bonus note, track name/type,
field limit, and the counts. Per meeting: rail, track type, condition — as RA's raw
`track_condition` and, parsed from it, `going` plus `going_rating`, the same pair
/v1/racing/horses/form publishes — weather, penetrometer, its own `as_of`,
`emergency_data`, `scratching_data` and `withheld_acceptance_data`.

**Identity (since 2026-10-12).** Every runner carries `horse_ref`, `pe:<folded name>`:
the HORSE, the same value on /v1/racing/form, /v1/racing/horses/form and
/v1/racing/horses/runs, stable across dates and meetings. `runner_ref` is Racing
Australia's code for THIS nomination and is new every time the horse is entered; join
histories on `horse_ref`, never on `runner_ref`.

**Fields-page extras (since 2026-09-29).** Every runner also carries what Racing
Australia prints under the acceptance table for that horse, verbatim and never inferred:
`age`, `sex`, `colour`, `sire`, `dam` (without the dam's sire), `breeder`, `owner` (RA's
Owners line), `gear_changes` for this start ("Tongue Tie OFF FIRST TIME"), the apprentice
`claim_kg` read off the jockey cell ("(a3/52kg)" -> 3; 0 is an apprentice who no longer
claims), `probable_weight_kg` and `penalty_kg` from their own columns, and the horse's LAST
START — the most recent dated start that is not a trial or jump-out: `last_start_date`,
`last_start_position`, `last_start_jockey`, `last_start_weight_kg`, `last_start_barrier`,
`last_start_winner` (the horse itself when it won) and `last_start_rating`, the "Rtg" RA
prints on that start's line. Null where RA prints nothing; null on every row stored before
2026-09-29 until the meeting is re-read. MEASURED on the first pass that read them
(2026-09-28 20:58Z, 10 meetings, 501 acceptances): pedigree/breeder/owner on 501 (100%), a
last start on 423 (84%), a last-start Rtg on 261 (52%), a claim on 107, gear changes on
111. `last_start_rating` is NOT a substitute for `hcp_rating`: of the runners with no Hcp
Rating, 5 carried a last-start Rtg on that pass (0 of 43 on the saved Moe card of
2026-09-08) — the unrated are overwhelmingly horses whose last start printed no Rtg either.

**No prices, on purpose.** This is the entry list, not a market. It is available about
two days out, which is the point of it — /v1/racing/next-to-go and
/v1/racing/best-odds carry prices when books open, and this endpoint stays readable
long before they do.

**Scratched runners are flagged, never removed.** They keep their place in the card so
it can be reconciled line-for-line against RA's official sheet.

**`emergency` is true, false or null.** Null means the meeting was collected before
emergency acceptances were recorded (2026-09-08 01:01:39 UTC) — its emergency acceptances are
absent from the source table entirely, so "false" would be a fabrication. The meeting
says which case it is in `emergency_data`: "parsed" or "unknown".

**`scratched` is true, false or null too, for the same reason.** RA's scratching sheet
does not exist for every date in the window — measured 2026-09-08, 2026-09-05 and
2026-09-06 have no scratching row at all while 09-07 has 96 and 09-08 has 77 — and each
meeting's sheet is collected separately, so one meeting can be missing its sheet while
its acceptances are present. A row from the sheet is the only positive
evidence it was read, so each meeting publishes `scratching_data`:
  * `"parsed"` — the sheet was read for this meeting; `scratched` is a real boolean
    and the counts resting on it are real numbers. `scratching_sheet_as_of` says when.
  * `"unknown_date"` — no meeting on this date has a scratching row. No sheet exists
    for the day; `scratched` is null everywhere on it.
  * `"unknown_meeting"` — other meetings on this date have a sheet and this one does
    not: either nobody was scratched here or this meeting's fetch failed, and nothing
    on this card tells them apart, so `scratched` is null.
Do not read a null as "not scratched", and do not read `scratching_data` other than
"parsed" as "clean meeting".

**The counts name their population.** An emergency acceptance runs only if it is
PROMOTED and RA does not publish whether it was, so a count that mixes emergencies
with declared runners overstates the field. Every level (race, meeting, day) carries:
`runner_count` (rows held, scratched and emergencies included — a floor wherever
`runner_set_status` is not "checks_passed"), `emergency_count`, `declared_count`
(runner_count minus emergency_count), `scratched_count`, `unscratched_count`
(runner_count minus scratched_count, a reconciliation figure that STILL includes
emergencies), `declared_scratched_count`, and `declared_remaining_count` — the horses
expected to jump barring a promotion, which is the number to render as the field.
Worked example, Moe R1 on 2026-09-08: 17 acceptances, 5 emergencies (#1, #14-#17),
12 declared, 6 scratchings all of declared runners — 11 rows are unscratched but only
6 declared horses remain. Anything resting on an unknown fact is null, not a guess,
and the day totals are null unless every meeting with rows knows the fact. With NO
meeting on the card publishing acceptances there is nothing to total: runner_count is
a real 0 and every other day count is null, matching what those meetings each report,
and `counts_cover_every_published_meeting` is false.

**On a race that is not "checks_passed", every count is a FLOOR.** All seven are
computed over the acceptance rows this card HOLDS, and such a race is one the card has
itself declared short. Two of them looked exact and were not.
`scratched_count` and `declared_scratched_count` count sheet rows MATCHED to an
acceptance row, so a scratching with no row here is in `missing_runners` and not in the
count: Townsville R6 on 2026-09-08 reads `scratching_data: "parsed"`,
`scratched_count: 0`, while RA's sheet lists #4 Five Star King and #9 Kickoff — at
least 2. And `declared_remaining_count` is the number to render as the field ONLY on a
"checks_passed" race: Townsville R5 that day is "gap_detected" with saddlecloth #6
unaccounted for and NOT on the sheet — a horse that may well be jumping — so its 11 is
"at least 11", never an exact field. Each such race's `runner_set_note` states the
bound explicitly.

**Completeness is cross-checked, and the note says what was OBSERVED.** ra_race_fields
is keyed (meeting_date_aet, runner_key) without a race number, so a horse accepted in
two races on one Sydney day has ONE slot — and since 2026-09-08 the acceptance pass
gives that slot to NEITHER race rather than publish one race's barrier and weight
against the other race's runner: the horse appears in neither race, not in one of them.
**Do not de-duplicate by `runner_key`
to recover them — there is nothing to de-duplicate.** Read `missing_runners` instead:
every withheld slot is named there, in its own race, with its REAL saddlecloth number,
`source` `"withheld_acceptance"`, and a `cause_detail` naming the slot published in its
place where one was. Each race is checked three ways — for saddlecloth holes, against
the independently-keyed scratching sheet where one exists, and against the withheld
slots recorded as withheld when the card was collected — then reports `runner_set_status`
("checks_passed", "gap_detected" or "unverified"), a `runner_set_note` and any
`missing_runners`. Each missing runner carries the cause actually observed for it —
`duplicate_runner_key` (the collision is visible, not assumed: the same runner_key is
held elsewhere on this card, or the slot was recorded as withheld),
`declared_preferred` (a declared acceptance elsewhere on the day won the key and this
race's emergency slot was dropped — nothing collided, so do not hunt a second race),
`eliminated_emergency` (RA's sheet marks it an emergency and no acceptance row exists)
or `not_determinable` — plus a `cause_detail` naming the observation. The endpoint
does not guess which of several indistinguishable causes applies.

**The withheld check is the only one that can see a loss above the top of the
numbering**, which is exactly where Racing Australia numbers its emergencies: drop
#13e from a 1..14 field and 1..12 is perfectly contiguous. Measured 2026-09-10, that
silence certified Warwick R2 and Bunbury R2 as "checks_passed" with `emergency_count`
0 while RA listed 14 and 13 entries against the 12 served each — false statements
under a schema that calls `declared_remaining_count` exact on a checks_passed race.
Each meeting publishes `withheld_acceptance_data`: `"parsed"` (this card placed this
meeting's withheld rows, so its discards are accounted for below), `"unplaced"` (the
pass recorded discards here and this card could NOT place a single one — the meeting's
acceptance fields are unpublished, or the race the row names is not on this card;
`withheld_acceptance_slots_unplaced` counts them and
`completeness.withheld_acceptance_slots_unplaced` totals the card) or `"unknown"` (no
row at all — either nothing was withheld, or the pass that read this meeting predates
the record). A row is the only positive evidence, so do NOT read `"unknown"` as
"nothing was lost"; `completeness.withheld_acceptances` says whether the whole date
holds any record at all.

Every `missing_runners` entry carries `withheld_acceptance` (true/false) — the
provenance of the loss, and the field `completeness.withheld_acceptance_slots` counts.
Read THAT, not `source`: one slot can be named by RA's scratching sheet AND recorded in
ra_withheld_acceptances, and it is listed once, keeping the sheet's `source` (the sheet
saw the scratching) while carrying the withheld cause and `withheld_acceptance: true`.
A withheld slot whose horse this card already holds in that SAME race under another
saddlecloth is not listed at all: RA renders one horse twice in one race under two
saddlecloths, only one row can be published, and no runner is missing from the race.

**A past-date card is a snapshot and will never complete.** `date_status` is "past",
"today" or "future". Acceptances are collected for today and forward only, so on
a PAST date: a meeting at `acceptances_published: false` will NEVER fill in (live on
2026-09-05: sportsbet bundaberg and sportsbet mareeba) — calling again cannot help,
and the meeting's `publication_note` says so; and the scratchings are frozen at the
last collection pass of that day, roughly midday race-day, with no later movement recoverable
from anywhere, /v1/racing/changes included. On "today" or "future" the next collection pass CAN
add both, every two hours — but that is not a promise that the card converges. Racing
Australia stops listing a meeting once
it is UNDERWAY, so a meeting's
rows stop advancing around 12:15-14:15 AEST while its own races run on to 17:00-19:30.
Log-verified 2026-09-09: the 02:15Z pass discovered all six of that day's meetings, the
04:15Z pass discovered one, the 06:15Z pass discovered none. The in-band signal is per
meeting — its own `as_of` and `scratching_sheet_as_of`. A stamp that stops moving while
later passes land on other meetings is a meeting that has gone underway, not a quiet
one, and from that point `/v1/racing/changes` carries the race-day movement.

**Why 2 credits.** A whole day is one request assembled from four reference tables: a
midweek card is a few hundred runners over a handful of meetings and a Saturday well
over a thousand across seventeen or more (measured: 372 runners / 4 meetings on
Tuesday 2026-09-08; 1,259 / 17 on Saturday 2026-09-05). That is materially more than
/v1/racing/track-conditions (1 credit, tens of rows) and is priced level with
/v1/racing/next-to-go; it does no cross-book price assembly, so it is not a 3. The
underlying data only updates every two hours — calling this once or twice a day is the
intended shape, not polling it.

**Coverage, honestly.** Australian THOROUGHBRED meetings only. Racing Australia
publishes no acceptance card for greyhounds or harness, and none for New Zealand, so
those meetings are absent here — not empty, absent. History is kept from 2026-09-29 on:
until then the reference tables were deleted three days after each meeting, so the store
begins at the oldest day that survived (2026-09-26) and grows by a day each day.
`coverage_from` is that first day, read from the tables on every call; any `date` from it
up to three days ahead is served, and an earlier one is a free 422 naming the floor rather
than a truthful-looking empty card. A past day is the card as the LAST read of that day
left it — see the past-date paragraph above.

**How current it is.** `as_of` is the newest RA read backing the meetings actually
returned (a venue filter narrows it, so one stale meeting cannot borrow another's
freshness), and each meeting carries its own plus `scratching_sheet_as_of`.

A malformed or out-of-window `date`, and an unknown query parameter, are both a free
422 — nothing is charged.

## Query parameters

- `date` string, nullable: Meeting day, Australia/Sydney, YYYY-MM-DD. Defaults to today. Any day from the store's first day (`coverage_from` in the response; an earlier date is a free 422 naming it) up to 3 days ahead.
- `venue` string, nullable: One meeting, case-insensitive ('Moe', 'sandown hillside'). Omit for every meeting on the day.

## Headers

- `X-API-Key` string
- `X-RapidAPI-Proxy-Secret` string

## Response `200`

Successful Response

- AcceptancesOut
  - `date` string, required: Meeting day, Australia/Sydney calendar date.
  - `date_status` string, required: 'past', 'today' or 'future', relative to the Australia/Sydney date. On 'past' this card is a FROZEN SNAPSHOT: acceptances are collected for today and forward only, so a meeting still showing acceptances_published false will never fill in and the scratching set can never converge. On 'today'/'future' the next collection pass CAN add acceptances and scratchings, every two hours — but that is not a promise that a meeting converges. Racing Australia stops listing a meeting once it is UNDERWAY, so a meeting's rows stop advancing around 12:15-14:15 AEST while its own races are still running to 17:00-19:30. Log-verified 2026-09-09: the 02:15Z pass discovered all six of that day's meetings, the 04:15Z pass discovered one, the 06:15Z pass discovered none. The in-band signal is per meeting, not per day — watch its own as_of and scratching_sheet_as_of: a stamp that stops moving while later passes land on other meetings is a meeting that has gone underway, not a quiet one. From that point race-day movement is on /v1/racing/changes, not here.
  - `meeting_count` integer, required
  - `race_count` integer, required
  - `runner_count` integer, required: Acceptance rows on this card — scratched runners and emergencies INCLUDED. A floor, not a guarantee, wherever a race reports runner_set_status other than 'checks_passed'.
  - `emergency_count` integer, nullable: Rows flagged as an emergency acceptance. NULL unless every meeting with rows on this card has emergency_data 'parsed' — see completeness. A FLOOR, not an exact figure, wherever a race reports runner_set_status other than 'checks_passed': it counts only the acceptance rows this card holds.
  - `declared_count` integer, nullable: runner_count minus emergency_count: the DECLARED field, i.e. the acceptances that are not emergencies. NULL when emergency_count is. A FLOOR wherever a race reports runner_set_status other than 'checks_passed'.
  - `scratched_count` integer, nullable: Sheet rows MATCHED to an acceptance row this card holds — NOT every scratching Racing Australia lists. A sheet row with no acceptance row here is not counted; it appears in that race's missing_runners with scratched true. Measured 2026-09-08: Townsville R6 has scratching_data 'parsed' and scratched_count 0 while the sheet holds #4 Five Star King and #9 Kickoff, so the true figure is at least 2. Read it as a FLOOR wherever a race reports runner_set_status other than 'checks_passed'; that race's runner_set_note states the bound. NULL unless every meeting with rows on this card has scratching_data 'parsed' — a meeting with no sheet cannot be said to have nobody scratched.
  - `unscratched_count` integer, nullable: runner_count minus scratched_count. A RECONCILIATION number against the sheet, NOT a field size: it still includes emergencies, which run only if promoted. A FLOOR wherever a race reports runner_set_status other than 'checks_passed'. NULL when scratched_count is.
  - `declared_scratched_count` integer, nullable: Rows that are scratched AND not emergencies. Like scratched_count it counts only sheet rows MATCHED to an acceptance row held here, so it is a FLOOR wherever a race reports runner_set_status other than 'checks_passed'. NULL unless BOTH emergency_data and scratching_data are 'parsed' for every meeting with rows.
  - `declared_remaining_count` integer, nullable: declared_count minus declared_scratched_count: the horses expected to jump barring an emergency promotion, which Racing Australia does not publish. It is the number to render as the field ONLY where every race behind it reports runner_set_status 'checks_passed'. Anywhere else it is a FLOOR — render it as 'at least N', never as an exact field: a runner Racing Australia lists that this card does not hold, and that is not on the scratching sheet, may well be jumping. Measured 2026-09-08: Townsville R5 is 'gap_detected' with saddlecloth #6 unaccounted for and published 11. The race's runner_set_note states the bound. NULL unless BOTH facts are known everywhere.
  - `as_of` string, nullable: Newest RA scrape backing the meetings actually returned, UTC — computed after the venue filter.
  - `coverage_from` string, nullable: The first meeting day (Australia/Sydney) this store holds an acceptance card for, read from the tables on every call — never a constant. Every day from here up to three days ahead is served; an earlier `date` is a free 422 naming this same day. Until 2026-09-29 the reference tables were deleted three days after each meeting, so the store begins at the oldest day that survived that (2026-09-26) and grows by one day per day. Null only when the store could not be read, and then the older 3-day rule applies.
  - `completeness` object, required: What could and could not be verified about this card.
  - `meetings` object[], required
  - `note` string, required

## Other responses

- `401`: Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors
- `402`: Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing
- `422`: Validation Error
- `429`: Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits
- `500`: Unexpected server error. Safe to retry with backoff.

---

[API](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api.md) · [All operations](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api/llms.txt) · [OpenAPI document](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api/revisions/f35b6aab1946?raw)
