How to evaluate odds-data coverage
OddsRelay · · Updated · 5 min read
Judge odds-data coverage per product, bookmaker, sport and market, because a headline book count answers none of those. The useful question is whether the venues, sports and markets your product needs have prices now, and whether you can check that without taking the vendor's word for it.
Why does a big book count mislead?
A count says how many books are on a list. It says nothing about what each one carries. A vendor can print a large number and still fail you in three ordinary ways.
- Thin coverage: a book is on the list but carries a handful of markets, so it lifts the total while being close to useless past the match result.
- Headline markets only: football is covered, but only the 1X2 price. Over/under, both teams to score and handicaps are missing, and those are often the markets your users want.
- Listed but not current: the book is named, but nothing has been read from it for your sport today. A price nobody has read for hours looks usable and is not.
A count also rewards padding. Twenty small books nobody uses lift the number and leave the books that matter to your users exactly where they were.
Start from your own list
Write down the bookmakers, exchanges, sports and markets your product needs before you read anyone's coverage page. Then ask for the venue list by name and check your must-haves are on it.
OddsRelay covers 140+ bookmakers, 60+ of them live in the UK & Ireland, bet365 included, with lay prices from Betfair, Smarkets, Matchbook and BETDAQ. The one region served is the UK & Ireland. GET /v2/bookmakers is the named list: every bookmaker and exchange key the API serves, with its display name, its regions and whether it is an exchange. It costs no tokens, so you can diff it against your own list in a script.
Coverage is per product, not per feed
A book that is live for football on a standard back/lay board may carry no each-way racing at all. So a single yes or no for a whole feed is the wrong unit. Ask for coverage per product, per venue and per sport, and read it the same way.
Here that question has a public answer. GET /v2/coverage without a key returns, for each product, every venue and sport as live or interrupted_24h. The second means an interruption in the last 24 hours, or no rows now. It carries no counts and no per-venue times. The coverage page reads exactly this document.
{
"region": "uk",
"generated_at": "2026-09-17T02:20:29Z",
"products": {
"each-way": [
{ "bookmaker": "7bet", "sport": "horse_racing", "status": "live" },
{ "bookmaker": "bet600", "sport": "horse_racing", "status": "live" }
],
"standard": [
{ "bookmaker": "7bet", "sport": "american_football", "status": "live" },
{ "bookmaker": "7bet", "sport": "aussie_rules", "status": "interrupted_24h" }
]
}
}Filter it to your list and you have a first answer in one call. A book that is live on the product you need, for the sports you need, passes this stage. Anything else is a question to ask before you sign.
How many markets does each book carry?
Depth is the market count per book on a real fixture, not the markets a vendor claims across its whole dataset. Test it directly. GET /v2/sports costs no tokens and lists every competition on the matched boards with the market keys seen under it, so you can see whether handicaps or totals exist for your competitions at all.
With a key, go one level down. Keyed /v2/coverage adds, for each venue and sport, the number of events it has rows for now and its last_seen time. Compare a bookmaker's event count with the exchanges' on the same product and sport: a wide gap on a product you need is worth raising with the vendor. Then pull the raw board for a few of your fixtures and count the markets each bookmaker returns. Walking raw shows how to page through it.
{
"region": "uk",
"generated_at": "2026-09-17T02:20:29Z",
"products": {
"2up": {
"bookmakers": [
{ "key": "betmgm", "name": "BetMGM",
"sports": { "soccer": { "events": 5, "last_seen": "2026-09-17T02:20:18Z" } } }
],
"exchanges": [
{ "key": "betdaq", "name": "Betdaq",
"sports": { "soccer": { "events": 149, "last_seen": "2026-09-17T02:20:06Z" } } }
]
}
}
}How recent is each price?
Be wary of a speed adjective with nothing in the reply to check it against. What you want is a timestamp you can read per venue. On a matched board, meta.last_seen gives the last read of each venue and sport, so now minus that time is an upper bound on a price's age. meta.processed_at is the board's own time. On raw, each market's last_update is when that market last changed, which is not a heartbeat: a quiet market's time ages while the venue is still read.
Every product on sale meets a maximum update time of 10–20 s. Check it the plain way: take a few rows and compare them with the bookmaker's own site at the same moment. The freshness guide covers each field.
Is the lay side covered too?
For an oddsmatcher or any matched-betting tool, a back price is half the row. Coverage has to include the exchange price for the same selection and the money available at it. On OddsRelay's back/lay boards each back offer is paired against exchange lay and liquidity-gated. The rating and qualifying loss are simple arithmetic on the pair, and the oddsmatcher widget shows them. Lay and exchange coverage goes further.
Does coverage hold over time?
Coverage that is whole in one week can thin out by the next, because bookmakers change what they offer. A single demo cannot show that. What you are buying is the upkeep, so watch it over time. Read the keyless coverage document daily for a week or two and note every venue and sport on your list that goes to interrupted_24h.
Completeness inside a market needs its own check. A correct-score market missing two selections still renders and still looks fine. Pick a few deep markets on your fixtures and compare them selection by selection with the bookmaker's own page.
Where to look next
See live coverage for every venue and sport on each product, then read the coverage method for both views of the route. When you want to count markets on your own fixtures, request access.