To use the Betfair API you need three things: a funded Betfair account, an app key from developer.betfair.com (a delayed key for learning, a live key for live prices), and, for a bot that runs unattended, a self-signed SSL certificate uploaded to your account. You then call the Exchange API to list markets and place or cancel bets, and the Stream API for pushed price updates. In Python, the betfairlightweight library handles login and requests. The steps below go from app key to a basic bot template.
- What the Betfair API does
- Two APIs: REST and Stream
- Prerequisites
- Step 1 — Create the app key
- Step 2 — Generate the SSL certificate (non-interactive login)
- Step 3 — Install client libraries
- Step 4 — First authenticated request
- Step 5 — List today's racing markets
- Step 6 — Stream live prices
- Step 7 — Place and cancel a real bet
- Bot template: lay the favourite at 5 minutes
- Limits and costs
- Other exchanges' APIs
- FAQ
This page contains affiliate links. If you open an account or buy software through them we may earn a commission, at no cost to you. It never changes our verdicts.
What the Betfair API does
The Betfair API is the interface behind Bet Angel, Geeks Toy, BetTrader and other Betfair trading platforms. When they display the ladder, list runners or place a bet, they are making API calls. You can call the same endpoints to build tools that off-the-shelf software does not provide:
- Custom automation bots: strategies that do not fit existing software, such as multi-event logic, machine learning predictions or non-betting data feeds.
- Live price logging: recording market depth and trades so you can test strategy rules against your own data without staking money.
- Matched betting automation: placing lay legs automatically when an external service identifies a bookmaker offer.
- Personal dashboards: P&L tracking, multi-account aggregation, alerts on market conditions.
- Statistical modelling: feeding Betfair odds into a Python model.
Two APIs: REST and Stream
- Exchange API (REST/JSON-RPC): request and response endpoints for listing markets, placing and cancelling bets, account funds and market catalogues. This is the foundation.
- Exchange Stream API: a subscription feed over a raw TCP socket (similar in idea to a WebSocket) that pushes price and order updates instead of you polling for them.
The REST API alone covers scheduled bets, low-frequency automation and most matched betting. You need the Stream API for in-play strategies that depend on sub-second price updates.
Prerequisites
- An active Betfair Exchange account with funds. See opening a Betfair account.
- A computer that runs Python 3.8+ or Node.js 16+. Any operating system works.
- Basic familiarity with the command line and HTTP requests. If you have never written code, start with what is Betfair trading and existing software instead.
- A small test balance, such as £20 to £50, to test bet placement. Small stakes keep the cost of early mistakes low.
Step 1 — Create the app key
Log in at developer.betfair.com and go to "Get Started → Visit My App Keys". Enter an Application Name (for example "MyTradingBot"). Two app keys are generated:
- Delayed (test) key: free and available immediately. Returns delayed market prices. Use it to learn the API.
- Live key: needed for live prices and real-money betting. Request it from the same page; it needs email approval from Betfair Developer Support, typically 1 to 3 business days.
Save both keys in a secrets file and never commit them to a public repository.
Step 2 — Generate the SSL certificate (non-interactive login)
Betfair offers interactive login (username and password each session) and non-interactive login (SSL certificate). A bot needs non-interactive login so it can start, log in and run without you.
Generate the certificate with OpenSSL (pre-installed on macOS and Linux; available through Git Bash on Windows):
openssl genrsa -out client-2048.key 2048 openssl req -new -key client-2048.key -out client-2048.csr openssl x509 -req -days 365 -in client-2048.csr \ -signkey client-2048.key -out client-2048.crt
OpenSSL asks for certificate details (country code, organisation, common name); any reasonable values work. Then, in your Betfair account, go to Settings → Security → "My Security" → "Certificate Authentication" and upload client-2048.crt. Certificate login becomes available within minutes.
Step 3 — Install client libraries
Open-source libraries handle authentication, retries and JSON serialisation, so you do not need to write raw requests:
| Language | Library | Install |
|---|---|---|
| Python | betfairlightweight (by liampauling) | pip install betfairlightweight |
| Node.js | betfair-api-ng, with TypeScript types | npm install betfair-api-ng |
| C# / .NET | Official Betfair SDK on GitHub | n/a |
| Java | betfair-stream-api-client-java (community) | n/a |
The examples below use Python with betfairlightweight, which has a large community and works well with pandas for data analysis. Translating them to another language is straightforward.
Step 4 — First authenticated request
Create a Python file test_login.py:
import betfairlightweight
from betfairlightweight import APIClient
trading = APIClient(
username="YOUR_BETFAIR_USERNAME",
password="YOUR_BETFAIR_PASSWORD",
app_key="YOUR_APP_KEY",
certs="/path/to/cert/folder/" # contains client-2048.crt and .key
)
trading.login()
funds = trading.account.get_account_funds()
print(f"Balance: {funds.available_to_bet_balance:.2f} GBP")
print(f"Exposure: {funds.exposure:.2f} GBP")
trading.logout()Run python test_login.py. It should print your balance and exposure. If you get an authentication error, check that the certificate is uploaded to your Betfair account and that the file paths are correct.
Step 5 — List today's racing markets
from betfairlightweight import APIClient
from betfairlightweight.filters import (
market_filter, time_range
)
from datetime import datetime, timedelta
trading = APIClient(...)
trading.login()
today_start = datetime.utcnow().strftime("%Y-%m-%dT00:00:00Z")
today_end = (datetime.utcnow() + timedelta(days=1)).strftime(
"%Y-%m-%dT00:00:00Z")
market_filter_obj = market_filter(
event_type_ids=["7"], # 7 = horse racing
market_countries=["GB"],
market_type_codes=["WIN"],
market_start_time=time_range(
from_=today_start, to=today_end)
)
markets = trading.betting.list_market_catalogue(
filter=market_filter_obj,
market_projection=["EVENT", "RUNNER_DESCRIPTION", "MARKET_START_TIME"],
max_results=200,
sort="FIRST_TO_START"
)
for m in markets[:10]:
print(f"{m.market_start_time} {m.event.venue:12s} {m.market_id}")
trading.logout()This prints the next 10 GB horse racing win markets by start time. Common event_type_ids: 7 horse racing, 1 soccer, 2 tennis, 4 cricket, 4339 greyhounds. The full list is in the Betfair developer documentation.
Step 6 — Stream live prices
Polling the REST endpoints every few seconds is enough for most strategies. In-play work that needs sub-second updates needs the Stream API:
from betfairlightweight import APIClient, StreamListener
from betfairlightweight.filters import (
streaming_market_filter, streaming_market_data_filter
)
trading = APIClient(...)
trading.login()
listener = StreamListener(max_latency=0.5)
stream = trading.streaming.create_stream(listener=listener)
market_filter_obj = streaming_market_filter(
market_ids=["1.245678901"] # market_id from list_market_catalogue
)
data_filter = streaming_market_data_filter(
fields=["EX_BEST_OFFERS_DISP", "EX_LTP", "EX_TRADED_VOL"],
ladder_levels=3
)
stream.subscribe_to_markets(
market_filter=market_filter_obj,
market_data_filter=data_filter
)
stream.start() # blocking — listener.snap() to read stateThe stream pushes updates to listener as they arrive. Call listener.snap() at any point for the current state of every subscribed market.
Step 7 — Place and cancel a real bet
This places a real bet with real money, and a mistake can lose money. Use the smallest stake Betfair allows.
from betfairlightweight.filters import (
place_instruction, limit_order, cancel_instruction
)
# Lay £2 at price 5.0 (minimum stake)
instructions = [
place_instruction(
order_type="LIMIT",
selection_id=12345678, # from list_runners
side="LAY",
limit_order=limit_order(
size=2.0,
price=5.0,
persistence_type="LAPSE"
)
)
]
response = trading.betting.place_orders(
market_id="1.245678901",
instructions=instructions,
customer_strategy_ref="my_test_bot_v1"
)
print(response.status)
for r in response.instruction_reports:
print(f"Bet ID: {r.bet_id}, Status: {r.status}")
bet_id = r.bet_id
# Cancel the bet immediately
cancel_response = trading.betting.cancel_orders(
market_id="1.245678901",
instructions=[cancel_instruction(bet_id=bet_id)]
)
print(cancel_response.status)It should print the place status, the bet ID, then the cancel status. Check the Betfair website to confirm the bet appeared and was cancelled. Every automated strategy builds on this place and cancel pattern.
Bot template: lay the favourite at 5 minutes
This template polls every 30 seconds for GB horse racing win markets starting in about 5 minutes. In each one it finds the favourite (lowest back price) and, if that price is between 2.50 and 3.80, lays it once at that price with a £20 stake. It has no stop-loss, exit or exposure limit; it shows the pattern only.
import time
from datetime import datetime, timedelta
from betfairlightweight import APIClient
from betfairlightweight.filters import (
market_filter, time_range, place_instruction, limit_order
)
trading = APIClient(...)
trading.login()
STAKE = 20.0
STRATEGY_REF = "lay_fav_5min_v1"
EXECUTED_MARKETS = set()
while True:
# Find races starting in next 5-7 minutes
now = datetime.utcnow()
window_start = now + timedelta(minutes=4, seconds=30)
window_end = now + timedelta(minutes=5, seconds=30)
mkts = trading.betting.list_market_catalogue(
filter=market_filter(
event_type_ids=["7"],
market_countries=["GB"],
market_type_codes=["WIN"],
market_start_time=time_range(
from_=window_start.strftime("%Y-%m-%dT%H:%M:%SZ"),
to=window_end.strftime("%Y-%m-%dT%H:%M:%SZ")
)
),
market_projection=["RUNNER_DESCRIPTION", "MARKET_START_TIME"],
max_results=20,
sort="FIRST_TO_START"
)
for mkt in mkts:
if mkt.market_id in EXECUTED_MARKETS:
continue
# Get live prices for this market
book = trading.betting.list_market_book(
market_ids=[mkt.market_id],
price_projection={"priceData": ["EX_BEST_OFFERS"]}
)[0]
# Find favourite (lowest back price)
runners_with_prices = [
r for r in book.runners
if r.ex.available_to_back
]
if not runners_with_prices:
continue
fav = min(
runners_with_prices,
key=lambda r: r.ex.available_to_back[0].price
)
fav_price = fav.ex.available_to_back[0].price
# Only lay if price is in 2.50-3.80 range
if not (2.50 <= fav_price <= 3.80):
continue
try:
response = trading.betting.place_orders(
market_id=mkt.market_id,
instructions=[place_instruction(
order_type="LIMIT",
selection_id=fav.selection_id,
side="LAY",
limit_order=limit_order(
size=STAKE,
price=fav_price,
persistence_type="LAPSE"
)
)],
customer_strategy_ref=STRATEGY_REF
)
print(f"{datetime.utcnow()} LAID {fav.selection_id} "
f"@ {fav_price} on {mkt.market_id}")
EXECUTED_MARKETS.add(mkt.market_id)
except Exception as e:
print(f"Error: {e}")
time.sleep(30) # poll every 30 secondsBefore real use it would need:
- error handling and a persistent log on disk
- a daily exposure cap and a stop after N losing trades
- error alerts by email or Discord
- state that survives a restart, so a crash does not place the same bet twice
We have not backtested or run this strategy, and the template is a pattern, not an edge. Record your own price data, backtest the rule on it, and paper trade before staking real money. Any edge a retail strategy like this has will be small. See what is Betfair trading for context.
Limits and costs
Betfair sets request limits and charges for API use, and some specialist data products, such as historical Stream API archives and specific country market subscriptions, carry separate fees. Check the current terms on developer.betfair.com before you build, because they decide how often a bot can poll and what it costs to run. Using the Stream API for price watching, rather than polling, keeps request counts down.
Other exchanges' APIs
If your strategy does not depend on Betfair's liquidity, other exchanges also offer APIs. Best Betfair alternatives covers the wider trade-offs; see also Betfair vs Smarkets and Betfair vs Betdaq.
- Smarkets API: REST with WebSocket streaming, documented, used for political market bots and matched betting automation.
- Betdaq API: SOAP-based, an older protocol that is harder to work with than REST, with a smaller community.
- Matchbook API: modern REST, used for US sports automation.
Betfair has the largest developer community and the most tutorials, which is why most bot developers start there.
For most retail traders, existing trading software such as Bet Angel (Excel and Guardian), Fairbot (bot rule editor) or BetTrader (multi-exchange interface) is faster and cheaper than building from the API. Use the API when your strategy does not fit existing software, when you want something proprietary, or when you want to learn the internals.
Open Betfair Exchange — required to obtain an API key.
Open Betfair Account → Visit Betfair Developer →FAQ
How long does it take to get a Betfair app key?
The delayed app key is free and approved within minutes. The live app key, needed for live market data and real-money betting, requires email approval from Betfair Developer Support and typically takes 1 to 3 business days. Live keys for commercial bots can take 1 to 2 weeks.
Do I need a coding background?
Yes. You need basic Python or JavaScript and the command line. Without that, start with our what is Betfair trading guide and existing software such as Bet Angel. If you can code, read the Betfair developer documentation and the betfairlightweight source, and build a non-trading tool such as a P&L logger first, so you learn the API with no money at risk.
Can my bot run unattended?
Yes. Once certificate login is set up (Step 2), the bot can log in, run and place bets without you. Bots are often run on a small VPS (DigitalOcean, Linode, AWS) for reliability, at £5 to £15 a month.
What happens if my bot makes a mistake?
You lose real money. Common mistakes are betting at the wrong price (validate price ranges in code), mishandling partial fills and having no daily exposure limit. Test with the smallest stakes, scale up only after weeks of stable behaviour, and build bankroll management rules into the bot.
Can I trade Betdaq from the same code?
Not directly. Betdaq uses a different, SOAP-based API, so you would add a separate API client to the same project. Alternatively, Fairbot and BetTrader handle several exchanges in one interface.
What is the difference between the API and software like Bet Angel?
Bet Angel uses the same API internally. It is a finished product with a graphical interface; the API is the raw building block. Use Bet Angel when its features fit your strategy and the API when they do not. You can use both: Bet Angel for ladder trading and Python scripts for specialised automation.
See also: Bet Angel Review, Building Betfair Bots, and bankroll management.