Build a live odds comparison tool in Python (free Australian odds API)
An odds comparison tool answers one question for every selection: which bookmaker is paying the most? Across Australia's books — Sportsbet, TAB, Neds, Ladbrokes, Unibet, PointsBet and Betfair — the best price can vary by 10%+, and that gap (the "overlay") is the entire edge in price-driven betting.
In this tutorial we'll build a best-price comparison in Python using the free PuntersEdge AU Odds API. No scraping, no maintaining a connector per bookmaker.
⚠️ 18+ only. This is market-data tooling, not a betting service or financial advice. Bet only what you can afford to lose. Gambling Help: 1800 858 858.
Get a free key
Free key at puntersedge.online/api-platform (1,500 credits/month, no card), passed in X-API-Key.
import requests
BASE = "https://api.puntersedge.online/v1"
HEADERS = {"X-API-Key": "YOUR_FREE_KEY"}
Step 1 — best price per selection
/v1/best-odds/{sport} already collapses every bookmaker to the best price per selection, and includes all_prices so you can show the full row:
def best_odds(sport):
r = requests.get(f"{BASE}/best-odds/{sport}", headers=HEADERS, timeout=15)
r.raise_for_status()
return r.json()
for ev in best_odds("afl"):
print(f"\n{ev['home_team']} v {ev['away_team']}")
for s in ev["selections"]:
print(f" {s['name']:<22} best {s['best_price']} @ {s['best_bookmaker']}")
Step 2 — render a comparison table
Pivot each selection's all_prices into a per-bookmaker grid, highlighting the best:
def table(event):
books = sorted({p["bookmaker"] for s in event["selections"] for p in s["all_prices"]})
print(f"{'Selection':<22}" + "".join(f"{b[:10]:>11}" for b in books))
for s in event["selections"]:
prices = {p["bookmaker"]: p["price"] for p in s["all_prices"]}
row = ""
for b in books:
v = prices.get(b)
cell = f"{v}{'*' if v == s['best_price'] else ' '}" if v else "-"
row += f"{cell:>11}"
print(f"{s['name']:<22}{row}")
table(best_odds("afl")[0]) # * marks the best price
Step 3 — measure the overlay (where the edge is)
/v1/arb/best-prices adds worst_price, avg_price, price_spread and overlay_pct per selection — the overlay is how far the best price sits above the market average, i.e. how much value the comparison is surfacing:
ev = requests.get(f"{BASE}/arb/best-prices", headers=HEADERS, timeout=15).json()[0]
print(f"{ev['home_team']} v {ev['away_team']}")
for s in ev["selections"]:
print(f" {s['name']:<22} best {s['best_price']} "
f"(avg {s['avg_price']}, +{s['overlay_pct']}% overlay, spread {s['price_spread']})")
Sort selections by overlay_pct and you've got a value board: the biggest gaps between the best and average price across the market.
Wrap up
That's a working odds comparison: best price per selection, a full per-book table, and an overlay metric to rank where the value is. Drop it behind a web framework and you've got a comparison site; poll it and alert on a target overlay.
- Free key + docs: https://puntersedge.online/api-platform
- Also on RapidAPI: https://rapidapi.com/Propertyscout001/api/puntersedge-au-odds
- Endpoints:
/v1/best-odds/{sport},/v1/arb/best-prices
(18+, gamble responsibly, Gambling Help 1800 858 858.)