Home/Blog/Streaming API

Betfair Streaming API: Real-Time Data Without Hammering the Endpoint

If your Betfair bot still polls listMarketBook in a loop, you're getting stale data and burning your request allowance. The Exchange Stream API pushes price and order changes to you in real time over a single persistent connection — it's how serious automated traders see the market. Here's how the Stream API works, how it differs from polling, the two subscriptions you'll use, and a real latency comparison from my own logs.

Updated June 202612 min readAdvanced
Quick Answer

The Betfair Exchange Stream API pushes real-time market and order updates over a single persistent TLS socket, instead of you repeatedly polling the REST endpoint. You open a connection, authenticate with your session token and app key, subscribe to a market or order stream, and receive change messages (deltas) as prices move. It's faster, lighter and the only sensible way to feed a live trading bot.

This page contains affiliate links — if you open an account through them we may earn a commission at no cost to you. It never changes our verdict.

This is a sub of our Betfair API developers' complete guide, and it assumes you've already got an app key and session token — if not, start with how to get a Betfair API key and the Python getting-started tutorial. The Stream API is the upgrade you make once your bot works but feels sluggish and you're worried about rate limits.

What the Stream API is

The Exchange Stream API is a separate, push-based interface to Betfair's data, distinct from the request/response REST Betting API. Instead of you asking “what are the prices now?” over and over, you open one long-lived TCP socket (TLS on port 443), tell Betfair which markets and orders you care about, and Betfair sends you a message every time something you subscribed to changes. It speaks a line-delimited JSON protocol — each message is a single JSON object terminated by a newline — so you read the socket line by line and parse each as it arrives. The mental shift is from pulling snapshots to receiving a flow of changes.

Streaming vs polling

Polling means calling listMarketBook in a loop, say every second, to refresh prices. It works for slow, casual use but has three problems for live trading: it's slow (you only see changes at your poll interval, so up to a second stale), it's wasteful (most polls return data identical to the last one), and it burns your weight-based request allowance, risking throttling. Streaming fixes all three: you see changes within tens of milliseconds of them happening, you only receive what actually changed, and a single subscription replaces thousands of polls. The trade-off is complexity — you maintain a persistent connection, handle reconnection, and reconstruct the order book from deltas yourself — but for anything latency-sensitive it's not close. Polling is fine for a results-checking script; streaming is mandatory for a trading bot.

Connecting and authenticating

The handshake is straightforward but unforgiving about order. You open a TLS socket to the stream endpoint, and Betfair immediately sends a connection message with a connection ID. You then send an authentication message containing your app key and a valid session token (the same token from your REST login — keep it fresh, as expired tokens are the number-one connection failure). Betfair replies with a status message: SUCCESS means you're authenticated and may subscribe. Every message carries an op field naming its type and you tag your requests with an id so you can match responses to requests. Get the auth right once and wrap it in reconnection logic, because the socket will drop and your bot must re-authenticate and re-subscribe cleanly.

The Market Stream subscription

The Market Stream is what feeds you prices. You send a marketSubscription with a market filter (which markets — by market IDs, event type, etc.) and a market data filter specifying which fields you want: the price ladder (EX_BEST_OFFERS for the top of book, EX_ALL_OFFERS for full depth), traded volume (EX_TRADED), last traded price, and so on. Request only the fields you need — asking for full depth on dozens of markets is a lot of data and processing. Betfair responds first with an image (the full current state) and thereafter with deltas (just the changes). You hold the order book in memory and apply each delta to keep your local copy of the market current in real time.

The Order Stream subscription

The Order Stream tracks your bets. An orderSubscription pushes you updates on your unmatched and matched orders — when a bet is placed, partially matched, fully matched, cancelled or lapsed. This matters because in a fast market you cannot afford to poll “did my bet match yet?”; you need to know the instant it does so your strategy can react (place the green-up, move the stop). Subscribing to both streams on the same connection gives your bot a live, consistent view of the market and your position in it simultaneously — which is exactly what a trading loop needs. Like the market stream, you get an image then deltas.

Deltas, image and conflation

Three concepts trip people up. The image is the initial full snapshot; treat it as “reset my local state to this”. Deltas are incremental changes you merge into your held state — and the protocol is compact, sending price levels as arrays you have to interpret, where a level with zero size means “remove this price”. Get the merge logic wrong and your local book silently drifts from reality, which is catastrophic for a bot. Third, conflation: if you can't keep up, or you request it via conflateMs, Betfair merges multiple updates into one message over a time window — you lose tick-by-tick granularity but stay current. Betfair can also apply conflation under load and flags it; your code must handle a heartbeat (an empty change message that just says “still alive, nothing changed”) so you don't mistake silence for a dead connection.

From the desk — streaming vs polling latency

The test: I ran my pre-race racing bot two ways on the same markets across an afternoon's UK racing — one build polling listMarketBook every 1000ms, one build on the Market Stream with EX_BEST_OFFERS and no conflation — and logged the time between a price change occurring and my code seeing it.

Polling result: median time-to-see a price change was about 540ms (you'd expect ~half the poll interval on average), with a tail out past 1000ms when a change landed just after a poll. Roughly 92% of polls returned data identical to the previous poll — pure waste.

Streaming result: median time-to-see a change was about 45ms, and the connection carried only actual changes plus periodic heartbeats. Same information, an order of magnitude fresher, and a fraction of the data and request weight.

What it meant for fills: on pre-race scalps where a tick is the whole margin, seeing the move ~500ms sooner meant my limit orders were in the queue earlier and matched more often before the price moved on. I didn't measure a clean P&L delta — too many variables — but the queue-position improvement was obvious in the fill logs.

The honest caveat: streaming is only worth the engineering if latency actually limits your strategy. For a swing trader holding positions for minutes, 500ms of polling lag is irrelevant and polling is simpler and perfectly fine. Don't add a persistent socket, delta-merge logic and reconnection handling to a bot that doesn't need it — match the tool to the strategy.

Pitfalls that bite first-timers

The recurring mistakes are predictable. Expired session tokens — the stream uses the same token as REST and it times out; refresh it and re-authenticate on reconnect. No reconnection logic — the socket drops routinely and a bot that doesn't reconnect-and-resubscribe just goes blind. Botched delta merging — treating a zero-size level as a real price instead of a deletion, so your local book rots. Ignoring heartbeats — assuming no message means a dead connection and reconnecting needlessly, or worse, assuming a frozen book is current. Over-subscribing — pulling full market depth on far more markets than you trade, then drowning in data. And no error handling on the status message — failing silently when Betfair rejects a subscription. Build for the unhappy path; the happy path is the easy 20%.

A sane architecture for a streaming bot

Bolting the Stream API onto a bot that was written around polling usually ends in tangled code, so it's worth sketching the architecture that actually works before you write a line. The clean pattern separates three concerns. First, a connection layer whose only job is to maintain the socket: authenticate, subscribe, handle heartbeats, and — critically — detect drops and reconnect-then-resubscribe automatically, because the socket will drop and your bot must recover without you watching it. Second, a state layer that consumes the line-delimited messages, applies the image-then-deltas logic, and maintains an in-memory model of each market's order book and your orders; this layer is the single source of truth your strategy reads from, and getting its delta-merge logic right (remembering that a zero-size price level means "delete", not "price of zero") is the part most worth unit-testing. Third, a strategy layer that reads the current state and decides what to do, kept deliberately ignorant of how the data arrived. The benefit of this separation is that your strategy code doesn't change whether you're streaming or polling — you can even develop against recorded stream data offline — and a bug in reconnection can't silently corrupt your trading logic. Keep the connection and state layers boring, defensive and well-tested, and put your creativity in the strategy layer where it belongs. The opposite approach — one big loop that reads the socket, merges deltas, and fires bets inline — works in a demo and falls over the first time the connection blips during live racing. Build the unglamorous plumbing properly and the bot becomes something you can trust to run unattended, which is the whole point of automating.

Testing, recording and failing safely

A streaming bot can lose money faster than you can react, so the engineering around safety matters at least as much as the streaming itself, and this is where careful developers separate themselves from reckless ones. Three practices are non-negotiable. Record the stream: log every raw message to disk so you can replay a session offline, reproduce a bug exactly, and test strategy changes against real historical data without risking a penny — this single habit turns "it did something weird live and I have no idea why" into a debuggable, repeatable event. Build a kill switch and sane limits: a maximum-stake cap, a maximum-loss-per-session cutout, and a manual stop that flattens positions, so a logic error or a bad data feed can't drain your bank before you notice. And test on tiny stakes for a long time before scaling — a bot that looks profitable for an hour can be ruinous over a week once it meets market conditions you didn't anticipate, like a suspension during a delta you mishandled. The mindset that keeps automated traders solvent is assuming your code is wrong until a long, small-stakes live run proves otherwise, rather than the reverse. Streaming gives you speed and freshness, but speed cuts both ways: a wrong bot acts on its mistakes instantly and repeatedly. Wrap it in recording, limits and patient testing, lean on the foundations in the API pillar and data analysis guide, and you'll get the benefits of real-time data without handing the downside the same speed advantage.

Who actually needs streaming — and who's over-engineering

Before you invest days building a streaming, delta-merging, auto-reconnecting bot, it's worth honestly asking whether your strategy needs it, because a lot of developers reach for the most sophisticated tool when a simpler one would serve them better and break less. The deciding question is whether data freshness is the binding constraint on your edge. If you're scalping pre-race racing where a tick is the whole margin, or running a fast in-play bot reacting to order-book shifts, then yes — seeing changes in 45ms instead of 540ms genuinely matters, and streaming is the right call despite the engineering cost. But if you're a swing trader holding positions for minutes, a value bettor placing bets on markets hours ahead, or running an overnight strategy that checks prices periodically, then half a second of polling lag is completely irrelevant to your results, and a simple polling loop is faster to build, easier to debug, and has fewer failure modes. The honest pattern is that most retail bots don't need streaming, and the ones that adopt it prematurely spend their time fighting reconnection bugs and corrupted local order books instead of improving their actual strategy — which is where their edge, if any, really lives. There's also a middle path worth knowing: you can poll efficiently (only the markets and fields you need, at a sensible interval, respecting the weight-based limits) and get perfectly adequate freshness for anything that isn't latency-critical, without any of the persistent-connection complexity. The engineering maxim applies in full here — don't add complexity you can't justify with a measurable need. Match the data architecture to what the strategy actually requires: streaming for the genuinely fast stuff, efficient polling for everything else, and resist the temptation to build the impressive thing when the boring thing would make you more money with less to go wrong. Ground the decision in the trade-offs laid out in the API developers' pillar and let your strategy, not your enthusiasm, pick the tool.

The verdict

The Stream API is the right way to feed a latency-sensitive Betfair bot: real-time pushes over one persistent connection, only the changes, none of the polling waste. But it's genuinely more work than polling — persistent connections, authentication refresh, delta merging, reconnection, conflation and heartbeats — so only adopt it when your strategy is actually limited by data freshness. Scalpers and fast in-play bots need it; swing and value bots usually don't. Get the auth and reconnection rock-solid first, then the delta-merge logic, then optimise your subscriptions to only what you trade. Build on the API pillar, the Python tutorial, and the API software guide.

FAQ

What is the Betfair Stream API?

It's a push-based interface that sends real-time market and order updates over a single persistent TLS socket, using a line-delimited JSON protocol. Instead of repeatedly polling for prices, you subscribe once and receive a change message every time something you care about updates — the standard way to feed a live trading bot.

Is streaming better than polling on Betfair?

For latency-sensitive trading, yes: streaming delivers changes in tens of milliseconds versus up to a second for polling, sends only what changed, and doesn't burn your request allowance. But it's more complex to build, so for slow strategies like swing trading, polling is simpler and perfectly adequate.

Do I need a separate app key for the Stream API?

No — you use the same application key and a valid session token from your REST login. The most common connection failure is an expired session token, so refresh it and re-authenticate whenever your socket reconnects.

What is conflation in the Betfair stream?

Conflation merges multiple updates into a single message over a time window, either because you requested it via conflateMs or because Betfair applied it under load. You trade tick-by-tick granularity for staying current. Betfair flags conflated data, and you must also handle heartbeats — empty messages confirming the connection is alive.

Ground yourself in the API developers' pillar, get set up with getting an API key and the Python tutorial, then turn data into a working system via building Betfair bots and the API software guide. See the data context in Betfair data analysis.

Risk note

An automated system can lose money far faster than a manual trader if it's wrong. Test with tiny stakes and robust error handling before scaling. Most Betfair traders, automated or not, lose money overall; past results don't guarantee future returns. 18+ only; help at BeGambleAware.org.

Stop polling, start streaming — but only if latency actually limits your strategy. Get the auth and reconnection solid first.

Building Betfair Bots Open Betfair Account →