API reference / Racing
GET /v1/racing/intelligence/scanScan the live window for runners that moved: time-anchored, breadth-gated
Every race inside the 60-minute capture window, analysed exactly as GET /v1/racing/intelligence analyses one race, with the runners that cleared the filters returned largest move first. This is the time-anchored, breadth-gated form of /v1/racing/movers, and /movers keeps serving unchanged. `window` selects the movement figure the gate applies to: `60m` for the move since the T-60 consensus, `15m` since T-15, `5m` over the last five minutes — the late-window figure a last-minute mover product wants. `min_books` is the breadth gate: a runner needs that many books with two or more captured prices, so a single book repricing cannot clear it. `signal` keeps only the named classes. The response carries the race header beside each runner so nothing has to be joined. Served from a 15-second cache shared by every caller with the same filters; `cached` says so and `as_of` is the moment the scan was computed. Plus and above. 5 credits. An unknown parameter value is a free 422.
X-API-Key
5 credits
curl 'https://api.puntersedge.online/v1/racing/intelligence/scan' \
-H 'X-API-Key: YOUR_KEY'
| Name | In | Type | Required | Description |
|---|---|---|---|---|
window |
query | string | no | Which movement gates the result: 60m (move_from_t60_pct), 15m (move_from_t15_pct) or 5m (move_last_5m_pct). |
min_move_pct |
query | number | no | Minimum absolute consensus move, in percent. |
min_books |
query | integer | no | Minimum books with history on the runner (breadth). |
direction |
query | string | no | firming or drifting; omit for both. |
signal |
query | string | no | Comma-separated signal classes to keep, e.g. strong_firm,firm. |
country |
query | string | no | Country code, e.g. AU or NZ. |
categories |
query | string | no | Comma-separated subset of horse, greyhound, harness. |
limit |
query | integer | no |
Status codes: 200, 401, 402, 403, 422, 429, 500. Response bodies are JSON; the full schema is in /openapi.json.
200 application/json
— this call costs 5 credits.
Field names and types are as the API returns them; values are a real sample, trimmed to a few items.
{
"as_of": "2026-10-06T01:30:16Z",
"window_minutes": 60,
"races_scanned": 9,
"filters": {
"window": "60m",
"min_move_pct": 3.0,
"min_books": 2,
"direction": null,
"signal": null,
"country": "AU",
"categories": null,
"limit": 50
},
"method": {
"consensus": "power, median across books, field scaled to one",
"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
},
"results": [
{
"race": {
"race_id": "be7c3a48-7b83-4f28-84d6-209c51d03adc",
"venue": "HOBART",
"race_number": 6,
"category": "greyhound",
"country": "AU",
"start_time": "2026-10-06T02:22:00Z",
"secs_to_jump": 3103
},
"move_pct": 31.83,
"runner_key": "pushthebutton",
"number": 1,
"name": "Push The Button",
"runner_ref": null,
"horse_ref": null,
"books_at": {
"now": 13,
"t60": 14,
"t15": null
},
"consensus": {
"now": 109.1,
"t60": 82.76,
"t30": null,
"t15": null,
"t10": null,
"t5": null,
"t2": null,
"high": {
"price": 109.1,
"at": "2026-10-06T01:29:02Z"
},
"low": {
"price": 82.76,
"at": "2026-10-06T01:22:02Z"
}
},
"move_from_t60_pct": 31.83,
"move_from_t15_pct": null,
"move_last_5m_pct": 6.31,
"move_last_2m_pct": 6.34,
"ticks_last_5m": 1,
"best": {
"price": 41.0,
"bookmaker": "betright",
"vs_consensus_pct": -62.42
},
"breadth": {
"quoting": 13,
"with_history": 7,
"firming": 0,
"drifting": 7,
"unchanged": 0
},
"first_mover": {
"bookmaker": "unibet",
"status": "attributed",
"at": "2026-10-06T01:22:32Z",
"lead_seconds": 35,
"median_follower_lag_seconds": 85,
"followers": [
"betdeluxe",
"neds",
"ladbrokes_au",
"pointsbetau",
"playup"
]
},
"signal": "strong_drift"
},
{
"race": {
"race_id": "be7c3a48-7b83-4f28-84d6-209c51d03adc",
"venue": "HOBART",
"race_number": 6,
"category": "greyhound",
"country": "AU",
"start_time": "2026-10-06T02:22:00Z",
"secs_to_jump": 3103
},
"move_pct": 22.9,
"runner_key": "bundaberggum",
"number": 6,
"name": "Bundaberg Gum",
"runner_ref": null,
"horse_ref": null,
"books_at": {
"now": 13,
"t60": 14,
"t15": null
},
"consensus": {
"now": 500.38,
"t60": 407.13,
"t30": null,
"t15": null,
"t10": null,
"t5": null,
"t2": null,
"high": {
"price": 500.54,
"at": "2026-10-06T01:25:02Z"
},
"low": {
"price": 407.13,
"at": "2026-10-06T01:22:02Z"
}
},
"move_from_t60_pct": 22.9,
"move_from_t15_pct": null,
"move_last_5m_pct": -0.03,
"move_last_2m_pct": -0.01,
"ticks_last_5m": 0,
"best": {
"price": 126.0,
"bookmaker": "sportsbet",
"vs_consensus_pct": -74.82
},
"breadth": {
"quoting": 13,
"with_history": 3,
"firming": 0,
"drifting": 3,
"unchanged": 0
},
"first_mover": {
"bookmaker": "unibet",
"status": "attributed",
"at": "2026-10-06T01:22:32Z",
"lead_seconds": 60,
"median_follower_lag_seconds": 60,
"followers": [
"betdeluxe"
]
},
"signal": "strong_drift"
},
{
"race": {
"race_id": "be7c3a48-7b83-4f28-84d6-209c51d03adc",
"venue": "HOBART",
"race_number": 6,
"category": "greyhound",
"country": "AU",
"start_time": "2026-10-06T02:22:00Z",
"secs_to_jump": 3103
},
"move_pct": 22.9,
"runner_key": "sydneydanger",
"number": 8,
"name": "Sydney Danger",
"runner_ref": null,
"horse_ref": null,
"books_at": {
"now": 13,
"t60": 14,
"t15": null
},
"consensus": {
"now": 500.38,
"t60": 407.13,
"t30": null,
"t15": null,
"t10": null,
"t5": null,
"t2": null,
"high": {
"price": 500.54,
"at": "2026-10-06T01:25:02Z"
},
"low": {
"price": 407.13,
"at": "2026-10-06T01:22:02Z"
}
},
"move_from_t60_pct": 22.9,
"move_from_t15_pct": null,
"move_last_5m_pct": -0.03,
"move_last_2m_pct": -0.01,
"ticks_last_5m": 0,
"best": {
"price": 126.0,
"bookmaker": "betright",
"vs_consensus_pct": -74.82
},
"breadth": {
"quoting": 13,
"with_history": 3,
"firming": 0,
"drifting": 3,
"unchanged": 0
},
"first_mover": {
"bookmaker": "unibet",
"status": "attributed",
"at": "2026-10-06T01:22:32Z",
"lead_seconds": 60,
"median_follower_lag_seconds": 60,
"followers": [
"betdeluxe"
]
},
"signal": "strong_drift"
}
],
"cached": false
}
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