Fundamentals
How bookmaker odds data is structured
Odds data is a four-level hierarchy: event to market to selection to price, plus bookmaker, region and freshness metadata. Once the shape clicks, integrating a feed is straightforward.
· 5 min read
Decimal, fractional and American are three ways to write the same price. For anything you compute with, standardise on decimal, store decimal, and convert only at the point of display.
Standardise on decimal. Odds come in three formats: decimal (2.10), fractional (11/10) and American (+110). They describe the same price in different notations, but only one is comfortable to compute with. Decimal is unambiguous, maps directly to implied probability, and is what most odds feeds return. Store decimal everywhere, do your maths in decimal, and convert to fractional or American only at the point of display.
The three formats are decimal, fractional and American, and each answers the same question in a different way. Decimal states the total return per unit staked, stake included. Fractional states profit relative to stake. American states how much you win on a fixed stake, or how much you must stake to win a fixed amount. A UK bookmaker page might show 11/10; the same selection in a data feed is almost always 2.10.
| Decimal | Fractional | American | Implied probability |
|---|---|---|---|
1.50 | 1/2 | -200 | 66.7% |
2.00 | 1/1 (evens) | +100 | 50.0% |
2.10 | 11/10 | +110 | 47.6% |
3.50 | 5/2 | +250 | 28.6% |
5.00 | 4/1 | +400 | 20.0% |
Reading across a row makes the point: fractional and American are display conventions, while decimal is the number you would actually calculate with. That is why a data model should treat decimal as the source of truth and the others as derived views.
Decimal wins because it is a single positive number with no branching rules. Fractional odds are a pair of integers you must parse, reduce and interpret, and evens is written as a word. American odds flip sign around the even-money line: a positive value means one calculation, a negative value means another. Both formats force conditional logic into code that should just be arithmetic.
Converting into decimal removes all of that. Fractional a/b becomes (a / b) + 1. American +p becomes (p / 100) + 1, and American -p becomes (100 / p) + 1. Once every price is decimal, comparing two books is a plain numeric comparison, and combining prices across selections is multiplication rather than a special case. A feed that hands you decimal has already absorbed that parsing burden for every book it covers.
const toDecimal = {
fractional: (a, b) => a / b + 1, // 11/10 -> 2.10
american: (n) => n > 0
? n / 100 + 1 // +110 -> 2.10
: 100 / -n + 1, // -200 -> 1.50
};
// Implied probability falls straight out of the decimal price:
const impliedProb = (decimal) => 1 / decimal; // 2.10 -> 0.476Implied probability is 1 divided by the decimal price. A price of 2.00 implies 50%, 4.00 implies 25%, 1.50 implies about 66.7%. This one line is why decimal is worth standardising on: the format you store is a division away from the probability every downstream calculation needs. There is no equivalent one-liner from fractional or American without converting to decimal first.
That probability is the foundation of value and arbitrage maths. Add the implied probabilities across every outcome of a market and you get the book's overround, the margin baked into its prices. Compare a bookmaker's implied probability against an exchange lay price for the same selection and you can see whether a matched bet or a sure bet exists. None of this is convenient unless every price is already decimal, which is exactly why the calculation belongs on stored decimal, not on a format you reformat for humans.
A feed should return one format, in decimal, across every book, so you never write per-bookmaker parsing. If one source hands you 11/10 and another +110 and a third 2.10, format-handling leaks into every consumer of the data. Consistency at the feed boundary means your matcher, your scanner and your dashboard all read the same numeric field the same way, whether the price came from bet365 or a smaller book.
This matters most when the feed is already matched. OddsRelay returns 60+ UK books, bet365 included, with each back price paired against a lay price from one of three exchanges (Betfair, Smarkets, Matchbook), and every value is decimal. A single matched row looks like this (illustrative shape, not live data):
{
"event": "Arsenal vs Chelsea",
"market": "match_odds",
"selection": "Arsenal",
"back": { "bookmaker": "bet365", "odds": 2.10 },
"lay": { "exchange": "betfair", "odds": 2.14, "liquidity": 1840 },
"rating": 98.1,
"qualifying_loss": -0.12
// ... region, feed_type and freshness fields elided
}Because back.odds and lay.odds are both decimal, the rating and qualifying_loss fields can be computed directly, and your code never guesses whether a value is a fraction or a signed integer. That uniformity is a small thing per row and a large thing across a market of thousands of selections. For how these fields sit inside the full payload, see the anatomy of a response, and for the wider model, how odds data is structured.
Standardise on decimal, store decimal, and convert to fractional or American only for display. Decimal computes cleanly, gives you implied probability in one division, and underpins the value and arbitrage maths that everything else depends on. A feed that returns decimal consistently across every book saves you the parsing tax on data you will read millions of times. The full field list is in the API docs, and you can put a real decimal feed to work with a free trial. It powers a leading UK matched-betting platform today.
Written by
Founder, OddsRelay
James is the founder of OddsRelay — the odds-data feed behind matched betting, arbitrage and odds-comparison products: 60+ UK bookmakers with bet365 included, matched against exchange lay prices and delivered as one clean, documented API. He writes here about how that data layer actually behaves — coverage, matching, freshness and the trade-offs — from the side that builds and runs it. The same feed powers a leading UK matched-betting platform today.
Part of the Fundamentals cluster
What is an odds API? A 2026 guide for builders18+ · Data product for licensed operators. Please gamble responsibly.
Fundamentals
Odds data is a four-level hierarchy: event to market to selection to price, plus bookmaker, region and freshness metadata. Once the shape clicks, integrating a feed is straightforward.
· 5 min read
Fundamentals
What every field in a good odds API response is for, walked one at a time: the event/market/selection keys, the back and lay blocks, rating and qualifying_loss, and the envelope around them.
· 6 min read
Exchange & lay data
Backing bets for an outcome; laying bets against it, and only an exchange lets you take that side. Here is the plain version, plus the back/lay data pair a matched feed hands you ready to use.
· 5 min read