Skip to content

BlogFundamentals

Football odds data, explained

OddsRelay · · Updated · 5 min read

Football odds data is every bookmaker's price for every outcome of a fixture, filed under a sport key, a market key and an outcome name. In the OddsRelay feed, football sits under soccer_* sport keys, and the matched boards set each back price beside the exchange lay for the same outcome.

What are the main football betting markets?

A single fixture carries dozens of markets, and they differ in shape. Some have two outcomes, some three, some one per scoreline. The common ones:

  • Match result (h2h): three outcomes, the home side, Draw and the away side.
  • Over/under goals (totals): an over and an under on a line, with the line itself in the outcome's point field. One venue often prices several lines on the same fixture, so the line is part of the outcome's identity.
  • Both teams to score: two outcomes, yes and no.
  • Correct score (correct_score): one outcome per scoreline, so it is the widest of the common markets.
  • The long tail: draw no bet, double chance, half-time/full-time and the Asian handicap lines.

Don't hardcode that list. Every row of GET /v2/sports carries markets, the market keys seen under that competition on the matched boards, and the markets filter takes the same keys. Name a key the catalogue doesn't know and the reply is a free 400 unknown_market with the valid keys listed.

Every competition has its own sport key

The Premier League is soccer_epl. Each other competition gets its own key under the same soccer prefix, with the readable name in sport_title. The sports filter takes a full key or a prefix of one, so sports=soccer asks for every football competition on the board and sports=soccer_epl asks for one. The matched-board filters guide covers the rest of the grammar.

One place uses the prefix instead of the full key. meta.last_seen, the time each venue's prices were last read, is keyed by the sport's key base, so every football competition shares the soccer entry. The freshness guide shows the lookup.

Where football sits on the boards

ProductWhat it carries for football
standardBookmaker back prices beside exchange lay prices, market by market.
2upEach bookmaker's own 2Up price on the match result, paired to the exchange lay for the same team.
dutchingBack prices only, one leg per outcome at different venues, grouped by dutch_id.
rawEach venue's markets and outcomes as that venue labels them, with a last_update per market.

All six matched boards and raw are on every plan, so one key reads all four. The 2Up board is the one built for football alone: its back side is the bookmaker's 2Up price, which can differ from the same bookmaker's ordinary match odds. The dutching walkthrough covers that board.

What a matched football row looks like

Here is one Premier League fixture on the standard board, trimmed to the match result:

Example · GET /v2/odds/standard?sports=soccer_epl&markets=h2h (trimmed)

{
  "meta": {
    "feed_type": "standard",
    "region": "uk",
    "odds_format": "decimal",
    "processed_at": "2026-09-20T12:20:57.271Z",
    "last_seen": {
      "bet365": { "soccer": "2026-09-20T12:20:51Z" },
      "william_hill": { "soccer": "2026-09-20T12:20:55Z" },
      "betfair_exchange": { "soccer": "2026-09-20T12:20:56Z" },
      "smarkets": { "soccer": "2026-09-20T12:20:54Z" }
    },
    "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": "bet365", "price": 2.9, "link": null },
            { "bookmaker": "william_hill", "price": 2.8, "link": null }
          ],
          "lay": [
            { "exchange": "betfair_exchange", "price": 3.0, "available": 175, "link": null }
          ]
        },
        {
          "name": "Draw",
          "back": [{ "bookmaker": "william_hill", "price": 3.5, "link": null }],
          "lay": [{ "exchange": "smarkets", "price": 3.6, "available": 42, "link": null }]
        }
      ]
    }]
  }]
}

Each outcome carries back offers, best price first, and lay offers, lowest first. A lay offer's available is the money on offer at that price. Matched offers carry no timestamp of their own. Now minus the venue's meta.last_seen entry is an upper bound on a price's age, and processed_at is the board's time.

The row 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. In your own code it is a few lines, at your own commission rate:

Example · your arithmetic on the Arsenal pair above

const back = 2.9, lay = 3.0, commission = 0.02, stake = 10;

const layStake = (back * stake) / (lay - commission);          // 9.73
const ifBackWins = stake * (back - 1) - layStake * (lay - 1);  // -0.46
const ifLayWins = layStake * (1 - commission) - stake;         // -0.46, the qualifying loss
const rating = (back / lay) * 100;                             // 96.7

The ratings explainer walks the formulas, including free-bet stakes.

Pairing is the hard part of football data

Prices are only half of a football feed. The other half is deciding that two venues are quoting the same fixture and the same outcome, when bookmakers spell teams their own way. One venue lists a club by its short name, another by its full name, and a third adds a suffix, on every fixture of every round. A football feed for matched betting should do that reconciliation once, for everyone, because every customer who does it alone rebuilds the same alias tables.

On the matched boards one fixture is one event with one event_id on every route. Treat that id as opaque. It holds within the feed's own mapping, but it can change, so don't store it as a permanent key. Raw keeps each venue's own market and outcome labels, which is the right trade when you want to run the matching yourself. The lay side matters as much as the pairing, since a lay with little money behind it cannot hedge a real stake. Why lay liquidity matters covers that part.

Which football the feed covers

The feed serves one region, the UK & Ireland: 140+ bookmakers, 60+ of them live in the UK & Ireland, bet365 included, with the lay side from Betfair, Smarkets, Matchbook and BETDAQ. GET /v2/sports lists every football competition on the boards now, and keyless GET /v2/coverage gives the live status per product, venue and sport.

The prices are pre-match. There is no in-play product, so a live-betting app needs a second source for the minutes after kick-off.

Price one competition first

Pick one competition key and one market, and add quote=true to the standard board call to see its token price before you spend any. The quickstart walks that call. See live coverage for what is on the boards today, or request access for a key.