Skip to content

Note

Click here to download the full example code

The Odds API

This example shows OddsApi, the paid odds source that carries time-stamped prices.

Nothing here is bought and nothing is downloaded. The example shows how you configure the source and how it handles your key. You want to understand both before you spend anything.

# Author: Georgios Douzas <gdouzas@icloud.com>
# Licence: MIT

import os

import matplotlib.pyplot as plt
import numpy as np

from sportsbet.sources import NBAStats, OddsApi, RawItem

# The source reads the key from the named variable. Set a placeholder, so the example runs without a real key and never
# writes yours into the docs.
os.environ['ODDS_API_KEY'] = 'your-key'

Configuring it

It carries prices with a timestamp. So you can backtest an in-play bet against the odds that were on offer at the minute you would have placed it. The free feeds cannot do that, because they publish the closing price only.

Every market, region and moment is a separate request. Each one adds to the work.

odds = OddsApi(key_env='ODDS_API_KEY', markets=['h2h'], regions=['eu'])
odds.name, odds.kind

Out:

('odds_api', 'odds')

It sells every sport. So it carries no sport of its own and takes the sport of the statistics you pair it with.

{'carries no sport of its own': odds.sport is None}

Out:

{'carries no sport of its own': True}

Your key never reaches the data

The source adds the key to a request at the moment it makes the request. The key is never part of a RawItem, so it is never written to disk.

item = RawItem(source='odds_api', key='snapshot', url='https://api.the-odds-api.com/v4/sports?all=true')
{'key in the item': 'your-key' in item.url}

Out:

{'key in the item': False}
odds.request_url(item)

Out:

'https://api.the-odds-api.com/v4/sports?all=true&apiKey=your-key'

Using it

Pair it with free statistics, here the NBA. Read your key from the environment rather than write it into a file that could be committed:

import os

from sportsbet.dataloaders import DataLoader
from sportsbet.sources import NBAStats, OddsApi

dataloader = DataLoader(
    param_grid={'league': ['NBA'], 'year': [2026]},
    stats=NBAStats(),
    odds=OddsApi(key_env='ODDS_API_KEY', markets=['h2h']),
)
X, Y, O = dataloader.extract_train_data(odds_type='pinnacle')

Extracting is what spends money. Every market, region and moment is its own request, and the vendor sets what those requests cost. Ask the source what it would fetch first, and price it before you commit.

NBAStats().sport, OddsApi(key_env='ODDS_API_KEY').sport

Out:

('basketball', None)

What a price implies

odds_range = np.linspace(1.05, 10, 200)

fig, ax = plt.subplots()
ax.plot(odds_range, 1 / odds_range)
ax.set_title('The probability a price implies')
ax.set_xlabel('decimal odds')
ax.set_ylabel('implied probability')

The probability a price implies

Out:

Text(42.722222222222214, 0.5, 'implied probability')

Total running time of the script: ( 0 minutes 0.060 seconds)

Download Python source code: plot_odds_api.py

Download Jupyter notebook: plot_odds_api.ipynb

Gallery generated by mkdocs-gallery