BlogOdds API basics

How to get bookmaker odds data into your app

How to get bookmaker odds data into your app comes down to two routes: collect the prices yourself, or license a feed and call it over HTTP.

Unless collecting odds is the product you sell, license the feed.

Decide these first

Settle four things first.

  • Which bookmakers. List the books your users expect to see, and check each one against a supplier's coverage page before anything else.
  • Which region. Bookmakers publish different prices, and sometimes different markets, per country. OddsRelay serves the UK & Ireland. If your product is built for bettors elsewhere, this feed is the wrong fit.
  • Raw or matched. Raw is each bookmaker's price on its own, which suits comparison tables and content. Matched pairs each bookmaker price with an exchange lay price for the same outcome, which is what an oddsmatcher or a matched-betting tool needs.
  • Pre-match or in-play. The OddsRelay feed serves pre-match prices by default and, since 2 November 2026, in-play prices with inPlay on raw and on the standard and dutching boards. Those are polled like the rest, with no scores or match clock, and bet365 and William Hill carry none. Live vs pre-match odds data sets out the difference.

If these terms are new, what an odds API is sets the baseline. The anatomy of an odds API response walks a real reply field by field.

A first call to a feed

Four steps, all plain HTTP: get a key, make one authenticated GET, parse the JSON, then cache it. With OddsRelay the key goes in an Authorization: Bearer header (or x-api-key), and each matched board has its own path under /v2/odds/.

A first call · example

curl --compressed -H "Authorization: Bearer $ODDSRELAY_KEY" \
  "https://api.oddsrelay.io/v2/odds/standard?region=uk&sports=soccer"

Keep --compressed on: it asks for gzip, and without it the reply is a much larger plain body. Add quote=true to any data request and it returns the call's price in tokens instead of the data, for free. The filters and tokens guide explains how a live-feed price comes from the board and filters you ask for, never from the size of the reply.

The reply is an envelope. meta describes the board as a whole, and data holds events, each with its markets and outcomes. On the standard board, every outcome carries back offers, the bookmakers' prices, and lay offers, the exchanges' prices with available, the money on offer at that price. One event, trimmed to one outcome:

Standard board, one event · example

{
  "meta": {
    "feed_type": "standard", "region": "uk",
    "odds_format": "decimal",
    "processed_at": "2026-09-17T02:20:57.271Z",
    "last_seen": { "william_hill": { "soccer": "2026-09-17T02:20:55Z" } },
    "count": 26,
    "version": "v2",
    "next_cursor": null
  },
  "data": [{
    "event_id": "or_evt_917dd44bce05",
    "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": "smarkets", "price": 3.0, "available": 175, "link": null }]
      }]
    }]
  }]
}

Each back price is paired with exchange lay from Betfair, Smarkets and Matchbook, and only where that lay has money behind it. The response carries prices only, and anything computed from them is yours. The API reference documents each field.

Cache with ETags and poll

The feed is pull-only: your app asks, the feed answers. Every data reply carries an ETag. Send it back as If-None-Match on the next call, and an unchanged board comes back as a 304 with no body, which costs no tokens.

  1. Make the first call. Store the body and its ETag.
  2. On each later call, send If-None-Match with that value. A 304 means the copy you hold is still the current board.
  3. On a 200, replace your copy and store the new ETag.

Judge freshness from the timestamps in the reply, never from when you fetched it. meta.processed_at is the board's time. meta.last_seen is when each venue and sport was last read, so now minus that time is an upper bound on a price's age. Show it to your users, or act on it, rather than assuming. The freshness guide and the conditional requests guide cover both in detail.

When to collect the data yourself

Build it when the data is your product, or when you need books or markets no supplier carries.

Reading a price once is the small part of the job. The lasting cost is keeping every bookmaker working as each one changes, then naming the same event the same way across books so their prices line up. A matched product adds a second system on top: pairing each back price with an exchange lay price and deciding when there is enough money behind the lay to show it.

A licensed feed moves that upkeep to the supplier. OddsRelay covers 140+ bookmakers, 60+ of them live in the UK & Ireland, bet365 included on every plan. Whichever supplier you pick, check the coverage before you commit: the coverage page lists every venue and the sports it carries on each feed. We work the costs through in buy versus build.

Make your first call

A key and the quickstart get you to a first priced call.

If your app shows those prices to other people, it runs on Enterprise, and a Free key of your own is enough to try it first.

Related posts

18+ · OddsRelay supplies odds data only and takes no bets. Please gamble responsibly.