How to Get Bet365 Odds via API in Python (2026 Guide)
Bet365 is the world's largest online sportsbook — but they don't offer a public API. No developer portal, no documentation, no OAuth flow. If you want Bet365 football odds programmatically, your options have traditionally been scraping (fragile, against terms of service, constant breakage) or paying $100-150+ per month for a single-bookmaker data feed.
UKOddsApi solves this. It provides Bet365 odds alongside 24 other UK bookmakers and exchanges — all through a single REST API. In this tutorial, you'll pull live Bet365 Premier League odds in under 5 minutes with Python.
What you'll build
By the end of this tutorial, you'll have a Python script that:
- Connects to the UKOddsApi and authenticates with your API key
- Fetches today's Premier League fixtures
- Pulls Bet365 odds for every match across multiple markets
- Compares Bet365 prices against other UK bookmakers to find the best odds
- Outputs a clean table showing where Bet365 is offering the best (or worst) value
Prerequisites
- Python 3.8+
- A UKOddsApi account (sign up free at ukoddsapi.com)
- The
requestslibrary (pip install requests)
Step 1: Verify your API key
Every request to UKOddsApi uses the X-Api-Key header. Let's confirm your key works:
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.ukoddsapi.com"
headers = {"X-Api-Key": API_KEY}
# Verify the key is valid
response = requests.get(f"{BASE_URL}/v1/auth/verify", headers=headers)
data = response.json()
if data.get("ok"):
print("✅ API key is valid")
else:
print("❌ Invalid API key — check your dashboard at ukoddsapi.com")
Step 2: See which bookmakers are available
Before pulling odds, let's see the full list of UK bookmakers available through the API:
response = requests.get(f"{BASE_URL}/v1/bookmakers", headers=headers)
bookmakers = response.json()["bookmakers"]
print(f"📚 {len(bookmakers)} bookmakers available:\n")
for bm in bookmakers:
bm_type = "🔄 Exchange" if bm["type"] == "exchange" else "📗 Sportsbook"
print(f" {bm_type} {bm['name']} ({bm['bookmaker_code']})")
Output:
📚 26 bookmakers available:
📗 Sportsbook 10Bet (UO001)
📗 Sportsbook 888sport (UO002)
📗 Sportsbook Bet365 (UO004)
📗 Sportsbook BetVictor (UO005)
🔄 Exchange Betfair (UO006)
📗 Sportsbook Betfred (UO007)
📗 Sportsbook Betway (UO008)
📗 Sportsbook BoyleSports (UO012)
📗 Sportsbook Coral (UO013)
📗 Sportsbook Ladbrokes (UO015)
🔄 Exchange Matchbook (UO017)
📗 Sportsbook Paddy Power (UO018)
📗 Sportsbook Sky Bet (UO020)
📗 Sportsbook Spreadex (UO022)
📗 Sportsbook Unibet (UO024)
📗 Sportsbook William Hill (UO027)
... and more
Notice that — unlike other odds APIs — UKOddsApi includes every major UK high street bookmaker: Bet365, Sky Bet, Paddy Power, William Hill, Ladbrokes, Coral, Betfred, BetVictor, and more. Plus exchanges like Betfair and Matchbook.
Step 3: Get today's Premier League fixtures
from datetime import date
today = date.today().isoformat()
response = requests.get(
f"{BASE_URL}/v1/football/events",
headers=headers,
params={
"schedule_date": today,
"league": "premier-league",
}
)
events = response.json()["events"]
print(f"⚽ {len(events)} Premier League matches today:\n")
for event in events:
print(f" {event['event_title']}")
print(f" Kick-off: {event['kickoff_utc']}")
print(f" Event ID: {event['event_id']}")
print()
Output:
⚽ 3 Premier League matches today:
Arsenal vs Chelsea
Kick-off: 2026-04-25T15:00:00Z
Event ID: evt_arsenal_chelsea_2026_04_25
Liverpool vs Manchester United
Kick-off: 2026-04-25T17:30:00Z
Event ID: evt_liverpool_manutd_2026_04_25
Brighton vs Tottenham
Kick-off: 2026-04-25T20:00:00Z
Event ID: evt_brighton_spurs_2026_04_25
Step 4: Pull Bet365 odds for a match
Now let's get Bet365 odds for a specific fixture. We'll filter by bookmaker code UO004 (Bet365):
event_id = events[0]["event_id"] # First match
response = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds",
headers=headers,
params={
"package": "core",
"bookmaker_codes": "UO004", # Bet365 only
"odds_format": "decimal",
}
)
odds_data = response.json()
print(f"📊 Bet365 odds for {odds_data['event_title']}")
print(f" Captured at: {odds_data['captured_at']}\n")
for market in odds_data["markets"]:
print(f" 📈 {market['market_name']} ({market['market_group']})")
for sel in market["selections"]:
print(f" {sel['selection_name']}: {sel['odds']}")
print()
Output:
📊 Bet365 odds for Arsenal vs Chelsea
Captured at: 2026-04-25T14:32:10.459641Z
📈 Win Market (main)
Arsenal: 1.85
Draw: 3.60
Chelsea: 4.20
📈 Both Teams to Score (main)
Yes: 1.72
No: 2.00
📈 Over/Under 2.5 Goals (main)
Over 2.5: 1.66
Under 2.5: 2.20
📈 Total Corners Over/Under (corners)
Over 9.5: 1.90
Under 9.5: 1.90
Step 5: Compare Bet365 against all UK bookmakers
This is where it gets powerful. Let's pull odds from ALL bookmakers and find where Bet365 offers the best price — and where other bookmakers beat them:
# Get odds from ALL bookmakers
response = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds/best",
headers=headers,
params={
"package": "core",
"odds_format": "decimal",
}
)
best_odds = response.json()
print(f"🏆 Best odds comparison for {best_odds['event_title']}\n")
for market in best_odds["markets"]:
print(f" 📈 {market['market_name']}")
for sel in market["selections"]:
best_bookie = sel["bookmaker_name"]
best_price = sel["odds"]
print(f" {sel['selection_name']}: {best_price} @ {best_bookie}")
print()
Output:
🏆 Best odds comparison for Arsenal vs Chelsea
📈 Win Market
Arsenal: 1.91 @ Paddy Power
Draw: 3.70 @ BoyleSports
Chelsea: 4.33 @ William Hill
📈 Both Teams to Score
Yes: 1.80 @ Sky Bet
No: 2.10 @ Coral
📈 Over/Under 2.5 Goals
Over 2.5: 1.72 @ Betfred
Under 2.5: 2.30 @ BetVictor
Step 6: Build a Bet365 value checker
Now let's combine everything into a practical tool. This script compares Bet365's prices against the best available odds across all UK bookmakers and tells you where Bet365 is offering poor value:
import requests
from datetime import date
API_KEY = "your_api_key_here"
BASE_URL = "https://api.ukoddsapi.com"
headers = {"X-Api-Key": API_KEY}
BET365_CODE = "UO004"
def get_todays_matches(league="premier-league"):
"""Fetch today's fixtures for a league."""
response = requests.get(
f"{BASE_URL}/v1/football/events",
headers=headers,
params={
"schedule_date": date.today().isoformat(),
"league": league,
}
)
return response.json().get("events", [])
def compare_bet365_odds(event_id):
"""Compare Bet365 odds against the best available price."""
# Get ALL bookmaker odds
response = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds",
headers=headers,
params={"package": "core", "odds_format": "decimal"}
)
all_odds = response.json()
# Get best odds
response = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds/best",
headers=headers,
params={"package": "core", "odds_format": "decimal"}
)
best_odds = response.json()
print(f"\n{'='*60}")
print(f"⚽ {all_odds['event_title']}")
print(f"{'='*60}")
# Build lookup: market_name -> selection_name -> {bet365_odds, best_odds, best_bookie}
# First, extract Bet365 odds from the full response
bet365_prices = {}
for market in all_odds["markets"]:
mname = market["market_name"]
bet365_prices[mname] = {}
for sel in market["selections"]:
if sel["bookmaker_code"] == BET365_CODE:
bet365_prices[mname][sel["selection_name"]] = sel["odds"]
# Then compare against best odds
for market in best_odds["markets"]:
mname = market["market_name"]
print(f"\n 📈 {mname}")
print(f" {'Selection':<20} {'Bet365':>8} {'Best':>8} {'Best Bookie':<16} {'Edge':>8}")
print(f" {'-'*62}")
for sel in market["selections"]:
sname = sel["selection_name"]
best_price = sel["odds"]
best_bookie = sel["bookmaker_name"]
b365_price = bet365_prices.get(mname, {}).get(sname)
if b365_price:
edge = ((best_price / b365_price) - 1) * 100
flag = "✅" if best_bookie == "Bet365" else "⚠️"
print(f" {flag} {sname:<18} {b365_price:>8.2f} {best_price:>8.2f} {best_bookie:<16} {edge:>+7.1f}%")
else:
print(f" ❓ {sname:<18} {'N/A':>8} {best_price:>8.2f} {best_bookie:<16}")
# Run it
matches = get_todays_matches()
if not matches:
print("No Premier League matches today. Try another league:")
matches = get_todays_matches(league="championship")
for match in matches[:3]: # First 3 matches
compare_bet365_odds(match["event_id"])
Output:
============================================================
⚽ Arsenal vs Chelsea
============================================================
📈 Win Market
Selection Bet365 Best Best Bookie Edge
--------------------------------------------------------------
✅ Arsenal 1.85 1.85 Bet365 +0.0%
⚠️ Draw 3.60 3.70 BoyleSports +2.8%
⚠️ Chelsea 4.20 4.33 William Hill +3.1%
📈 Both Teams to Score
Selection Bet365 Best Best Bookie Edge
--------------------------------------------------------------
⚠️ Yes 1.72 1.80 Sky Bet +4.7%
⚠️ No 2.00 2.10 Coral +5.0%
📈 Over/Under 2.5 Goals
Selection Bet365 Best Best Bookie Edge
--------------------------------------------------------------
⚠️ Over 2.5 1.66 1.72 Betfred +3.6%
⚠️ Under 2.5 2.20 2.30 BetVictor +4.5%
This instantly shows where Bet365 is competitive and where you're leaving value on the table by not checking other UK bookmakers.
Step 7: Get Bet365 player props (Pro plan)
If you're on the Pro plan, you can access player props — goalscorer odds, shots, cards, and more — from Bet365 and every other UK bookmaker:
# Use package=full to include player props and team props
response = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds",
headers=headers,
params={
"package": "full",
"bookmaker_codes": "UO004", # Bet365
"market": "goalscorer", # Filter to goalscorer markets
"odds_format": "decimal",
}
)
props = response.json()
print(f"🎯 Bet365 Player Props — {props['event_title']}\n")
for market in props["markets"]:
print(f" 📈 {market['market_name']}")
# Show top 5 selections by odds (shortest price = most likely)
sorted_sels = sorted(market["selections"], key=lambda x: x["odds"])
for sel in sorted_sels[:5]:
print(f" {sel['selection_name']}: {sel['odds']}")
print()
Output:
🎯 Bet365 Player Props — Arsenal vs Chelsea
📈 Anytime Goalscorer
Kai Havertz: 2.50
Bukayo Saka: 3.00
Nicolas Jackson: 3.20
Gabriel Jesus: 3.50
Cole Palmer: 3.75
📈 Player Shots Over/Under
Bukayo Saka Over 1.5 Shots: 1.44
Cole Palmer Over 1.5 Shots: 1.57
Kai Havertz Over 1.5 Shots: 1.65
Compare Bet365's goalscorer odds against all 25+ UK bookmakers to find the best price for every player — something no other odds API can do.
What to build next
Now you have Bet365 odds flowing through a clean API, here are some ideas:
- Odds comparison website — show the best odds across all UK bookmakers for every Premier League match
- Telegram alert bot — get notified when Bet365 drops below a certain price on a market you're watching
- Value bet finder — compare Bet365 retail odds against Betfair Exchange to identify +EV opportunities
- Arbitrage scanner — use the built-in
/v1/football/arbitrageendpoint to find guaranteed-profit opportunities across UK bookmakers (Scale plan)
Full working script
Here's everything combined into a single file you can save and run:
"""
bet365_odds_checker.py
Compare Bet365 football odds against all UK bookmakers.
Uses UKOddsApi — sign up free at https://ukoddsapi.com
Usage:
pip install requests
python bet365_odds_checker.py
"""
import requests
from datetime import date
# ─── Configuration ───────────────────────────────────────
API_KEY = "your_api_key_here" # Get yours at ukoddsapi.com
BASE_URL = "https://api.ukoddsapi.com"
BET365_CODE = "UO004"
LEAGUE = "premier-league" # Try: championship, league-one, champions-league
# ─────────────────────────────────────────────────────────
headers = {"X-Api-Key": API_KEY}
def verify_key():
r = requests.get(f"{BASE_URL}/v1/auth/verify", headers=headers)
if not r.json().get("ok"):
raise SystemExit("❌ Invalid API key. Get one at ukoddsapi.com")
print("✅ API key verified\n")
def get_events(league, schedule_date=None):
params = {"league": league}
if schedule_date:
params["schedule_date"] = schedule_date
r = requests.get(f"{BASE_URL}/v1/football/events", headers=headers, params=params)
return r.json().get("events", [])
def check_bet365_value(event_id):
# Full odds from all bookmakers
r_all = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds",
headers=headers,
params={"package": "core", "odds_format": "decimal"}
)
all_data = r_all.json()
# Best odds per selection
r_best = requests.get(
f"{BASE_URL}/v1/football/events/{event_id}/odds/best",
headers=headers,
params={"package": "core", "odds_format": "decimal"}
)
best_data = r_best.json()
print(f"\n{'='*65}")
print(f"⚽ {all_data['event_title']}")
print(f" Kick-off: {all_data['kickoff_utc']}")
print(f"{'='*65}")
# Extract Bet365 prices
b365 = {}
for mkt in all_data["markets"]:
b365[mkt["market_name"]] = {
sel["selection_name"]: sel["odds"]
for sel in mkt["selections"]
if sel["bookmaker_code"] == BET365_CODE
}
# Compare
for mkt in best_data["markets"]:
mn = mkt["market_name"]
print(f"\n {mn}")
print(f" {'Selection':<22}{'Bet365':>8}{'Best':>8} {'Bookie':<16}{'Edge':>7}")
print(f" {'-'*63}")
for sel in mkt["selections"]:
sn = sel["selection_name"]
bp = sel["odds"]
bb = sel["bookmaker_name"]
b3 = b365.get(mn, {}).get(sn)
if b3:
edge = ((bp / b3) - 1) * 100
flag = "✅" if bb == "Bet365" else "⚠️"
print(f" {flag} {sn:<20}{b3:>8.2f}{bp:>8.2f} {bb:<16}{edge:>+6.1f}%")
def main():
verify_key()
today = date.today().isoformat()
events = get_events(LEAGUE, schedule_date=today)
if not events:
print(f"No {LEAGUE} matches today. Showing upcoming fixtures...\n")
events = get_events(LEAGUE)
print(f"Found {len(events)} fixtures\n")
for event in events[:5]:
check_bet365_value(event["event_id"])
if __name__ == "__main__":
main()
API reference
| Endpoint | Description |
|---|---|
GET /v1/bookmakers |
List all 25+ UK bookmakers with codes |
GET /v1/football/events |
Get fixtures by date, league, or status |
GET /v1/football/events/{id}/odds |
Full odds from all bookmakers |
GET /v1/football/events/{id}/odds/best |
Best price per selection |
GET /v1/football/markets |
Browse all available market types |
POST /v1/football/odds/batch |
Odds for up to 50 events in one call |
GET /v1/football/arbitrage |
Find arbitrage opportunities by date |
All endpoints use the X-Api-Key header for authentication. Odds are returned in decimal format by default — pass odds_format=fractional or odds_format=american to change.
UKOddsApi provides odds from 25+ UK bookmakers including Bet365, Sky Bet, Paddy Power, William Hill, Ladbrokes, Coral, Betfred, BetVictor, 888sport, and more. Sign up free and start building.