Feed liveChannel BlogMarkets Back / Lay
Transport REST / WebSocketPush 100–500 msV1
Guides

Betfair Odds vs Pinnacle Odds: What Each Price Means

Betfair odds vs Pinnacle odds: an exchange price is a funded order with size behind it, a bookmaker price is a quote with margin. How to compare them correctly.

A Betfair Exchange price is a standing order from another bettor. A Pinnacle price is a quote from a bookmaker. Same event, same outcome, two completely different objects — and treating them as interchangeable numbers in a spreadsheet is the most common modelling error I run into when people show me their pipelines.

The short definition

Every price on the exchange is collateralised. Someone has put money behind it and it fills until that money is gone.

  • A back price is the best odds another user is willing to lay you. Back Team A at 2.10 and somebody has already posted funds at 2.10 taking the other side.
  • A lay price is the best odds someone is willing to back at. Laying makes you the bookmaker for that selection: you take their stake, you pay if it wins.
  • Behind each price sits a size — how much is available at that rung of the ladder. Ask for more than the size and you walk up the ladder at worse odds.

Betfair charges commission on net market winnings, so what you see is a gross price. Your realised return is lower, always.

Pinnacle does something structurally different. It publishes a two-sided quote with margin baked in — no queue, no size, no ladder. It posts a number, accepts a stake up to an internal limit that depends on the market and on you, and moves the number when flow or its model says to. The margin is the amount by which the implied probabilities of both sides sum above 100%.

So the honest answer to "why do Betfair odds differ from Pinnacle odds" is that they are not measuring the same thing. One is a clearing price where supply met demand a moment ago. The other is a market maker's opinion plus a commercial buffer.

Exchange odds vs sharp bookmaker odds, mechanically

Say Pinnacle shows 1.95 / 1.95 on a two-way market. Roughly a 2.6% margin; normalise it and the fair price on each side is about 2.00.

The exchange ladder for the same outcome might look like this:

Selection: Team A
  back  2.02   £4,180
  back  2.00   £11,900
  lay   2.04   £6,350
  lay   2.06   £2,100

Best back 2.02, best lay 2.04, mid around 2.03. That mid is the market's unvarnished read — no vig, just a bid-ask spread set by whoever is competing for queue position.

Two consequences fall straight out of that structure.

The exchange carries no built-in margin. The spread is your cost, and on a liquid market it is tight. On a Sunday afternoon third-tier fixture it is not tight, and the mid is close to meaningless.

The exchange price also carries commission drag. Back at 2.02 with 5% commission on a winning market and you net about 1.97 in effective terms. If you compare no-vig Pinnacle against gross exchange prices, your comparison is broken before it starts.

Betfair lay price meaning, precisely

The lay price is the ask — the number at which the market will sell you the outcome. Lay at 2.04 and you accept someone's £X stake while risking £X × 1.04 of your own.

Here is the mistake I see most: people grab the best lay price, call it "the odds", and compare it directly to a bookmaker's back price. Every bookmaker then looks generous, because you have compared their bid to the exchange's ask. If you need one number to represent the exchange's view, use a size-weighted mid between best back and best lay — and throw it away when the sizes are trivial.

Why the two prices disagree

Liquidity does most of the work. Premier League match odds, top-tier ATP, NBA sides — these converge closely. Thin markets diverge wildly, and when they diverge the exchange is usually the one that's wrong. A 1.90/2.30 spread with £40 behind it is not information.

Timing, second. Both prices react to news but through different machinery: Pinnacle moves when its traders or models move it; the exchange moves when somebody hits the queue. In-play, the exchange can jump a tick ahead of a bookmaker or trail it, depending entirely on who's watching.

Commission and vig, again, because it keeps getting skipped. Gross versus gross tells you nothing.

Different populations. Pinnacle's number reflects sharp flow it has chosen to accept. The exchange number reflects everyone with an account and an opinion — arb bots, hedgers unwinding, someone dumping a green-up position at the worst possible moment. Late exchange steam is not automatically informed money.

Why this matters if you build models

Most quantitative bettors use market prices as a probability estimate. For that job the exchange hands you something a bookmaker feed structurally cannot: the size behind the price.

A price on its own is a claim. A price with £11,900 queued behind it is a claim someone has funded. That is what turns exchange data into a confidence-weighted signal rather than a single scalar:

  • Weight closing-line comparisons by available size, not just by price.
  • 1.98 with £200 behind it is noise. 1.98 with £30,000 behind it is a prior worth respecting.
  • Watch for lopsided books — when lay size dwarfs back size, somebody is trying to unload risk, and that asymmetry is a feature you can model.

None of that exists in a published bookmaker number. Which is why I'll argue the exchange is the better raw input for calibrating a model, while a bookmaker quote is often the better input for the separate question of what you can actually get filled at. Those are two different jobs and it's fine for them to use different data.

The honest caveats

Where the exchange is the weaker instrument, plainly.

Liquidity is wildly uneven. Outside top-flight football, major tennis and the big US leagues, exchange markets can be near-empty. Pinnacle will quote a price on fixtures where Betfair has £80 in the book. If your model needs coverage across thousands of obscure matches, an exchange feed will disappoint you and no API can fix that — the money simply isn't there.

Commission changes the answer. Depending on your account, commission materially erodes apparent edge. Any "the exchange is 3% better" claim that ignores it is arithmetic done wrong.

In-play prices can be stale in the way that hurts. Markets suspend around goals and reopen. A price that looks live may be a pre-suspension leftover. Every response from the Betfair Odds API carries meta.stale and meta.age_ms for exactly this reason, with thresholds of 15 seconds live and 120 seconds prematch. Check the flag before you act on the number.

We sell one side of this comparison. Betfair Odds API serves Betfair Exchange prices — back, lay, sizes, live and prematch. We do not sell Pinnacle data and we do not sell aggregated multi-book feeds. If your workflow needs the bookmaker leg, source it separately. Better you hear that now than after a subscription.

Doing the comparison in code

The snapshot endpoint is /betfair/v1/livemap. ?feed= selects live or prematch and defaults to live when omitted; &sports= filters by sport name, case-insensitive.

import requests

HEADERS = {"x-api-key": "YOUR_KEY"}
COMMISSION = 0.05

r = requests.get(
    "https://betfair-odds.com/betfair/v1/livemap",
    params={"feed": "live", "sports": "soccer"},
    headers=HEADERS,
    timeout=10,
)
payload = r.json()
meta = payload["meta"]  # feed, receivedAt, seq, stale, age_ms, event_count

if meta["stale"] or meta["age_ms"] > 15_000:
    raise RuntimeError(f"stale snapshot: age_ms={meta['age_ms']}")

def effective_back(price, commission=COMMISSION):
    """Net-of-commission decimal odds for a back bet."""
    return 1.0 + (price - 1.0) * (1.0 - commission)

def no_vig_two_way(a, b):
    """Normalise a bookmaker's two-way quote to fair odds."""
    ia, ib = 1.0 / a, 1.0 / b
    total = ia + ib
    return 1.0 / (ia / total), 1.0 / (ib / total)

def weighted_mid(back_px, back_sz, lay_px, lay_sz):
    if back_sz + lay_sz == 0:
        return None
    return (back_px * lay_sz + lay_px * back_sz) / (back_sz + lay_sz)

Run the ladder above through it. weighted_mid(2.02, 4180, 2.04, 6350) returns about 2.028 — pulled toward the back side because the lay queue is heavier, and heavier resting money on the lay side is pressure to sell. Then effective_back(2.02) gives 1.969, while no_vig_two_way(1.95, 1.95) gives 2.00 flat. Compare 1.969 against 2.00 and the bookmaker wins that particular line, which is the opposite of the conclusion you'd reach comparing 2.02 to 1.95 naively.

Note the weighting direction, because it trips people up: each side is weighted by the opposite side's size. And gate everything on meta.stale first. A fast wrong number costs more than a slow right one.

Anything that needs sub-poll reaction — in-play, where the book turns over on every attack — should not be polling. REST leaves you behind by up to your polling interval by construction. The push feed at /betfair/v1/stream sends updates as they land:

{"action":"authenticate","apiKey":"YOUR_KEY"}
{"action":"subscribe","feeds":["live"]}
{"action":"pong"}

Authenticate within 10 seconds or the socket closes, subscribe, and answer pings with pong. Snapshots arrive chunked at 512 KB. Every plan permits one concurrent connection per key, so fan out to your own workers from a single socket instead of opening several — the second connection is the mistake, not the first. The WebSocket ships with Pro + WS and Scale; plain Pro is REST only unless you take the add-on.

One transport-level gotcha worth writing into your error handler now: REST error bodies use the field error, WebSocket error frames use code. Same failure, different shape, depending on how you asked. The schemas are in the docs.

Takeaway

Never compare a raw exchange price to a raw bookmaker price. Strip the vig from the bookmaker quote, strip commission from the exchange price, and only then measure the gap — weighted by the money actually sitting behind that exchange price, because a price with nothing behind it is a hope, not a quote. Do that consistently and betfair odds vs pinnacle odds stops being an argument about which source is sharper. It becomes two independent estimates of the same probability, each with a known bias you can correct for.

Frequently asked questions

Why do Betfair odds differ from Pinnacle odds?

Because they are different objects: a Betfair price is a funded order from another bettor with a size behind it, while a Pinnacle price is a bookmaker quote with margin built in. Liquidity, timing of updates, commission versus vig, and the mix of who is betting all push the two numbers apart.

What does the lay price mean on Betfair?

The lay price is the ask — the odds at which someone is willing to back, so laying means you take their stake and pay out if the selection wins. Comparing a lay price directly to a bookmaker's back price is an apples-to-oranges comparison that makes bookmakers look better than they are.

Are Betfair Exchange odds better than bookmaker odds?

On liquid markets, usually yes after you account for commission, because the exchange has no built-in margin and the spread is the only cost. On thin markets with little money in the book, the exchange price can be meaningless while a bookmaker will still quote something usable.

Does the Betfair Odds API provide Pinnacle odds too?

No. Betfair Odds API serves Betfair Exchange prices only — back and lay with the sizes behind them, live and prematch. If you need bookmaker prices for comparison, you will need a separate source for that leg.

How do I know if a Betfair odds snapshot is out of date?

Every response carries a meta object with stale and age_ms fields. Treat live data older than 15 seconds and prematch data older than 120 seconds as suspect, and check meta.stale before computing anything from the prices.

Get real-time Pinnacle odds in your code

Live & prematch markets with instant odds-drop alerts over SSE and WebSocket. Free trial key in seconds — no card.

Start free trial