API reference / Racing
GET /v1/racing/intelligenceMarket intelligence on one race: consensus at fixed marks, time-anchored moves, breadth, first mover, signal
One race on the live board: for every runner, the market consensus price now and at fixed marks before the jump (T-60, T-30, T-15, T-10, T-5, T-2), its high and low since capture began, movement measured against those marks and against the last five and two minutes, the number of ticks in the last five minutes, the best price against the consensus, how many books moved with the headline, the first attributable book to move, and a signal class whose rule is printed in the response. **Naming the race.** `race_id` from /v1/racing/next-to-go or /v1/racing/events is exact. Failing that, `venue` + `meeting_date` (AET) + `race_number`; a venue split answers 409 and costs nothing. **Time-anchored, not open-anchored.** Every movement figure compares the consensus NOW with the consensus at a fixed time, computed by the same arithmetic as GET /v1/racing/consensus and the archive's consensus columns: each book's win prices with its margin removed, the median across books, the field scaled to one. `move_from_t60_pct` is negative for a runner that shortened. A mark is null when the race had not entered the capture window by then — capture begins 60 minutes before the jump, so a race further out than that carries `now` only and `window.open` is false. **Breadth.** `with_history` counts books quoting now with two or more captured prices on the runner; `firming`, `drifting` and `unchanged` partition them by each book's own price against its price at T-60 (or its first tick, when it joined later). A headline move that most of `with_history` did not make is one book repricing, not the market. **First mover** names the earliest attributable book to move at least 5 % in the headline direction, with its lead over the next book and the median lag of the followers. It is `undetermined` when fewer than two attributable books moved or when the lead is inside the 30-second attribution floor (the books are polled every 8–17 seconds). Books whose timestamps cannot order a move are excluded and named in `method`: push-fed books (the stamp is the receipt, not the read) and books polled slower than the floor. **Signal** is one of `strong_firm`, `firm`, `steady`, `drift`, `strong_drift` or `insufficient`, from `move_from_t60_pct` and the breadth, by the rule in `method.signal_rule`. It is a classification of what the market did, not a prediction; its strike rate against results will be published on the market report once the archive carries it. **Live only.** A race that has left the live board answers 404; a race inside the ten minutes after its jump is still served while the books drop off, with a note. Every plan, Free included. 3 credits, charged after the race is found.
X-API-Key
3 credits
curl 'https://api.puntersedge.online/v1/racing/intelligence' \
-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 or /events. |
venue |
query | string | no | Venue as the feeds spell it; needs meeting_date and race_number. |
meeting_date |
query | string | no | AET meeting date, YYYY-MM-DD. |
race_number |
query | string | no | |
min_books |
query | integer | no | Included books a runner needs before it carries a consensus at a mark. |
Status codes: 200, 401, 402, 404, 409, 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.
{
"race": {
"race_id": "2e33fc28-13a5-421b-a6f3-6f99283c5cb6",
"venue": "Menangle",
"race_number": 2,
"category": "harness",
"country": "AU",
"start_time": "2026-10-06T01:43:00Z",
"secs_to_jump": 763,
"status": "upcoming",
"as_of": "2026-10-06T01:30:16Z"
},
"window": {
"open": true,
"first_tick_at": "2026-10-06T00:43:01Z",
"ticks_total": 412,
"books_in_ticks": 14,
"marks_available": [
"t60",
"t30",
"t15",
"m5",
"m2"
]
},
"method": {
"consensus": "power, median across books, field scaled to one (consensus_math); a book counts at a mark when it has a tick at or before it and is still in the market",
"min_books": 2,
"signal_rule": "strong_firm: move_from_t60_pct <= -15 and firming >= 0.6 x with_history; firm: <= -7 and firming >= 0.5 x; strong_drift / drift the mirror; steady otherwise; insufficient when there is no T-60 consensus, or when a move of 7% or more rests on fewer than 3 books with history",
"attribution_floor_seconds": 30,
"attribution_excluded_books": [
"betgold",
"boostbet",
"palmerbet",
"sportsbet"
]
},
"market": {
"market_pct": {
"now": 124.44,
"t15": 127.26,
"t60": 126.78
},
"favourite": {
"now": "Alpha Stride",
"at_t10": null,
"changed_last_10m": null
},
"books_in_consensus_now": 13,
"books_at_t60": 14
},
"runners": [
{
"runner_key": "alphastride",
"number": 10,
"name": "Alpha Stride",
"runner_ref": null,
"horse_ref": null,
"books_at": {
"now": 13,
"t60": 14,
"t15": 13
},
"consensus": {
"now": 3.77,
"t60": 4.5,
"t30": 4.46,
"t15": 4.44,
"t10": null,
"t5": null,
"t2": null,
"high": {
"price": 4.5,
"at": "2026-10-06T00:43:01Z"
},
"low": {
"price": 3.77,
"at": "2026-10-06T01:30:16Z"
}
},
"move_from_t60_pct": -16.22,
"move_from_t15_pct": -15.09,
"move_last_5m_pct": -15.09,
"move_last_2m_pct": -9.59,
"ticks_last_5m": 25,
"best": {
"price": 3.6,
"bookmaker": "playup",
"vs_consensus_pct": -4.54
},
"breadth": {
"quoting": 13,
"with_history": 13,
"firming": 12,
"drifting": 1,
"unchanged": 0
},
"first_mover": {
"bookmaker": null,
"status": "undetermined",
"reason": "lead of 0s is inside the 30s attribution floor"
},
"signal": "strong_firm"
},
{
"runner_key": "callmejack",
"number": 2,
"name": "Call Me Jack",
"runner_ref": null,
"horse_ref": null,
"books_at": {
"now": 13,
"t60": 14,
"t15": 13
},
"consensus": {
"now": 4.95,
"t60": 4.52,
"t30": 4.64,
"t15": 4.72,
"t10": null,
"t5": null,
"t2": null,
"high": {
"price": 4.95,
"at": "2026-10-06T01:30:16Z"
},
"low": {
"price": 4.5,
"at": "2026-10-06T00:44:01Z"
}
},
"move_from_t60_pct": 9.51,
"move_from_t15_pct": 4.87,
"move_last_5m_pct": 5.1,
"move_last_2m_pct": 2.91,
"ticks_last_5m": 11,
"best": {
"price": 4.0,
"bookmaker": "betright",
"vs_consensus_pct": -19.17
},
"breadth": {
"quoting": 13,
"with_history": 13,
"firming": 0,
"drifting": 13,
"unchanged": 0
},
"first_mover": {
"bookmaker": "playup",
"status": "attributed",
"at": "2026-10-06T00:43:32Z",
"lead_seconds": 35,
"median_follower_lag_seconds": 1334,
"followers": [
"betright",
"pointsbetau",
"tabtouch",
"betr_au",
"betdeluxe",
"tab",
"unibet"
]
},
"signal": "drift"
},
{
"runner_key": "bertinelli",
"number": 1,
"name": "Bertinelli",
"runner_ref": null,
"horse_ref": null,
"books_at": {
"now": 13,
"t60": 14,
"t15": 13
},
"consensus": {
"now": 6.71,
"t60": 6.61,
"t30": 6.51,
"t15": 6.52,
"t10": null,
"t5": null,
"t2": null,
"high": {
"price": 6.71,
"at": "2026-10-06T01:30:01Z"
},
"low": {
"price": 6.5,
"at": "2026-10-06T01:17:01Z"
}
},
"move_from_t60_pct": 1.51,
"move_from_t15_pct": 2.91,
"move_last_5m_pct": 2.91,
"move_last_2m_pct": 1.82,
"ticks_last_5m": 1,
"best": {
"price": 5.5,
"bookmaker": "betright",
"vs_consensus_pct": -18.08
},
"breadth": {
"quoting": 13,
"with_history": 4,
"firming": 0,
"drifting": 4,
"unchanged": 0
},
"first_mover": {
"bookmaker": null,
"status": "undetermined",
"reason": "fewer than two attributable books moved"
},
"signal": "steady"
}
],
"scratchings": [],
"note": null
}
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/consensus — The market consensus on one race: margin-free probability per runnerGET /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 resultsThe free tier needs no credit card, and the sandbox endpoints need no key at all.
Get a free API key Quickstart