The Betfair API 5-second delay, explained
OddsRelay · · Updated · 5 min read
Betfair's delayed application key returns exchange prices late on purpose, and only a live key, on a funded account that bets through it, removes the delay. Betfair grants live keys on its own terms, so no change to your code gets you past it.
Why does the Betfair API return delayed data?
The delay comes from the application key, not from a bug in your code. Betfair gives each developer account two keys, a delayed one for building and testing and a live one, and the delayed key is the one that works straight away. If your prices trail the Betfair website and the gap keeps changing, you are almost certainly reading on a delayed key.
The "5 seconds" quoted in forum threads is second-hand. Betfair's developer support pages describe the delayed key's prices as snapshots with a variable delay, anywhere from about a second to a few minutes, and Betfair sets that length and can change it. Build as if the exact number is unknown. Betfair's own docs carry the current terms.
Delayed application key vs live application key
The endpoints are the same on both keys. What comes back differs. Betfair says the delayed key also leaves out traded volume (totalMatched) and the full ladder of offers (EX_ALL_OFFERS), so a build that reads either sees gaps until it moves to a live key.
| Delayed application key | Live application key | |
|---|---|---|
| Price data | Returned on a delay | Undelayed |
| Traded volume and full ladder | Not returned | Returned |
| How you get it | Issued with a developer account | Granted by Betfair on its own terms |
| Suits | Development, and pre-match reads where the delay is tolerable | Betting applications, including in-play |
The split as Betfair documents it. Check Betfair's developer docs for the current terms.
Polling harder or retrying faster changes nothing, because the price left Betfair late. A live key has a condition too. Betfair's support pages say a live key used to pull data without matching bets placed through it can have a delay applied.
When the delay matters
It depends on how long a price has to stay right after you read it. Place your product in one of these before you apply for a live key.
- Pre-match matched betting: you pair a bookmaker back price with a Betfair lay price before the event starts. Pre-match prices usually move more slowly, so the delay rarely changes which bet qualifies and a delayed key is often workable.
- Content and comparison: an odds table or a match preview shows a price the reader acts on later, by hand. A delay of a minute or two rarely shows.
- In-play: prices move with every goal, wicket and point, so a delayed key is unusable. This is the case that needs a live key.
For a matched bettor, a delayed lay price costs accuracy. The lay is struck at whatever price the exchange offers when it is placed, so a delayed read means the qualifying loss worked out beforehand is off by however far the price moved. A good tool tells the user to check the exchange before placing, whatever key sits behind it.
If your product is pre-match, the delay is a smaller problem than the one beside it: pairing the lay price to the right back price, with enough money behind it to be real. How to get Betfair lay odds covers that in detail.
One exchange is only part of the lay side
Even with a live key, Betfair alone is not the whole job. A matched bettor wants the best lay against a given back price, and on some events that lay sits on another exchange. Read one exchange and you will sometimes lay at a worse price than the market offered.
A fuller build reads four exchanges, Betfair, Smarkets, Matchbook and BETDAQ, each with its own authentication and response shape. Then every lay price has to be paired to the right bookmaker back price and carry the money available at that price. The delayed key is the first wall you hit. It is far from the last.
What a matched feed changes
OddsRelay does that pairing before the data reaches you. The feed covers 140+ bookmakers, 60+ of them live in the UK & Ireland, bet365 included, and the standard board pairs bookmaker back prices against lay prices from the same four exchanges. You hold one key and one response shape, and no exchange application key of your own.
Each outcome carries back offers, a bookmaker's price, and lay offers, an exchange's price with available, the money on offer. The pairs are liquidity-gated. The rating and qualifying loss are simple arithmetic on the pair, and the oddsmatcher widget shows them. Why lay liquidity matters explains why available matters as much as the price.
{
"meta": {
"region": "uk",
"odds_format": "decimal",
"processed_at": "2026-09-20T12:18:11.402Z",
"last_seen": {
"william_hill": { "soccer": "2026-09-20T12:18:09Z" },
"betfair_exchange": { "soccer": "2026-09-20T12:18:07Z" }
},
"count": 1,
"version": "v2",
"next_cursor": null
},
"data": [{
"event_id": "or_evt_917dd44bce05",
"sport_key": "soccer_epl",
"sport_title": "Premier League",
"commence_time": "2026-09-20T14:00:00Z",
"home_team": "Arsenal",
"away_team": "Chelsea",
"markets": [{
"key": "h2h",
"outcomes": [{
"name": "Arsenal",
"back": [{ "bookmaker": "william_hill", "price": 2.9, "link": null }],
"lay": [{ "exchange": "betfair_exchange", "price": 3.0, "available": 175, "link": null }]
}]
}]
}]
}Every response dates its prices
A matched feed does not make price age go away. It tells you how old a price can be. Every response carries meta.processed_at, the time the board was built. On a matched board, meta.last_seen gives the last read for each venue and sport, so now minus last_seen is an upper bound on how old that venue's price is.
const outcome = board.data[0].markets[0].outcomes[0]; const back = outcome.back[0]; const lay = outcome.lay[0]; // Your arithmetic, not a field in the feed. const rating = (back.price / lay.price) * 100; // 96.7 // Upper bound on each side's age, in seconds. "soccer" is the sport's group key. const ageOf = (venue) => (Date.now() - Date.parse(board.meta.last_seen[venue].soccer)) / 1000; const backAge = ageOf(back.bookmaker); const layAge = ageOf(lay.exchange);
Checking often is cheap. Every data reply carries an ETag: send it back as If-None-Match and an unchanged board comes back as a 304 that costs no tokens. The conditional requests guide shows the loop.
Every product on sale must meet a maximum update time of 10–20 s. That fits pre-match matched betting and comparison. The feed is built for pre-match data and has no in-play product, so an in-play tool needs its own live Betfair key.
Our view: build around the age you can measure, and treat every price as old until its timestamp says otherwise. A product that shows each price's age to the user fails more gracefully than one that assumes speed. The freshness guide covers both fields and the sport keys behind last_seen.
Where to go from here
Check which venues and sports are live right now on the coverage page, then read the quickstart for the first call. When you want a key for your own build, request access.