Free Odds API: Access 350+ Bookmakers Without Paying a Cent
The Developer’s Dilemma: You Need Data Before You Can Afford Data
You want to build a betting model. Maybe an arbitrage scanner. Maybe a value betting algorithm. Maybe you just want to backtest a theory before risking real money.
But here’s the catch: you need odds data to prove your model works, but you can’t afford data until you’ve proven it works.
So you search for “free odds API” and find the usual suspects:
- APIs with 40 bookmakers (none of them sharp)
- “Free trials” that expire in 7 days
- Scrapers that break every week
- Enterprise APIs that want $500/month before you’ve written a single line of code
OddsPapi’s free tier is different. You get 350+ bookmakers—including Pinnacle, Singbet, and other sharps—with no credit card required. Build your model. Prove it works. Then decide if you need more.
What’s Actually Free on OddsPapi
Let’s be specific. Here’s what you get on the free tier:
| Feature | Free Tier |
|---|---|
| Bookmakers | 350+ (not 40, not 80—over three hundred fifty) |
| Sharp Bookmakers | Pinnacle, Singbet, SBOBet, Circa |
| Soft Bookmakers | Bet365, DraftKings, FanDuel, William Hill, 1xBet |
| Sports | 59 sports covered |
| Historical Data | Included free (competitors charge $50-200/mo) |
| Requests/Month | 250 |
| Credit Card Required | No |
The 250 request limit sounds tight, but each request returns data from all 350+ bookmakers. One request, 350+ prices. You’re not paying per bookmaker like some APIs.
Free Tier Comparison: The Real Numbers
Here’s how OddsPapi’s free tier stacks up against competitors:
| Feature | OddsPapi Free | The Odds API Free | Sports Game Odds |
|---|---|---|---|
| Bookmakers | 350+ | ~80 | ~50 |
| Sharp Books (Pinnacle) | ✓ | ✗ | ✗ |
| Asian Sharps (Singbet) | ✓ | ✗ | ✗ |
| Historical Data | ✓ Free | ✓ Free | Limited |
| Requests/Month | 250 | 500 (credits) | 1,000 objects |
| Data Delay | Real-time | Real-time | 5 minutes |
Yes, The Odds API gives you more requests. But 500 requests across 80 bookmakers gives you less coverage than 250 requests across 350+ bookmakers. And if you need Pinnacle or Singbet data for sharp-vs-soft analysis, only one of these options works.
Get Started in 5 Minutes: Python Tutorial
Enough theory. Let’s write some code.
Step 1: Get Your Free API Key
Head to oddspapi.io and sign up. No credit card. You’ll get an API key immediately.
Step 2: Verify Your Key Works
import requests
API_KEY = "YOUR_FREE_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"
# Test authentication
response = requests.get(f"{BASE_URL}/sports", params={"apiKey": API_KEY})
print(f"Status: {response.status_code}")
print(f"Sports available: {len(response.json())}")
You should see Status: 200 and Sports available: 59.
Step 3: Browse Available Sports
import requests
API_KEY = "YOUR_FREE_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"
# Get all available sports
response = requests.get(f"{BASE_URL}/sports", params={"apiKey": API_KEY})
sports = response.json()
# Print sport IDs for reference
for sport in sports[:10]:
print(f"{sport['sportId']}: {sport['sportName']}")
Output:
10: Soccer
11: Basketball
12: Tennis
13: Baseball
14: American Football
15: Ice Hockey
16: Volleyball
17: Handball
18: Rugby League
19: Cricket
Step 4: Get Tournaments for a Sport
import requests
API_KEY = "YOUR_FREE_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"
# Get soccer tournaments with upcoming fixtures
response = requests.get(f"{BASE_URL}/tournaments", params={
"apiKey": API_KEY,
"sportId": 10 # Soccer
})
tournaments = response.json()
# Filter for tournaments with upcoming matches
active = [t for t in tournaments if t.get('upcomingFixtures', 0) > 0]
print(f"Active soccer tournaments: {len(active)}")
for t in active[:5]:
print(f" {t['tournamentName']}: {t['upcomingFixtures']} upcoming matches")
Step 5: Get Fixtures for a Tournament
import requests
API_KEY = "YOUR_FREE_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"
# Get Premier League fixtures (tournamentId: 2)
response = requests.get(f"{BASE_URL}/fixtures", params={
"apiKey": API_KEY,
"tournamentId": 2
})
fixtures = response.json()
# Filter for fixtures with odds available
with_odds = [f for f in fixtures if f.get('hasOdds', False)]
print(f"Total fixtures: {len(fixtures)}")
print(f"Fixtures with odds: {len(with_odds)}")
for fixture in with_odds[:3]:
print(f" {fixture['participant1Name']} vs {fixture['participant2Name']}")
print(f" Fixture ID: {fixture['fixtureId']}")
print(f" Start: {fixture['startTime']}")
Step 6: Pull Odds from Pinnacle, Bet365, and DraftKings
import requests
API_KEY = "YOUR_FREE_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"
# Replace with an actual fixture ID from Step 5
FIXTURE_ID = "id1000000861624354"
# Get odds for this fixture
response = requests.get(f"{BASE_URL}/odds", params={
"apiKey": API_KEY,
"fixtureId": FIXTURE_ID
})
data = response.json()
# Extract odds from specific bookmakers
target_books = ['pinnacle', 'bet365', 'draftkings', 'singbet']
bookmaker_odds = data.get('bookmakerOdds', {})
print(f"Total bookmakers with odds: {len(bookmaker_odds)}")
print("\n--- Sharp vs Soft Comparison ---")
for slug in target_books:
if slug in bookmaker_odds:
markets = bookmaker_odds[slug].get('markets', {})
# Market 101 = Full Time Result (1X2)
if '101' in markets:
outcomes = markets['101'].get('outcomes', {})
print(f"\n{slug.upper()} - Full Time Result:")
for outcome_id, outcome_data in outcomes.items():
price = outcome_data.get('players', {}).get('0', {}).get('price', 'N/A')
name = outcome_data.get('outcomeName', outcome_id)
print(f" {name}: {price}")
This gives you a direct comparison between sharp bookmakers (Pinnacle, Singbet) and soft bookmakers (Bet365, DraftKings). The foundation for any value betting or arbitrage system.
What You Can Build on the Free Tier
250 requests/month is enough for:
| Use Case | Feasible on Free Tier? |
|---|---|
| Pregame value betting models | ✓ Yes |
| Historical backtesting (CLV analysis) | ✓ Yes |
| Bookmaker coverage dashboards | ✓ Yes |
| Line shopping tools (manual) | ✓ Yes |
| Model training datasets | ✓ Yes |
| Real-time arb bots | ✗ Need WebSocket (Pro tier) |
| High-frequency applications | ✗ 250 req/mo limit |
The free tier is designed for development and proof-of-concept. Build your model, prove it works, then scale up.
When to Upgrade
We’ll be honest about the limitations. Upgrade to a paid tier when:
- You need WebSocket for sub-second updates. Arbitrage windows close in milliseconds. Polling won’t cut it.
- You’re exceeding 250 requests/month. If your model is working, you’ll want more data.
- You’re building production trading systems. The free tier is for development, not production.
But here’s the thing: you’ll know when you need to upgrade because your model will be making money. That’s the point of a free tier that doesn’t suck.
Stop Scraping. Start Building.
Scraping is a waste of time. Bookmakers change their DOM, you fix your scraper. They add CAPTCHAs, you solve CAPTCHAs. They ban your IP, you rotate proxies. It never ends.
Or you could spend 5 minutes getting a free API key and start building something that actually works.
Get your free OddsPapi API key →
250 requests. 350+ bookmakers. Zero dollars.