The best win, place and tote price for every runner in the next races, with the bookmaker offering it and a deep link to their race page. `market_percentage` is the sum of implied probabilities at the best available price. **Under 100 means the best prices across books beat the field** — a cross-book arbitrage. Any single book's market is always over 100. `price_spread_pct` per runner is how much better the best price is than the worst currently quoted: how much a punter loses by not shopping around. ⚠️ `best_tote` is **not comparable to `best_win`**. A pre-race tote dividend is an estimate that moves as the pool fills, and taking the highest across books and products is upward biased by construction — the noisiest estimate wins. Greyhound pools are thinnest and swing hardest: measured 2026-08-15, greyhound tote-to-fixed ratios reached 8.8x on betright and 9.9x on tabtouch, against averages near 1.0 for horse and harness. A tote figure far above the fixed price is usually a thin pool, not an edge. Settle against a FINAL dividend, and read the `product` code — `PROV` is indicative, `SP`/`MIDDIV`/`RD+`/`BT+SP` are named products. The comparison covers the Australian fixed-odds bookmakers. Betfair Exchange prices are withheld pending a Betfair Exchange data licence, and non-AU reference books are excluded because an Australian punter cannot bet them — so `betfair_ex_au` never appears as a `best_win` bookmaker, and `market_percentage` is the fixed-odds market rather than an exchange-inclusive one. **Scratched runners are never priced here.** They appear in `scratchings` only, and are left out of `market_percentage`. **Every published price carries its own age.** `best_win`, `best_place` and `best_tote` each include `last_update`, `age_seconds` and `stale`, because the book with the best price is not always the book that answered most recently. Race level, `data_age_seconds` is the oldest of those winning quotes and `stale_bookmakers` names any past 120s. Responses are cached for 20s and say so via `cached` / `cache_age_seconds`; ages are recomputed at serve time, so a cached payload reports its real age rather than the age it had when it was stored.
X-API-Key
3 credits
curl 'https://api.puntersedge.online/v1/racing/best-odds' \
-H 'X-API-Key: YOUR_KEY'
| Name | In | Type | Required | Description |
|---|---|---|---|---|
num_races |
query | integer | no | |
categories |
query | string | no | horse,greyhound,harness or omit for all |
bookmakers |
query | string | no | Restrict the comparison to these bookmaker keys |
country |
query | string | no | ISO country codes, comma-separated (e.g. AU). Omit for every country. Foreign races are quoted by a median of one book, so a cross-book comparison on them compares nothing. |
Status codes: 200, 401, 402, 422, 429, 500. Response bodies are JSON; the full schema is in /openapi.json.
GET /v1/racing/events — Upcoming race listGET /v1/racing/movers — Racing steamers and driftersGET /v1/racing/next-to-go — Next races to runGET /v1/racing/price-history — Racing price history / closing lineGET /v1/racing/results — Settled race resultsThe free tier needs no credit card, and the sandbox endpoints need no key at all.
Get a free API key Quickstart