Live vs pre-match odds data: which one your product needs
OddsRelay · · Updated · 5 min read
Pre-match odds are the prices before an event starts, in-play odds are the prices while it runs, and they are two different data products. OddsRelay's feed is built for pre-match. It has no in-play product.
What's the difference between in-play and pre-match odds data?
The difference is how long a price stays true. Before kick-off, a price moves on team news, money and the bookmaker's own view, and it can hold for minutes or hours. Once play starts, every incident can re-price a market at once, and bookmakers suspend markets while they do it. A price that was right a moment ago can be gone.
That changes what a feed has to do. A pre-match feed is judged on breadth, correct matching and a price age you can reason about. An in-play feed is judged on how quickly each change reaches you and whether it keeps arriving during the busiest moments of a match. They can share a schema. The engineering problems differ.
| Pre-match | In-play | |
|---|---|---|
| How long a price holds | Often minutes or hours | Often until the next incident |
| Suspensions | Occasional | Routine, around every incident |
| What the buyer checks | Coverage, matching, price age | Delivery delay under load |
| Typical delivery | Polling a board | A push stream |
The same markets, judged on different things.
A matched pair needs a market that holds still
A matched board pairs a bookmaker's back price with an exchange's lay price for the same selection. Before the off, both sides usually hold still long enough for that pair to mean something, and the lay side carries available, the money on offer at that price. In-play, both sides move between incidents and exchange money can vanish while a market settles. A pair that was correct when it was read may not exist by the time a user acts on it.
OddsRelay's feed covers 140+ bookmakers, 60+ of them live in the UK & Ireland, and each back price is paired against exchange lay from Betfair, Smarkets, Matchbook and BETDAQ and liquidity-gated. The rating and qualifying loss are simple arithmetic on the pair, and the oddsmatcher widget shows them.
Our view is that a supplier should sell the product its freshness can support and name the boundary. Stretching the word "live" over a pre-match board sets up a user to act on a price that no longer exists.
What a pre-match feed should guarantee about freshness
Every product OddsRelay sells must meet a maximum update time of 10–20 s before it launches. That figure bounds the age of a bookmaker's prices when you receive them, measured from outside the feed. It is a fact about the data in your hand. It says nothing about how often prices are collected, and we don't publish how they are collected.
The bound is the promise. The fields in each response are how you check it:
meta.processed_at(and theX-Processed-Atheader) is the board's time, on every response.meta.last_seenon a matched board gives, per venue and sport, the last time it was read. Now minus that time is an upper bound on a price's age.last_updateon each raw market is when that market last changed. It is not a heartbeat: a quiet market's time ages while the venue is still read.
// groupOf maps each sport_key to its key base (soccer, horse_racing), built from GET /v2/sports const seen = meta.last_seen[offer.bookmaker]?.[groupOf[event.sport_key]]; const ageSeconds = seen ? (Date.now() - Date.parse(seen)) / 1000 : null; // your own threshold, your own decision const usable = ageSeconds !== null && ageSeconds < myMaxAgeSeconds;
The feed drops no row for its age. If your product needs a tighter tolerance than ours, apply it on your side with the fields above. The freshness guide covers how last_seen is keyed, and the response anatomy post walks the rest of the envelope.
Pre-match data is polled, and an unchanged board costs no tokens
In-play products usually push each change down a stream, because a poll can land between incidents. The OddsRelay feed is pull only. There is no webhook, WebSocket or stream. You poll a board and send back the ETag from your last reply as If-None-Match. An unchanged board comes back as a 304, which costs no tokens.
For pre-match work that is the right trade: you choose your own polling rate and spend tokens only when the board changed. The polling post covers the loop, and webhooks vs polling sets out when push is worth its extra moving parts.
Which one does your product need?
Work back from the moment your user acts. If they act before the event starts, you need pre-match data, and paying for in-play buys a capability nothing in your product touches. If the whole point of the product is reacting to a goal or a break of serve, you need in-play, and a pre-match feed will not serve it.
- Pre-match fits an oddsmatcher, a matched-betting tool, an odds comparison page, and preview or tipping content. Every price they show is a price from before the off.
- In-play is required for in-play trading, in-play hedging and any tool built around score changes. That needs a supplier with an in-play product.
- Mixed products can split the job: pre-match boards from a pre-match feed, and the in-play screens from a specialist.
On a pre-match build, hide any row whose commence_time has passed: once the event starts, its pre-match price is history. The matched boards also take a kick-off window (commenceTimeFrom and commenceTimeTo). The matched-board filters guide lists the rest.
Next step
If your users act before the off, the coverage page shows each venue and sport the feed carries now, and the quickstart walks your first board request. When the fit looks right, request access.