Developers / Freshness
Every racing quote carries its own age. Here is what that age measures, when a quote is called stale, and how old the board you receive can be.
Close to the jump, inside 3 hours, every bookmaker's price for a race is re-read on each polling pass. Further out, races are re-read on a slower cycle, which keeps a full day's card inside the bookmakers' own request limits.
Every quote carries age_seconds, the time since that price was last read from that bookmaker, and a stale flag.
On a paid plan, the /v1/racing/next-to-go board you receive was built at most 20 seconds earlier. On Free, at most 65 seconds earlier.
Right now, 15 of 15 Australian books are quoting and the median time since each was last read is 10 seconds. Every book's own figure is on data quality.
age_seconds measuresage_seconds is the time since the price was last read from the bookmaker, and last_update on the same bookmaker entry is that read time in UTC. It is the age of the read, not of the price. Capture is change-only, so a price that has not moved for a while is confirmed by every read and still shows a small age. To see when a price last moved, use price history in the API reference or the changes feed below.
age_basis says where the age counts from. With poll, it counts from the moment the price was read. With push_receipt, it counts from the moment a pushed update reached us, for an update that did not say when it was read. The true age is then longer by the sender's delay, which the payload cannot show, so treat a push_receipt age as a lower bound.
refresh_tierEach race, and each bookmaker entry on it, says which rule applies.
live, inside 3 hours of the jump: every book's price is re-read on each polling pass, and a quote older than 120 seconds is stale.card, further out: races are re-read on the slower cycle, and a quote older than 30 minutes is stale.A bookmaker entry can be card on a live race. Some books limit how often we may ask them, so they are re-read on every pass only in the final minutes before the jump. Earlier than that, their quotes refresh on the slower cycle and are published as card. A book's tier is never tighter than its race's, and age_seconds is the true age either way: only the threshold changes.
At race level, data_age_seconds is the age of the oldest quote in the race, freshest_age_seconds the newest, and stale_bookmakers names the books past their threshold. A stale book does not make the race unusable: drop that leg. If you apply your own threshold, branch on each entry's refresh_tier rather than one number, or the whole morning card will read as stale.
/v1/racing/next-to-go serves a stored board, so that callers asking the same question share one build. On a paid plan a stored board is reused only while it is younger than 20 seconds. An older one is rebuilt for you, and the rebuild is stored, so every caller reads the newer board from then on. On Free, a stored board can be up to 65 seconds old.
A race served from a stored board carries cached: true and cache_age_seconds. Every age_seconds in it is recomputed from last_update when the response is sent, so the ages are true at the moment you receive them. What a board's age limits is which price moves it can contain.
Send the ETag from a response back as If-None-Match: an unchanged board answers 304 Not Modified and costs no credits.
/v1/racing/changes returns only what moved since your last call, and it is never cached. Call it with a recent since, then send back the server_time from each response as the next since. server_time is set 30 seconds behind the clock, so a change can arrive twice but never zero times: deduplicate on race_id, name, bookmaker_key and updated_at. A since older than 30 minutes is refused without charge; fetch next-to-go and resume from the server_time it returns.
A runner appears when its win price changes. A move in the place price alone arrives with that runner's next win-price move, so poll next-to-go if place prices are your main signal.
A result is interim until its placings have been stable for 30 minutes, then final. Exotic dividends are declared once the race fully settles, a few minutes after the placings, so a just-resulted race can carry win and place dividends while exotics is still empty. It fills in on a later read.
Sports prices are re-read from each bookmaker we poll directly, with a 2-minute pause between passes; prices that reach us by push are updated as each push arrives. By default a sports market is served until it has gone 6 hours without an update, so a sports price can be hours old. Each sports market carries a quality object with its own age_seconds, and a market older than 30 minutes is flagged stale in its issues. The racing thresholds are tighter because racing prices move fastest in the minutes before the jump.
A small age means we read the bookmaker recently. It does not prove the bookmaker's own price moved, and a feed that is frozen or wrong at source can still look fresh. That limit, and what we check against it, is set out on data quality.
Data quality · Coverage report · Rate limits · API reference · Live status