Racing

Upcoming race list

Cost: 1 credit. The CARD - every race scheduled in the requested window, optionally filtered by racing category and country. EVERY country is served by default, not only AU and NZ — pass country=AU (pairing it with include_unresolved=true, per that parameter) if you want an Australian card.

How far ahead you can see (2026-09-22). hours_ahead reaches 24h on Free and Hobby, 48h on Standard, and 168h (7 days) on Plus and above. Every response carries your ceiling as X-Horizon-Hours and the window actually used as X-Horizon-Used-Hours, so you never have to discover it by trial. Asking past it is a 403 naming the tier that reaches further, and costs no credit -- it is never a silent clamp to a shorter window. date=YYYY-MM-DD is the single-day alias for an Australian Eastern meeting day; a day is reachable when its last moment is inside your horizon, so it is bounded by the same ceiling rather than being a second entitlement.

Nothing lost anything here: 24h was the hard cap for every plan, free included, until this landed, and Free and Hobby still have exactly that. AU cards carry thoroughbred, harness and greyhound; NZ cards carry thoroughbred and harness.

Hong Kong (country=HK, feature_requests #29, 2026-09-09) is listed too, on the HKJC's own nights — Happy Valley on Wednesday evenings and Sha Tin on Saturday or Sunday afternoons, AEST — whenever an Australian bookmaker quotes the meeting. Thoroughbred only, and PRICES ONLY on /v1/racing/next-to-go and /v1/racing/best-odds: a Hong Kong race carries no results, form, race conditions or runner_ref, because those come from Racing Australia and cover AU thoroughbreds only (horse_ref is derived from the runner's name, so it is there). Foreign meetings other than Hong Kong still appear here whenever a book in the panel lists them; this endpoint has never filtered them out.

This is the schedule endpoint, and it lists a race before any book has priced it. Since 2026-09-01 the feed reads the early markets (Sportsbet's full card 3-12h out, BetRight's early lane, a PointsBet wide sweep), so the FIRST price on a race now lands well ahead of the jump: measured over the 48h to 2026-09-03 11:00 UTC, median 10.1h before the jump on AU thoroughbreds (79 of 80 races priced 3h+ out), 5.3h on AU greyhounds, 6.8h on AU harness. That first price is one or two books; the full board still fills inside about an hour of the jump. A race listed here with no prices yet is one no book has opened - /v1/racing/next-to-go carries the priced window, and the race.odds_open webhook fires the moment a race's first prices land.

scratchings is served here as well as on /v1/racing/next-to-go, so a scratching is visible from the moment a book reports it rather than only once the race enters the priced window. Its entries are {name, number, barrier, scratched_at, late, emergency}, merged across every reporting book — scratched_at (UTC) is the book's own stamp where it sends one (Ladbrokes, Neds, BetRight) and Racing Australia's official scratching sheet otherwise for AU thoroughbreds, read every two hours; late and emergency come from the same sources. On greyhound cards some entries are box-vacancy placeholders - a literal '....' or 'Vacant Box' - and several books can report the same empty box separately, so count boxes by number, not by list length.

status is written when the race row is created and never revised, so every race in this window reads 'open'. market_status and inplay are the live betting-market state.

market_closed_at and inplay_at are the race lifecycle: when the market was first seen shut, and when the race was first seen in-play — the actual off, where start_time is the advertised one and moves. Both are POLL-OBSERVED: each is the first poll at which the state was seen, so it lands up to one polling pass after it, and passes are most frequent in the minutes before the jump. Both are SET ONCE, so a market that flickers SUSPENDED -> OPEN -> SUSPENDED reports the first suspension. Null never means the market stayed open. This endpoint serves upcoming races and the live row is purged 10 minutes after the jump; /v1/racing/results carries the same fields permanently.

Who reports market state, and what you see. Two feeds do. PointsBet closes its book at the real jump — measured 2026-09-03 over 9 live races followed across their jump, 0.2 to 1.4 minutes AFTER the advertised start on AU/NZ cards — and that is what populates market_closed_at for most races. The Betfair Exchange reports state while it quotes the market, which ends about two minutes BEFORE the jump (measured 2026-09-01 on Horsham R3, advertised 05:24 UTC: betfair last seen 119s before the off), which is why these fields read null on every race before 2026-09-03. Exchange-sourced market state is withheld from customer plans pending a data licence, so a race whose state only the exchange saw reads null for customers; bookmaker-sourced state is served to everybody. market_state_source names the feed behind the values you receive, and is itself null whenever they are withheld.

inplay_at stays exchange-only: bookmakers do not run racing in-play, so a bookmaker feed can say when it CLOSED its book but not when the race went. For a race the exchange has stopped quoting, market_closed_at is the closest measured instant to the off.

get/v1/racing/events

Request

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

Query parameters

hours_aheadinteger

How many hours ahead to list, from now. Your ceiling depends on the plan and is returned on every response as X-Horizon-Hours: 24 on Free and Hobby, 48 on Standard, 168 (7 days) on Plus and above. Asking past your ceiling is a free 403 naming it, never a silent clamp. Mutually exclusive with date.

datestring nullable

Single-day alias: date=YYYY-MM-DD lists that Australian Eastern meeting day instead of a rolling hours_ahead window. Mutually exclusive with hours_ahead. A day is reachable when its last moment is inside your horizon, so this is bounded by the same X-Horizon-Hours ceiling and is not a separate entitlement. Forward-looking only -- a past date is a free 422 pointing at /v1/racing/results and /v1/racing/closing-lines.

categoriesstring
categorystring

Alias of categories. Both spellings are accepted on every racing endpoint. An unknown value is a free 422 naming the valid ones.

countrystring

ISO country codes, comma-separated (e.g. AU, AU,NZ, GB,IE for the British and Irish card or ZA for the South African card). Omit for every country. HK lists Sha Tin and Happy Valley on the HKJC race nights (prices only, no results or form). Pair with include_unresolved=true or you will silently lose races whose meeting is not confirmed yet.

include_unresolvedboolean

Include races whose country is not resolved yet (country is null). OFF by default. Most of an Australian card is unresolved until the meeting is confirmed — 58.8% of horse races in a measured window — so country=AU alone can return far fewer races than are running, or none at all. Pass true to get them, and read country per race to see which are still unresolved.

Headers

X-API-Keystring
X-RapidAPI-Proxy-Secretstring

Response

Successful Response

race_idstring required
venuestring nullable required
venue_idstring nullable
venue_canonicalstring nullable
venue_sitestring nullable
race_numberinteger nullable required
categorystring nullable required
start_timestring required
countrystring nullable required
race_namestring nullable
distance_minteger nullable
track_conditionstring nullable
weatherstring nullable
race_classstring nullable

The first term of RA's official conditions line ('BenchMark 64', 'Maiden', 'Group 1'). AU thoroughbred only.

conditionsstring nullable

RA's official conditions line, verbatim.

prize_totalinteger nullable

Total advertised prize, whole AUD.

railstring nullable

Rail position for the meeting, as RA publishes it.

track_namestring nullable

RA's own name for the course this race runs on ('Hillside', 'Randwick', 'Main'). AU thoroughbred only; null elsewhere.

track_condition_changed_atstring nullable

UTC instant of the most recent logged track-condition, weather or rail transition for this race's meeting; null when nothing has changed since we began watching it. The sequence is on /v1/racing/track-conditions.

statusstring nullable

Set when the race row is created and revised exactly once, if at all: to 'abandoned' when Racing Australia posts an official abandoned, postponed or transferred notice for the meeting (2026-09-06). Otherwise it reads 'open' for every race in this window. It is not a live market-state signal - /v1/racing/results carries the settled status (interim, final, abandoned).

scratchingsobject[]

Scratched runners for this race: {name, number, barrier, scratched_at, late, emergency}. scratched_at (UTC) is the book's own stamp where it sends one (Ladbrokes, Neds, BetRight) and Racing Australia's official scratching sheet otherwise (AU thoroughbreds, read two-hourly); absent when neither knows. late marks a late scratching, emergency an emergency that did not gain a start. Merged across every book that reports one. Greyhound cards also carry box-vacancy placeholders here (a literal '....' or 'Vacant Box'), which are the reporting book naming an empty box rather than a withdrawn runner; match on number and treat a name from that set as a vacant box.

market_statusstring nullable

Betting-market state (OPEN, SUSPENDED, CLOSED). Reported by PointsBet, which sends CLOSED when it shuts its book at the jump, and by the Betfair Exchange, which is withheld from customer responses pending a data licence — so a value last written by the exchange reads null. Most races are quoted by both: the exchange holds the state until about two minutes before the jump, PointsBet reports the close.

inplayboolean nullable

True once the market is in-play. Exchange-only — bookmakers do not run racing in-play — so it carries the same licence hold as market_status and reads null for customers.

market_closed_atstring nullable

UTC time at which the market was FIRST seen shut — the book stopped taking bets on this race. Poll-observed: this is the first poll that saw the state, not the exact instant, so it lands up to one polling pass after it, and passes are most frequent in the minutes before the jump. Set once: a market that flickers SUSPENDED -> OPEN -> SUSPENDED keeps the FIRST suspension. TWO SOURCES report market state. PointsBet closes its book at the real jump — measured 2026-09-03 over 9 live races followed across their jump, 0.2 to 1.4 minutes AFTER the advertised start on AU/NZ cards — and the Betfair Exchange reports it while it quotes the market, which is until about two minutes before the jump. market_state_source names the one that produced this value. Exchange-sourced stamps are withheld from customer plans, so a race seen shut only by the exchange reads null. Bookmaker-sourced stamps are served to everybody. Null also means no feed observed a transition — it never means the market stayed open.

inplay_atstring nullable

UTC time at which the race was FIRST seen in-play — the actual off, as opposed to start_time, which is the ADVERTISED off and moves. Same poll-observed, set-once semantics as market_closed_at, and withheld on the same source rule. Reported by the Betfair Exchange only: bookmakers do not run racing in-play, so a bookmaker feed says when it CLOSED its book, not when the race went. For a race the exchange has stopped quoting, market_closed_at from a bookmaker is the closest measured instant to the off.

market_state_sourcestring nullable

Which feed's market state produced market_closed_at / inplay_at on this race — 'pointsbetau' for the bookmaker, 'betfair_ex_au' for the exchange. Set once, alongside the first stamp. Null when no transition has been observed, and null for customer plans whenever the stamps themselves are withheld, so a non-null value here is always the provenance of values you can see.

Example response

[
  {
    "category": "horse",
    "country": "AU",
    "market_closed_at": "2026-06-07T04:11:12Z",
    "market_state_source": "pointsbetau",
    "market_status": "CLOSED",
    "race_id": "race_123",
    "race_number": 4,
    "scratchings": [
      {
        "barrier": "9",
        "name": "Soul Of Spain",
        "number": 9
      }
    ],
    "start_time": "2026-06-07T04:10:00Z",
    "status": "open",
    "venue": "Eagle Farm"
  }
]

Changes

No recorded changes to this operation across all 1 revision of this API.