Live Betting API: Real-Time Odds for In-Play Markets
What Is a Live Betting API?
A live betting API (also called an in-play odds API) delivers real-time odds for matches already in progress. Unlike pre-match odds that update every few hours, live odds can shift every few seconds as the game state changes—a goal scored, a red card issued, momentum swinging.
If you’re building anything that touches in-play markets, you need an API that can keep up.
Common use cases:
- Live arbitrage scanners
- In-play trading dashboards
- Real-time odds comparison widgets
- CLV (Closing Line Value) trackers
- Automated in-play alerts
The Problem: Live Odds Are Hard to Get
Here’s the reality most developers hit:
| Approach | Problems |
|---|---|
| Scraping bookmaker sites | Blocked instantly. Cloudflare. Legal risk. Maintenance nightmare. |
| Enterprise feeds (Sportradar, etc.) | $50K+/year minimum. 6-month sales cycles. Enterprise contracts. |
| Consumer APIs (The Odds API) | Limited bookmaker coverage. No sharps. Delayed live data. |
The sharp bookmakers (Pinnacle, Singbet, SBOBet) don’t offer public APIs. The enterprise data vendors want enterprise money. The free APIs only cover 20-40 soft bookmakers with minutes-old data.
OddsPapi is the bridge. We aggregate real-time odds from 350+ bookmakers—including the sharps—and expose them through a developer-friendly REST API. Free tier included.
Live Betting Coverage
Sports With Live Odds
OddsPapi covers 59 sports. Here’s what’s typically available for in-play betting:
| Sport | Sport ID | Live Coverage |
|---|---|---|
| Soccer | 10 | 100+ live fixtures daily |
| Basketball | 11 | NBA, Euroleague, and international leagues |
| Tennis | 12 | ATP, WTA, ITF matches |
| Ice Hockey | 15 | NHL, KHL, European leagues |
| Esports (CS2) | 17 | Major tournaments and tier 1/2 matches |
| Esports (LoL) | 18 | LCK, LEC, LCS, and regional leagues |
| Table Tennis | 25 | 24/7 coverage |
Bookmakers Streaming Live Odds
Not all bookmakers update prices during play. Here are the ones that do—and that OddsPapi tracks live:
| Bookmaker | Type | Slug |
|---|---|---|
| Pinnacle | Sharp | pinnacle |
| Singbet (Crown) | Sharp Asian | singbet |
| SBOBet | Sharp Asian | sbobet |
| Bet365 | Soft | bet365 |
| 1xBet | Crypto/High-limit | 1xbet |
| Betfair Exchange | Exchange | betfair-ex |
| Betway | Soft | betway |
| Unibet | Soft | unibet |
A single live soccer fixture typically has odds from 80-100+ bookmakers simultaneously.
Live Market Types
OddsPapi provides live odds for the full range of markets:
- Moneyline / 1X2 (Market ID: 101)
- Asian Handicap (Multiple IDs: 1064-1076)
- Over/Under Totals (Market ID: 1010 for O/U 2.5)
- Both Teams To Score (Market ID: 104)
- Next Goal and period-specific markets
Live Odds API Comparison
| Feature | OddsPapi | The Odds API | OddsJam |
|---|---|---|---|
| Total Bookmakers | 350+ | ~40 | ~70 |
| Sharp Bookmakers | Pinnacle, Singbet, SBOBet | None | Pinnacle only |
| Live Odds | Yes (REST + WebSocket) | Limited | Yes |
| Free Tier Live Access | Yes | No | No |
| Sports Covered | 59 | ~15 | ~20 |
| Asian Markets | Native support | No | Limited |
| Historical Data (Free) | Yes | Paid add-on | Paid |
Python Tutorial: Get Live Odds
Let’s build a simple live odds fetcher. All examples use the free tier.
Step 1: Get Your Free API Key
Sign up at oddspapi.io and grab your API key. No credit card required.
Step 2: Find Live Fixtures
First, let’s find matches currently in progress:
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"
# Date range for today
today = datetime.now()
from_date = today.strftime("%Y-%m-%dT00:00:00Z")
to_date = (today + timedelta(days=1)).strftime("%Y-%m-%dT23:59:59Z")
# Get soccer fixtures (sportId=10)
response = requests.get(f"{BASE_URL}/fixtures", params={
"apiKey": API_KEY,
"sportId": 10,
"from": from_date,
"to": to_date
})
fixtures = response.json()
# Filter to live fixtures (statusId=1) with odds
live_fixtures = [
f for f in fixtures
if f.get("statusId") == 1 and f.get("hasOdds")
]
print(f"Live soccer fixtures with odds: {len(live_fixtures)}")
for fixture in live_fixtures[:5]:
print(f" {fixture['fixtureId']} - Started: {fixture['trueStartTime']}")
Step 3: Get Live Odds for a Fixture
Once you have a fixture ID, fetch the current odds:
# Get odds for a live fixture
fixture_id = live_fixtures[0]["fixtureId"]
response = requests.get(f"{BASE_URL}/odds", params={
"apiKey": API_KEY,
"fixtureId": fixture_id
})
odds_data = response.json()
# List all bookmakers with odds
bookmakers = list(odds_data.get("bookmakerOdds", {}).keys())
print(f"Bookmakers with live odds: {len(bookmakers)}")
# Get Pinnacle's 1X2 odds (if available)
if "pinnacle" in odds_data["bookmakerOdds"]:
markets = odds_data["bookmakerOdds"]["pinnacle"]["markets"]
# Market 101 = Full Time Result (1X2)
if "101" in markets:
outcomes = markets["101"]["outcomes"]
home = outcomes["101"]["players"]["0"]["price"]
draw = outcomes["102"]["players"]["0"]["price"]
away = outcomes["103"]["players"]["0"]["price"]
last_update = outcomes["101"]["players"]["0"]["changedAt"]
print(f"Pinnacle 1X2: Home {home} | Draw {draw} | Away {away}")
print(f"Last updated: {last_update}")
Step 4: Poll for Line Movements
To detect line movements, poll periodically and compare prices:
import time
def get_pinnacle_odds(fixture_id):
"""Fetch current Pinnacle 1X2 odds for a fixture."""
response = requests.get(f"{BASE_URL}/odds", params={
"apiKey": API_KEY,
"fixtureId": fixture_id
})
data = response.json()
if "pinnacle" not in data.get("bookmakerOdds", {}):
return None
markets = data["bookmakerOdds"]["pinnacle"]["markets"]
if "101" not in markets:
return None
outcomes = markets["101"]["outcomes"]
return {
"home": outcomes["101"]["players"]["0"]["price"],
"draw": outcomes["102"]["players"]["0"]["price"],
"away": outcomes["103"]["players"]["0"]["price"],
"timestamp": outcomes["101"]["players"]["0"]["changedAt"]
}
# Poll every 10 seconds for 1 minute
previous_odds = None
for i in range(6):
current_odds = get_pinnacle_odds(fixture_id)
if current_odds and previous_odds:
# Check for movement
if current_odds["home"] != previous_odds["home"]:
print(f"HOME moved: {previous_odds['home']} -> {current_odds['home']}")
if current_odds["draw"] != previous_odds["draw"]:
print(f"DRAW moved: {previous_odds['draw']} -> {current_odds['draw']}")
if current_odds["away"] != previous_odds["away"]:
print(f"AWAY moved: {previous_odds['away']} -> {current_odds['away']}")
previous_odds = current_odds
time.sleep(10)
print("Done monitoring.")
What Can You Build?
Live Arbitrage Scanner
Compare odds across 100+ bookmakers in real-time. When Pinnacle moves, soft books lag behind—that’s your window.
In-Play Trading Dashboard
Display live odds from multiple sharps side-by-side. Spot steam moves and react.
CLV Tracker
Record your entry price and compare against the closing line. Measure your actual edge over time.
Live Odds Widget
Embed real-time odds on your affiliate site. Show users what Pinnacle is offering right now, not cached data from an hour ago.
Free Tier vs. Pro: An Honest Take
Let’s be real about what each tier can do:
| Use Case | Free Tier (REST) | Pro Tier (WebSocket) |
|---|---|---|
| Live odds display | Viable (poll every 5-10s) | Best |
| Manual betting research | Viable | Overkill |
| Casual arb scanning | Viable (you won’t catch sub-second arbs) | Recommended |
| Serious arb trading | Not ideal | Required |
| HFT-style trading | No | Yes |
| Backtesting models | Viable (historical data free) | Same |
REST polling latency: ~800-1000ms per request. That’s fine for displaying odds, building dashboards, or manual research. It’s not fast enough to catch arbs that close in milliseconds.
WebSocket streaming: Sub-second updates pushed to you. Required if you’re building anything latency-sensitive.
Start with the free tier. If you find yourself rate-limited or missing opportunities, upgrade.
Start Building Your Live Betting Tool
Stop scraping. Stop paying enterprise prices for limited data.
OddsPapi gives you real-time odds from 350+ bookmakers—including the sharps that actually matter for live betting—through a single API.
- Free tier with live REST access
- 59 sports covered
- Pinnacle, Singbet, SBOBet included
- Historical data free for backtesting
Get your free OddsPapi API key and start building.