API reference / Racing
GET /v1/racing/marketsEvery market on one race: win, place, Top 2/3/4 and exotic dividends
One race, every market the panel quotes on it, book by book: the win price, the place price, the Same Race Multi legs (**Top 2, Top 3 and Top 4**), each book's market percentage, the best price per runner in each market, and — once the race has been run — the exotic dividends it paid. **Naming the race.** `race_id` 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, because picking one of a venue split silently would be worse than refusing. **Who quotes what.** Every book in the panel prices win, and all but the exchange price place. Top 2/3/4 come from **sportsbet, ladbrokes_au, neds and pointsbetau** — no other book in the feed publishes Same Race Multi legs, so an empty `top3` is a fact about the market and not a gap in the feed. Each leg is validated against the chain win >= top2 >= top3 >= top4 > 1.0 before it is stored, so a leg that would break it is absent rather than wrong. **overround_pct** is Σ (1/price) × 100 over the runners that book quoted in that market — 100% is a book taking no margin. It is null where a book quoted fewer than two runners, which is not a market. Place and Top-N percentages are naturally far above 100 because several runners can win the bet. **Live or stored.** A race whose market is still open is read live (`source: "live"`). Once it has been run the live rows are purged, and the answer comes from the minute-by-minute capture of the last price each book showed before the jump (`source: "closes"`). Races that jumped before that capture began carry no market rows and say so in `note`. **exotics** are SETTLED DIVIDENDS — what the tote paid — not prices. Nothing in this feed quotes fixed-odds quinella, exacta, trifecta or first four before a race, so `exotics` is null until the race is resulted, and then carries the result's own `status`: `interim` dividends can still move, `final` cannot. **quote_detail** (since 2026-09-29) lists, per book and runner, what the book publishes beside its prices: `open_price` (the book's own opening price — not the archive's first captured price), `flucs` (its recent prices, most recent first), `tote_win` / `tote_place` (its tote dividends keyed by product code; `PROV` is an indicative pre-race dividend that moves until the pool closes), `boost_price` / `boost_type`, and the exchange fields. Each entry names `bookmaker`, `number`, `name`, `runner_ref` and `seen_at` — when the book was last read — and only the fields that book carries. Who carries them, measured on the AU board of 2026-09-29 before its first race (20 races, 2,219 book-runner rows): flucs at betdeluxe, betgold, boostbet and betright on every row, open_price at betright on every row, tote_win at tabtouch on 89 of 194 rows and tote_place on 26 (a provisional dividend appears as the pool forms), no boost that morning. The exchange fields are Betfair's, and Betfair is withheld from customer answers. For a race that has been run the values are the last read before the jump. **scratchings** (since 2026-09-29) are the race's scratched runners — `name`, `number`, `barrier`, `scratched_at` (the scratching book's own time, UTC) and `vacant` for an empty box — from the open race while it is live, and once it has been purged from the capture taken at the jump. A race run before 2026-09-29 answers an empty list after its purge. Plus and above, and Standard keys issued before 20 September 2026. Every other key below Plus receives a 403 and is not charged.
X-API-Key
2 credits
curl 'https://api.puntersedge.online/v1/racing/markets' \
-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, /results or the archive. 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 | |
bookmakers |
query | string | no | Comma-separated bookmaker keys to restrict to. Omit for every book quoting the race. |
markets |
query | string | no | Comma-separated subset of win, place, top2, top3, top4, exotics. Omit for all of them. |
Status codes: 200, 401, 402, 403, 404, 409, 422, 429, 500. Response bodies are JSON; the full schema is in /openapi.json.
200 application/json
— this call costs 2 credits.
Field names and types are as the API returns them; values are a real sample, trimmed to a few items.
{
"race": {
"race_id": "81db7342-2e44-482a-bf62-5d5166d764f5",
"venue": "Tatura",
"race_number": 1,
"category": "horse",
"country": "AU",
"start_time": "2026-09-29T03:30:00Z",
"places_paid": 3,
"status": "resulted",
"source": "closes"
},
"markets": [
{
"market": "win",
"places": 1,
"bookmakers": [
{
"key": "betright",
"runners_quoted": 9,
"overround_pct": 120.34,
"observed_at": "2026-09-29T03:29:36.794038Z",
"runners": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"horse_ref": "pe:alphamensae",
"price": 17.0,
"source_url": null
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"horse_ref": "pe:theshyster",
"price": 2.35,
"source_url": null
}
]
},
{
"key": "pointsbetau",
"runners_quoted": 9,
"overround_pct": 120.49,
"observed_at": "2026-09-29T03:29:58.949035Z",
"runners": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"horse_ref": "pe:alphamensae",
"price": 17.0,
"source_url": null
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"horse_ref": "pe:theshyster",
"price": 2.3,
"source_url": null
}
]
}
],
"best": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"price": 17.0,
"bookmaker": "betright"
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"price": 2.35,
"bookmaker": "sportsbet"
}
]
},
{
"market": "place",
"places": 3,
"bookmakers": [
{
"key": "betright",
"runners_quoted": 9,
"overround_pct": 363.62,
"observed_at": "2026-09-29T03:29:36.794038Z",
"runners": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"horse_ref": "pe:alphamensae",
"price": 3.8,
"source_url": null
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"horse_ref": "pe:theshyster",
"price": 1.25,
"source_url": null
}
]
},
{
"key": "pointsbetau",
"runners_quoted": 9,
"overround_pct": 376.36,
"observed_at": "2026-09-29T03:29:58.949035Z",
"runners": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"horse_ref": "pe:alphamensae",
"price": 3.6,
"source_url": null
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"horse_ref": "pe:theshyster",
"price": 1.17,
"source_url": null
}
]
}
],
"best": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"price": 3.8,
"bookmaker": "betright"
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"price": 1.26,
"bookmaker": "tab"
}
]
},
{
"market": "top2",
"places": 2,
"bookmakers": [
{
"key": "pointsbetau",
"runners_quoted": 9,
"overround_pct": 251.86,
"observed_at": "2026-09-29T03:29:58.949035Z",
"runners": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"horse_ref": "pe:alphamensae",
"price": 6.33,
"source_url": null
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"horse_ref": "pe:theshyster",
"price": 1.43,
"source_url": null
}
]
}
],
"best": [
{
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"price": 6.33,
"bookmaker": "pointsbetau"
},
{
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"price": 1.5,
"bookmaker": "ladbrokes_au"
}
]
}
],
"exotics": {
"source": "results",
"status": "final",
"dividends": [
{
"code": "QN",
"type": "Quinella",
"product": "VIC",
"selection": "8,13",
"amount": 25.5
},
{
"code": "TF",
"type": "Trifecta",
"product": "VIC",
"selection": "8,13,7",
"amount": 178.1
}
]
},
"note": null,
"quote_detail": [
{
"bookmaker": "betright",
"number": 2,
"name": "Around The Marx",
"runner_ref": "ra:NDIzMDk5ODU2OTY",
"seen_at": "2026-09-29T03:29:58.463340Z",
"open_price": 19.0,
"flucs": [
23.0,
26.0,
21.0
],
"tote_win": {
"RD+": 21.909
},
"tote_place": {
"MIDDIV": 4.0
}
},
{
"bookmaker": "tabtouch",
"number": 1,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"seen_at": "2026-09-29T03:29:59.993599Z",
"tote_win": {
"PROV": 16.2
},
"tote_place": {
"PROV": 3.6
}
},
{
"bookmaker": "betgold",
"number": 8,
"name": "The Shyster",
"runner_ref": "ra:NDIzMjAzNDI2NDA",
"seen_at": "2026-09-29T03:30:00.918826Z",
"flucs": [
2.3,
2.35,
2.4,
2.45,
2.4,
2.45,
2.4,
2.45,
2.4,
2.45,
2.4,
2.45,
2.4
]
},
{
"bookmaker": "betdeluxe",
"number": null,
"name": "Alpha Mensae",
"runner_ref": "ra:NDIzMzYyNjA2MjQ",
"seen_at": "2026-09-29T03:30:00.351934Z",
"flucs": [
8.5,
15.0,
16.0,
18.0
]
}
],
"scratchings": [
{
"name": "Inside Word",
"number": 5,
"barrier": 11,
"scratched_at": "2026-09-28T21:30:08Z"
},
{
"name": "Japanese Moka",
"number": 6,
"barrier": 13,
"scratched_at": "2026-09-27T22:56:17Z"
},
{
"name": "Tyrant Rex",
"number": 9,
"barrier": 9,
"scratched_at": "2026-09-28T10:18:19Z"
},
{
"name": "Chapel Belle",
"number": 10,
"barrier": 12,
"scratched_at": "2026-09-28T04:09:14Z"
}
]
}
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