REST response latency
Median and p95 from the public status feed.
API statusHorse racecards, scratchings and win/place odds from 11 bookmakers plus Betfair exchange, delivered over REST, SSE and WebSocket.
Plus Betfair exchange. Australia, New Zealand, Great Britain and Ireland.
Sportsbet
Ladbrokes
PlayUp
PointsBet
Dabble
BetRight
Betr
Unibet
Sky Bet
William Hill
Paddy Power
Betfair ExchangeMedian and p95 from the public status feed.
API statusScheduled check pauses. Sportsbet uses push.
Scrape timesDecimal prices by runner and bookmaker.
win_odds and place_odds. Place terms come from the bookmaker. Exotics, in-play prices and results are not included.
Price collection opens 24 hours before start. Checks speed up in the final 10 minutes.
Check pauses for Ladbrokes, PlayUp, PointsBet, Dabble, BetRight, Betr and Unibet.
| Time or source | Configured timing | Applies to |
|---|---|---|
| UK bookmaker checks | 2 seconds | Sky Bet, William Hill and Paddy Power in the near-start window. |
| Sportsbet | Push-based collection | The next collection request follows the source's long-poll response. |
| More than 1 hour before start | 30 minutes | Early collection inside the 24-hour window. |
| 1 hour to 12 minutes before start | 10 minutes | Early collection before the near-start handover. |
These are configured pauses between collection cycles, not guaranteed quote ages. Source response time and pacing add to the cycle; PlayUp requests have a minimum 1.5-second spacing. Collection settings checked 16 October 2026.
REST latency measures an API request, not the time since a bookmaker changed its price. Use source timestamps for quote age.
Match bookmaker prices using runner_number.
Illustrative response · decimal prices
| Bookmaker | Win | Place |
|---|---|---|
| 3.40 | 1.65 | |
| 3.55 | 1.70 |
{
"event_id": "HORSE_RACE_ID",
"as_of_ts_ms": 1788411600000,
"items": [
{
"bookmaker_name": "sportsbet",
"runners": [{
"runner_number": "4",
"runner_name": "Horse Four",
"win_odds": 3.40,
"place_odds": 1.65
}]
},
{
"bookmaker_name": "ladbrokes",
"runners": [{
"runner_number": "4",
"runner_name": "Horse Four",
"win_odds": 3.55,
"place_odds": 1.70
}]
}
],
"resume": "1788411600000-0"
}| Data | Fields | Use in your app |
|---|---|---|
| Race identity | event_idrace_venuerace_number | One race reference connecting the meeting venue, card number, racecard and odds requests. |
| Card and start | race_start_timerace_distancerace_statestatus | Unix start time, advertised distance, jurisdiction state and current race status. |
| Horse and connections | runner_numberrunner_namejockey_nametrainer_name | The declared horse and its supplied jockey and trainer metadata inside the racecard. |
| Non-runners and deductions | runner_statusis_scratchedremoval_dateadjustment_factor | Explicit signals for a withdrawn horse and any source-supplied price adjustment factor. |
| Bookmaker market | bookmaker_namewin_oddsplace_odds | Decimal win and place prices for each priced runner, grouped by bookmaker. |
| Freshness and continuity | as_of_ts_msupdated_at_tsresume | Snapshot time, an optional bookmaker timestamp when source metadata is requested, and the continuation token for supported updates. |
race_country=GBrace_country=IErace_country=AUrace_country=NZRequest the next horse races and keep the event_id, start time, venue and race number needed by your product.
GET /v1/racing/events?race_type=horse-racing&status=fetching&limit=25Read the current runners, race distance, start time and available connection metadata before showing the market.
GET /v1/racing/events/{event_id}Group items by bookmaker_name and match the same horse by runner_number inside items[].runners[].
GET /v1/racing/events/{event_id}/oddsContinue from resume for supported price changes and reload the snapshot whenever the stream requests a resync.
SSE or WebSocketEnterprise grade
Custom projects, scoped with your team.
Timing checked 16 October 2026.
The horse racing catalog includes 11 fixed-odds bookmakers: Sportsbet, Ladbrokes, PlayUp, PointsBet, Dabble, BetRight, Betr, Unibet, Sky Bet, William Hill and Paddy Power, plus Betfair exchange. Prices are grouped by source and joined to the field using event ID and runner number.
The normalized racing response returns separate decimal win_odds and place_odds for each priced runner. Keep the source's place terms with each offer when comparing place prices.
Earlier collection checks every 30 minutes, tightening to every 10 minutes from one hour to 12 minutes before start. In the final 10 minutes, configured pauses for the Australian request bookmakers tighten from 4 seconds to 0.75 seconds; PlayUp has a minimum 1.5-second request spacing. Sky Bet, William Hill and Paddy Power use 2-second near-start pauses. Sportsbet uses push-based collection. These are collection settings, while actual price age is read from source timestamps.
Use race_type=horse-racing on GET /v1/racing/events. Legacy horse and thoroughbred aliases are normalized, but horse-racing is the canonical value for new integrations.
Keep every horse inside its event_id and join bookmaker rows on runner_number. Use runner_name as a display and validation field rather than the primary key.
The compact runner model can include jockey_name and trainer_name when those fields are supplied. Your application should allow either field to be absent without dropping the horse or its price.
Use runner_status, is_scratched and removal_date when present. Do not infer a non-runner from one missing bookmaker price, and use adjustment_factor only when supplied.
Yes. Load the odds snapshot first, then connect to its SSE or WebSocket route and continue from the latest resume token. Reload the snapshot after a resync event.
For an eligible scheduled race, bookmaker price collection starts 24 hours before its advertised start. The racecard can appear in event discovery earlier, so use the event status and current odds response to confirm active prices.