7. Using APIs for Data Imports #

This chapter starts by using NASDAQ Data Link to download some BTC price and return data. We’ll also see our first set of simulations. I’ll then show you how to use Pandas Data Reader.

This is also our first time using an API. Their API, or Application Programming Interface, let’s us talk to a remote data storage system and pull in what we need. APIs are more general, though, and are used whenever you need one application to talk to another.

We’ll use the NASDAQ Data Link. They also have Python specific instructions.

You can read about the install on their package page.

We can again use pip to install packages via the command line or in your Jupyter notebook.

pip install nasdaq-data-link

To install a package directly in your notebook (e.g. in Google Colabs), use the ! pip convention.

! pip install nasdaq-data-link

When you sign-up for NASDAQ Data Link, you’ll get an API Key. You will need to add this key to the set-up to access the NASDAQ data using Quandl.

I have saved my key locally and am bringing it in with quandl.read_key, so that it isn’t publicly available. You don’t need that bit of code.

You can also install pandas-datareader using pip.

pip install pandas-datareader

Again, add the ! pip if you’re in Google Colab.

Finally, for a large set of APIs for access data, check out Rapid API. Some are free, others you have to pay for. You’ll need to get an access API key for each one. This is a great way to get data for projects!. More on this at the end of these notes.

Let’s do our usual sort of set-up code.

# Set-up

import nasdaqdatalink # You could also do something like: import nasdaqdatalink as ndl
import pandas_datareader as pdr

import numpy as np
import pandas as pd
import datetime as dt

import matplotlib as mpl 

import matplotlib.pyplot as plt

# Include this to have plots show up in your Jupyter notebook.
%matplotlib inline 

# nasdaqdatalink.ApiConfig.api_key = 'YOUR_KEY_HERE'

nasdaqdatalink.read_key()

#nasdaqdatalink.read_key(filepath="/data/.corporatenasdaqdatalinkapikey")
#print(nasdaqdatalink.ApiConfig.api_key)
gdp = nasdaqdatalink.get('FRED/GDP')
gdp
Value
Date
1947-01-01 243.164
1947-04-01 245.968
1947-07-01 249.585
1947-10-01 259.745
1948-01-01 265.742
... ...
2020-10-01 21477.597
2021-01-01 22038.226
2021-04-01 22740.959
2021-07-01 23202.344
2021-10-01 23992.355

300 rows × 1 columns

btc = nasdaqdatalink.get('BCHAIN/MKPRU')
btc.tail()
Value
Date
2024-01-04 42854.95
2024-01-05 44190.10
2024-01-06 44181.10
2024-01-07 43975.63
2024-01-08 43928.07
btc['ret'] = btc.pct_change().dropna()
btc = btc.loc['2015-01-01':,['Value', 'ret']]
btc.plot()
<AxesSubplot:xlabel='Date'>
../_images/7_nasdaq_api_6_1.png

Well, that’s not a very good graph. The returns and price levels are in different units. Let’s use an f print to show and format the average BTC return.

print(f'Average return: {100 * btc.ret.mean():.2f}%')
Average return: 0.22%

Let’s make a cumulative return chart and daily return chart. We can then stack these on top of each other. I’ll use the .sub(1) method to subtract 1 from the cumulative product. You see this a lot in the DataCamps.

btc['ret_g'] = btc.ret.add(1) # gross return
btc['ret_c'] = btc.ret_g.cumprod().sub(1)    # cummulative return
btc
Value ret ret_g ret_c
Date
2015-01-01 316.15 0.001425 1.001425 0.001425
2015-01-02 314.81 -0.004238 0.995762 -0.002819
2015-01-03 270.93 -0.139386 0.860614 -0.141812
2015-01-04 276.80 0.021666 1.021666 -0.123218
2015-01-05 263.17 -0.049241 0.950759 -0.166392
... ... ... ... ...
2024-01-04 42854.95 -0.046799 0.953201 134.745803
2024-01-05 44190.10 0.031155 1.031155 138.974976
2024-01-06 44181.10 -0.000204 0.999796 138.946468
2024-01-07 43975.63 -0.004651 0.995349 138.295629
2024-01-08 43928.07 -0.001082 0.998918 138.144979

3295 rows × 4 columns

We can now make a graph using the fig, axs method. This is good review! Again, notice that semi-colon at the end. This suppresses some annoying output in the Jupyter notebook.

fig, axs = plt.subplots(2, 1, sharex=True, sharey=False, figsize=(10, 6))

axs[0].plot(btc.ret_c, 'g', label = 'BTC Cumulative Return')
axs[1].plot(btc.ret, 'b', label = 'BTC Daily Return')
            
axs[0].set_title('BTC Cumulative Returns')
axs[1].set_title('BTC Daily Returns')

axs[0].legend()
axs[1].legend();
../_images/7_nasdaq_api_12_0.png

I can make the same graph using the .add_subplot() syntax. The method above gives you some more flexibility, since you can give both plots the same x-axis.

fig = plt.figure(figsize=(10, 6))

ax1 = fig.add_subplot(2, 1, 1)
ax1.plot(btc.ret_c, 'g', label = 'BTC Cumulative Return')

ax2 = fig.add_subplot(2, 1, 2)
ax2.plot(btc.ret, 'b', label = 'BTC Daily Return')

ax1.set_title('BTC Cumulative Returns')
ax2.set_title('BTC Daily Returns')

ax1.legend()
ax2.legend()

plt.subplots_adjust(wspace=0.5, hspace=0.5);
../_images/7_nasdaq_api_14_0.png

Let’s put together some ideas, write a function, and run a simulation. We’ll use something called geometric brownian motion (GBM). What is GBM? It is a particular stochastic differential equation. But, what’s important for us is the idea, which is fairly simple. Here’s the formula:

(7.1)#\[\begin{align} dS = \mu S dt + \sigma S dW_t \end{align}\]

This says that the change in the stock price has two components - a drift, or average increase over time, and a shock that it is random at each point in time. The shock is scaled by the standard deviation of returns that you use. So, larger standard deviation, the bigger the shocks can be. This is basically the simplest way that you can model an asset price.

The shocks are what make the price wiggle around around, or else it would just go up over time, based on the drift value that we use.

And, I’ll stress - we aren’t predicting here, so to speak. We are trying to capture some basic reality about how an asset moves and then seeing what is possible in the future. We aren’t making a statement about whether we think an asset is overvalued or undervalued, will go up or down, etc.

You can solve this equation to get the value of the asset at any point in time t. You just need to know the total of all of the shocks at time t.

(7.2)#\[\begin{align} S(t) = S(0) \exp \left(\left(\mu - \frac{1}{2}\sigma^2\right)t + \sigma W(t)\right) \end{align}\]
T = 30 # How long is our simulation? Let's do 31 days (0 to 30 the way Python counts)
N = 30 # number of time points in the prediction time horizon, making this the same as T means that we will simulate daily returns 
S_0 = btc.Value[-1] # initial BTC price
N_SIM = 100      # How many simulations to run?
mu = btc.ret.mean()
sigma = btc.ret.std()

This is the basic syntax for writing a function in Python. We saw this earlier, back when doing “Comp 101”. Remember, in Python, indentation matters!

def simulate_gbm(s_0, mu, sigma, n_sims, T, N):
    dt = T/N # One day
    dW = np.random.normal(scale = np.sqrt(dt), 
        size=(n_sims, N))  # The random part
    W = np.cumsum(dW, axis=1)
    time_step = np.linspace(dt, T, N)
    time_steps = np.broadcast_to(time_step, (n_sims, N))
    S_t = s_0 * np.exp((mu - 0.5 * sigma ** 2) * time_steps + sigma * np.sqrt(time_steps) * W)
    S_t = np.insert(S_t, 0, s_0, axis=1)
    return S_t

Nothing happens when we define a function. We’ve just created something called simulate_gbm that we can now use just like any other Python function.

We can look at each piece of the function code, with some numbers hard-coded, to get a sense of what’s going on. This gets tricky - keep track of the dimensions. I think that’s the hardest part. How many numbers are we creating in each array? What do they mean?

# Creates 100 rows of 30 random numbers from the standard normal distribution.
dW = np.random.normal(scale = np.sqrt(1), 
        size=(100, 30))

# cumulative sum along each row
W = np.cumsum(dW, axis=1) 

# Array with numbers from 1 to 30
time_step = np.linspace(1, 30, 30)

# Expands that to be 100 rows of numbers from 1 to 30. This is going to be the t in the formula above. So, for the price on the 30th day, we have t=30.
time_steps = np.broadcast_to(time_step, (100, 30))

# This is the formula from above to find the value of the asset any any point in time t. np.exp is the natural number e. W is the cumulative sum of all of our random shocks.
S_t = S_0 * np.exp((mu - 0.5 * sigma ** 2) * time_steps + sigma * np.sqrt(time_steps) * W)

# This inserts the initial price at the start of each row.
S_t = np.insert(S_t, 0, S_0, axis=1)

We can look at these individually, too.

dW
array([[-5.34806895e-01,  6.26811104e-01, -2.55951226e-01, ...,
         1.00737530e+00,  5.78126790e-01,  3.88150560e-01],
       [ 5.99873560e-01,  6.39561247e-02,  2.14466737e+00, ...,
        -5.38069263e-01, -8.58050801e-01, -5.16026856e-01],
       [ 1.51657474e+00,  1.24924862e+00, -6.52424136e-01, ...,
         1.86145843e-01, -7.61330775e-01,  1.72615783e+00],
       ...,
       [-5.47916337e-01,  8.63074955e-01,  2.48968864e-02, ...,
        -9.00298605e-01, -1.60692342e+00,  1.61836970e+00],
       [-3.78820915e-02,  5.76213842e-02, -8.58066629e-01, ...,
        -2.21380687e-01, -4.67827145e-01,  1.21468252e+00],
       [ 1.07314421e+00, -2.75410825e-01,  2.37539507e-01, ...,
        -5.58011413e-01, -1.38785865e+00, -1.02008786e-03]])
time_steps
array([[ 1.,  2.,  3., ..., 28., 29., 30.],
       [ 1.,  2.,  3., ..., 28., 29., 30.],
       [ 1.,  2.,  3., ..., 28., 29., 30.],
       ...,
       [ 1.,  2.,  3., ..., 28., 29., 30.],
       [ 1.,  2.,  3., ..., 28., 29., 30.],
       [ 1.,  2.,  3., ..., 28., 29., 30.]])
len(time_steps)
100
np.shape(time_steps)
(100, 30)

I do this kind of step-by-step break down all of the time. It’s the only way I can understand what’s going on.

We can then use our function. This returns an narray.

gbm_simulations = simulate_gbm(S_0, mu, sigma, N_SIM, T, N)

And, we can plot all of the simulations. I’m going to use pandas to plot, save to ax, and the style the ax.

gbm_simulations_df = pd.DataFrame(np.transpose(gbm_simulations))

# plotting
ax = gbm_simulations_df.plot(alpha=0.2, legend=False)

ax.set_title('BTC Simulations', fontsize=16);
../_images/7_nasdaq_api_29_0.png

The y-axis has a very wide range, since some extreme values are possible, given this simulation.

7.1. Using pandas-datareader and yfinance#

The pandas data-reader API lets us access additional data sources, such as FRED.

There are also API that let you access the same data. For example, Yahoo! Finance has several, like yfinance. I think that the Yahoo! Finance access for pandas-datareader was broken in a recent update. See my comments below.

Lots of developers have written APIs to access different data sources.

Note

Different data sources might require API keys. Sometimes you have to pay. Always read the documentation.

Here’s another FRED example, but using pandas-datareader.

start = dt.datetime(2010, 1, 1)

end = dt.datetime(2013, 1, 27)

gdp = pdr.DataReader('GDP', 'fred', start, end)

gdp.head
<bound method NDFrame.head of                   GDP
DATE                 
2010-01-01  14764.610
2010-04-01  14980.193
2010-07-01  15141.607
2010-10-01  15309.474
2011-01-01  15351.448
2011-04-01  15557.539
2011-07-01  15647.680
2011-10-01  15842.259
2012-01-01  16068.805
2012-04-01  16207.115
2012-07-01  16319.541
2012-10-01  16420.419
2013-01-01  16648.189>

As mentioned, the pandas data-reader and yfinance APIs let you pull stock data from Yahoo! Finance. However, Yahoo! Finance keeps breaking what you need to scrape the data, so these packages can sometimes be unreliable. However, we can get aspects of them to work.

Here’s some basic set-up that gets yfinance working.

# The usual type of set-up.
import pandas as pd
import numpy as np
import bt as bt
import ffn as ffn

# This will get our plots to automatically show up.
%matplotlib inline

# As of Dec 2022, looks like yfinance broke the ffn/bt data import. Add this to get it to work. See https://github.com/pmorissette/ffn/issues/185
import yfinance as yf
yf.pdr_override()

I’ll do the example from the yfinance webpage. This brings in information on MSFT as a yfinance ticker object. It looks like a JSON file to me. See below for more on JSON as a storage type.

msft = yf.Ticker("MSFT")

# get all stock info
msft.info
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
Input In [21], in <cell line: 4>()
      1 msft = yf.Ticker("MSFT")
      3 # get all stock info
----> 4 msft.info

File /opt/anaconda3/lib/python3.9/site-packages/yfinance/ticker.py:138, in Ticker.info(self)
    136 @property
    137 def info(self) -> dict:
--> 138     return self.get_info()

File /opt/anaconda3/lib/python3.9/site-packages/yfinance/base.py:1020, in TickerBase.get_info(self, proxy)
   1018 def get_info(self, proxy=None) -> dict:
   1019     self._quote.proxy = proxy
-> 1020     data = self._quote.info
   1021     return data

File /opt/anaconda3/lib/python3.9/site-packages/yfinance/scrapers/quote.py:555, in Quote.info(self)
    551 @property
    552 def info(self) -> dict:
    553     if self._info is None:
    554         # self._scrape(self.proxy)  # decrypt broken
--> 555         self._fetch(self.proxy)
    557         self._fetch_complementary(self.proxy)
    559     return self._info

File /opt/anaconda3/lib/python3.9/site-packages/yfinance/scrapers/quote.py:706, in Quote._fetch(self, proxy)
    703 self._already_fetched = True
    704 modules = ['summaryProfile', 'financialData', 'quoteType',
    705              'defaultKeyStatistics', 'assetProfile', 'summaryDetail']
--> 706 result = self._data.get_raw_json(
    707     _BASIC_URL_ + f"/{self._data.ticker}", params={"modules": ",".join(modules), "ssl": "true"}, proxy=proxy
    708 )
    709 result["quoteSummary"]["result"][0]["symbol"] = self._data.ticker
    710 query1_info = next(
    711     (info for info in result.get("quoteSummary", {}).get("result", []) if info["symbol"] == self._data.ticker),
    712     None,
    713 )

File /opt/anaconda3/lib/python3.9/site-packages/yfinance/data.py:209, in TickerData.get_raw_json(self, url, user_agent_headers, params, proxy, timeout)
    207 def get_raw_json(self, url, user_agent_headers=None, params=None, proxy=None, timeout=30):
    208     response = self.get(url, user_agent_headers=user_agent_headers, params=params, proxy=proxy, timeout=timeout)
--> 209     response.raise_for_status()
    210     return response.json()

File /opt/anaconda3/lib/python3.9/site-packages/requests/models.py:1021, in Response.raise_for_status(self)
   1016     http_error_msg = (
   1017         f"{self.status_code} Server Error: {reason} for url: {self.url}"
   1018     )
   1020 if http_error_msg:
-> 1021     raise HTTPError(http_error_msg, response=self)

HTTPError: 401 Client Error: Unauthorized for url: https://query2.finance.yahoo.com/v10/finance/quoteSummary/MSFT?modules=summaryProfile%2CfinancialData%2CquoteType%2CdefaultKeyStatistics%2CassetProfile%2CsummaryDetail&ssl=true

In VS Code, you can open the rest of that in a text editor (see the message) and look at every variable in there. You can pull specific information out this object.

# Get the sector.
msft.info['sector']
'Technology'

Here’s something a bit more complex. I’ll pull the first company officer. Note the indexing, starting at 0, the usual Python way.

msft.info['companyOfficers'][0]
{'maxAge': 1,
 'name': 'Mr. Satya  Nadella',
 'age': 55,
 'title': 'Chairman & CEO',
 'yearBorn': 1967,
 'fiscalYear': 2022,
 'totalPay': 12676750,
 'exercisedValue': 0,
 'unexercisedValue': 0}

You can drill down even more. Honestly, I was guessing a bit at how to access this data. This just seemed like a “Python” or “JSON” way to do it and it worked.

msft.info['companyOfficers'][0]['totalPay']
12676750

They have recent accounting data, too.

msft.info['grossMargins']
0.68522

Here’s two years of price, volume, dividend, and split data. Remember when we looked at return calculations? You need the dividends if you’re going to accurately calculate returns. You also need the stock splits, or you’ll be comparing prices pre- and post- splits, getting funky returns!

hist = msft.history(period="2y")
hist
Open High Low Close Volume Dividends Stock Splits
Date
2021-05-03 00:00:00-04:00 248.910705 249.843887 246.671100 247.397995 19626600 0.0 0.0
2021-05-04 00:00:00-04:00 246.523756 246.759509 241.406051 243.400085 32756100 0.0 0.0
2021-05-05 00:00:00-04:00 244.647597 245.079804 241.465007 242.103485 21901300 0.0 0.0
2021-05-06 00:00:00-04:00 242.083851 245.433442 240.355036 245.305740 26491100 0.0 0.0
2021-05-07 00:00:00-04:00 247.682876 249.794795 246.720242 247.987396 27032900 0.0 0.0
... ... ... ... ... ... ... ...
2023-04-26 00:00:00-04:00 296.700012 299.570007 292.730011 295.369995 64599200 0.0 0.0
2023-04-27 00:00:00-04:00 295.970001 305.200012 295.250000 304.829987 46462600 0.0 0.0
2023-04-28 00:00:00-04:00 304.010010 308.929993 303.309998 307.260010 36446700 0.0 0.0
2023-05-01 00:00:00-04:00 306.970001 308.600006 305.149994 305.559998 21294100 0.0 0.0
2023-05-02 00:00:00-04:00 307.760010 309.165009 303.910004 305.410004 26404431 0.0 0.0

504 rows × 7 columns

As noted on their webpage, you can pull multiple stocks, by ticker, at once.

tickers = yf.Tickers('msft aapl goog')

tickers.tickers['AAPL'].history(period="1mo")
Open High Low Close Volume Dividends Stock Splits
Date
2023-04-03 00:00:00-04:00 164.270004 166.289993 164.220001 166.169998 56976200 0.0 0.0
2023-04-04 00:00:00-04:00 166.600006 166.839996 165.110001 165.630005 46278300 0.0 0.0
2023-04-05 00:00:00-04:00 164.740005 165.050003 161.800003 163.759995 51511700 0.0 0.0
2023-04-06 00:00:00-04:00 162.429993 164.960007 162.000000 164.660004 45390100 0.0 0.0
2023-04-10 00:00:00-04:00 161.419998 162.029999 160.080002 162.029999 47716900 0.0 0.0
2023-04-11 00:00:00-04:00 162.350006 162.360001 160.509995 160.800003 47644200 0.0 0.0
2023-04-12 00:00:00-04:00 161.220001 162.059998 159.779999 160.100006 50133100 0.0 0.0
2023-04-13 00:00:00-04:00 161.630005 165.800003 161.419998 165.559998 68445600 0.0 0.0
2023-04-14 00:00:00-04:00 164.589996 166.320007 163.820007 165.210007 49337200 0.0 0.0
2023-04-17 00:00:00-04:00 165.089996 165.389999 164.029999 165.229996 41516200 0.0 0.0
2023-04-18 00:00:00-04:00 166.100006 167.410004 165.649994 166.470001 49923000 0.0 0.0
2023-04-19 00:00:00-04:00 165.800003 168.160004 165.539993 167.630005 47720200 0.0 0.0
2023-04-20 00:00:00-04:00 166.089996 167.869995 165.559998 166.649994 52456400 0.0 0.0
2023-04-21 00:00:00-04:00 165.050003 166.449997 164.490005 165.020004 58311900 0.0 0.0
2023-04-24 00:00:00-04:00 165.000000 165.600006 163.889999 165.330002 41949600 0.0 0.0
2023-04-25 00:00:00-04:00 165.190002 166.309998 163.729996 163.770004 48714100 0.0 0.0
2023-04-26 00:00:00-04:00 163.059998 165.279999 162.800003 163.759995 45498800 0.0 0.0
2023-04-27 00:00:00-04:00 165.190002 168.559998 165.190002 168.410004 64902300 0.0 0.0
2023-04-28 00:00:00-04:00 168.490005 169.850006 167.880005 169.679993 55209200 0.0 0.0
2023-05-01 00:00:00-04:00 169.279999 170.449997 168.639999 169.589996 52472900 0.0 0.0
2023-05-02 00:00:00-04:00 170.089996 170.350006 167.539993 168.539993 48425696 0.0 0.0

I wasn’t able to figure out how to get historical financial statement data out of yfinance. I would suggest using our Bloomberg terminals or Factset to do that. Easy enough to just pull historical data, by ticker, into Excel or a CSV file from those data sources. You can then import that into Python to use as part of a trading signal or just to do some basic comparisons and graphs.

7.2. Data Details - Using APIs#

This notes above use the NASDAQ Datalink API to pull some BTC data. Now, I’ll discuss using this API more generally, as well as using Rapid API, another website with a variety of data options. I’ll also show you an API from Github.

As mentioned above, APIs are ways for one program or piece of software to talk to another. In our case, we’re using them to get data. That data might come in as a pandas DataFrame, ready to use. Other times, it might come in as something called a JSON file. We’ll have to do a bit more work with this common data structure.

7.2.1. NASDAQ API - Another Example#

Let’s look at the NASDAQ API one more time. Once you log in, you’ll see the home page below. Note the strip across the upper-left, that has API, Python, Excel, etc. You can use the NASDAQ API in a variety of settings. There’s a SEARCH FOR DATA box at the top.

../_images/07-nasdaq-home.png

Fig. 7.1 NASDAQ API homepage.#

If you click EXPLORE next to the search box, you’re taken to a list of all of their data. Much of it is premium - you have to pay. However, you can filter for free data. There’s free data for house prices, gold and silver markets, IMF macro data, the Fed, etc. Much of this free data comes from Quandl, which was purchased by Nasdaq recently.

Quandl has been completely integrated by NASDAQ now, though you will see legacy instructions on the website that refer to its older API commands.

../_images/07-nasdaq-explore.png

Fig. 7.2 Exploring NASDAQ data options.#

Let’s look at the Zillow data, the first option presented when I look for free data. I’ve used them in labs and exams.

../_images/07-nasdaq-zillow.png

Fig. 7.3 NASDAQ has an API for Zillow housing data.#

Each the data APIs shows you samples of what you can access. So, we see an example table with data for a particular indicator and region. We also see a table that has a list of all of the indicators and what they measure. Finally, we see a table with all of the regions and what they represent.

This data structure makes it clear that we can download value data and then merge in ID and region descriptions if needed. But, how do we do that? See the tab in the upper-left, with DATA highlighted? You can click on DOCUMENTATION and USAGE to learn more. We’ll look at a quick example here.

Click USAGE and then the Python icon. You’ll seen an example that lets you filter by a single indicator_id and region. It has your API key and the .get_table method.

However, note the quandl stuff. They haven’t transitioned this code yet. You’ll need to do a pip install for quandl.

Also, we didn’t use .get_table above for BTC. The Zillow data is stored differently.

Make sure that you include your API key. You can input it directly, using the code that they provide. I’m using a different way to do the key that doesn’t require me to type my API key into this publicly available code.

#! pip install quandl

# Bring in quandl for downloading data
import quandl
# quandl.ApiConfig.api_key = 'YOUR_KEY_HERE'
quandl.read_key()

You need that paginate=True in there in order to download all of the available data. Without it, it will only pull the first 10,000 rows. Using paginate extends the limit to 1,000,000 rows, or observations. Now, note that this could be a lot of data! You might need to download the data in chunks to get what you want.

Let’s try pulling in the indicator_id ZATT for all regions.

# zillow = quandl.get_table('ZILLOW/DATA', indicator_id = 'ZATT', paginate=True)

I’ve commented out the code above, because I know it will exceed the download limit! So, we need to be more selective.

If you look on the NASDAQ Zillow documentation page, you’ll see the three tables that you can download, the variables inside of each, and what you’re allowed to filter on. You unfortunately can’t filter on date in the ZILLOW/DATA table. Other data sets, like FRED, do let you specify start and end dates. Every API is different.

You can find examples of how to filter and sub-select your data on the NASDAQ website: https://docs.data.nasdaq.com/docs/python-tables

However, you can filter on region_id. Let’s pull the ZILLOW/REGIONS table to see what we can use.

regions = quandl.get_table('ZILLOW/REGIONS', paginate=True)
regions
region_id region_type region
None
0 99999 zip 98847; WA; Wenatchee, WA; Chelan County; Pesha...
1 99998 zip 98846; WA; Okanogan County; Pateros
2 99997 zip 98845; WA; Wenatchee; Douglas County; Palisades
3 99996 zip 98844; WA; Okanogan County; Oroville
4 99995 zip 98843; WA; Wenatchee, WA; Douglas County; Orondo
... ... ... ...
89300 100000 zip 98848; WA; Moses Lake, WA; Grant County; Quincy
89301 10000 city Bloomington; MD; Garrett County
89302 1000 county Echols County; GA; Valdosta, GA
89303 100 county Bibb County; AL; Birmingham-Hoover, AL
89304 10 state Colorado

89305 rows × 3 columns

What if we just want cities?

cities = regions[regions.region_type == 'city']
cities
region_id region_type region
None
10 9999 city Carrsville; VA; Virginia Beach-Norfolk-Newport...
20 9998 city Birchleaf; VA; Dickenson County
56 9994 city Wright; KS; Dodge City, KS; Ford County
124 9987 city Weston; CT; Bridgeport-Stamford-Norwalk, CT; F...
168 9980 city South Wilmington; IL; Chicago-Naperville-Elgin...
... ... ... ...
89203 10010 city Atwood; KS; Rawlins County
89224 10008 city Bound Brook; NJ; New York-Newark-Jersey City, ...
89254 10005 city Chanute; KS; Neosho County
89290 10001 city Blountsville; AL; Birmingham-Hoover, AL; Bloun...
89301 10000 city Bloomington; MD; Garrett County

28131 rows × 3 columns

cities.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 28131 entries, 10 to 89301
Data columns (total 3 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   region_id    28131 non-null  object
 1   region_type  28131 non-null  object
 2   region       28131 non-null  object
dtypes: object(3)
memory usage: 879.1+ KB

I like to look and see what things are stored as, too. Remember, the object type is very generic.

There are 28,131 rows of cities! How about counties?

counties = regions[regions.region_type == 'county']
counties
region_id region_type region
None
94 999 county Durham County; NC; Durham-Chapel Hill, NC
169 998 county Duplin County; NC
246 997 county Dubois County; IN; Jasper, IN
401 995 county Donley County; TX
589 993 county Dimmit County; TX
... ... ... ...
89069 1003 county Elmore County; AL; Montgomery, AL
89120 1002 county Elbert County; GA
89204 1001 county Elbert County; CO; Denver-Aurora-Lakewood, CO
89302 1000 county Echols County; GA; Valdosta, GA
89303 100 county Bibb County; AL; Birmingham-Hoover, AL

3097 rows × 3 columns

Can’t find the regions you want? You could export the whole thing to a CSV file and explore it in Excel. This will show up in whatever folder you currently have as your home in VS Code.

counties.to_csv('counties.csv', index = True)

You can also open up the Variables window at the top of VS Code (or the equivalent in Google Colab) and scroll through the file, looking for the region_id values that you want.

Finally, you can search the text in a column directly. Let’s find counties in NC.

nc_counties = counties[counties['region'].str.contains("; NC")]
nc_counties
region_id region_type region
None
94 999 county Durham County; NC; Durham-Chapel Hill, NC
169 998 county Duplin County; NC
2683 962 county Craven County; NC; New Bern, NC
4637 935 county Chowan County; NC
4972 93 county Ashe County; NC
... ... ... ...
87475 1180 county Martin County; NC
87821 1147 county Lenoir County; NC; Kinston, NC
88578 1059 county Greene County; NC
88670 1049 county Graham County; NC
88823 1032 county Gaston County; NC; Charlotte-Concord-Gastonia,...

100 rows × 3 columns

nc_counties.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 94 to 88823
Data columns (total 3 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   region_id    100 non-null    object
 1   region_type  100 non-null    object
 2   region       100 non-null    object
dtypes: object(3)
memory usage: 3.1+ KB

There are 100 counties in NC, so this worked. Now, we can save these regions to a list and use that to pull data.

By exploring the data like this, you can maybe find the region_id values that you want and give them as a list. I’m also going to use the qopts = option to name the columns that I want to pull. This isn’t necessary here, since I want all of the columns, but I wanted to show you that you could do this.

nc_county_list = nc_counties['region_id'].to_list()
zillow_nc = quandl.get_table('ZILLOW/DATA', indicator_id = 'ZATT', paginate = True, region_id = nc_county_list,  qopts = {'columns': ['indicator_id', 'region_id', 'date', 'value']})
zillow_nc.head(25)
indicator_id region_id date value
None
0 ZATT 999 2023-03-31 541442.450359
1 ZATT 999 2023-02-28 542934.945251
2 ZATT 999 2023-01-31 546725.963769
3 ZATT 999 2022-12-31 539928.263825
4 ZATT 999 2022-11-30 542585.370376
5 ZATT 999 2022-10-31 598375.000000
6 ZATT 999 2022-09-30 601490.000000
7 ZATT 999 2022-08-31 606467.000000
8 ZATT 999 2022-07-31 607902.000000
9 ZATT 999 2022-06-30 608465.000000
10 ZATT 999 2022-05-31 597607.000000
11 ZATT 999 2022-04-30 585235.000000
12 ZATT 999 2022-03-31 572754.000000
13 ZATT 999 2022-02-28 556641.000000
14 ZATT 999 2022-01-31 538430.000000
15 ZATT 999 2021-12-31 516010.000000
16 ZATT 999 2021-11-30 506505.000000
17 ZATT 999 2021-10-31 498382.000000
18 ZATT 999 2021-09-30 486909.000000
19 ZATT 999 2021-08-31 475100.000000
20 ZATT 999 2021-07-31 469689.000000
21 ZATT 999 2021-06-30 456018.000000
22 ZATT 999 2021-05-31 443594.000000
23 ZATT 999 2021-04-30 435319.000000
24 ZATT 999 2021-03-31 427213.000000

Hey, there’s Durham County!

zillow_nc.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 26510 entries, 0 to 26509
Data columns (total 4 columns):
 #   Column        Non-Null Count  Dtype         
---  ------        --------------  -----         
 0   indicator_id  26510 non-null  object        
 1   region_id     26510 non-null  object        
 2   date          26510 non-null  datetime64[ns]
 3   value         26510 non-null  float64       
dtypes: datetime64[ns](1), float64(1), object(2)
memory usage: 828.6+ KB

Now you can filter by date if you like. And, you could pull down multiple states this way, change the variable type, etc. You could also merge in the region names using region_id as your key.

7.2.2. Using Rapid API#

Another data option is Rapid API. There’s all types of data here - markets, sports, gambling, housing, etc. People will write their own APIs, perhaps interfacing with the websites that contain the information. They can then publish their APIs on this webpage. Many have free options, some you have to pay for. There are thousands here, so you’ll have to dig around.

../_images/07-rapidapi.png

Fig. 7.4 Main Rapid API webpage#

One you have an account, you’ll be able to subscribe to different APIs. You probably want the data to have a free option.

The quick start guide is here.

Luckily, all of the APIs here tend to have the same structures. These are called REST APIs. This stands for “Representational State Transfer” and is just a standardized way for computers to talk to each other. They are going to use a standard data format, like JSON. More on this below.

You can read more on their API Learn page.

We’ll look at one example, Pinnacle Odds, which has some sports gambling information: https://rapidapi.com/tipsters/api/pinnacle-odds/

Once you’ve subscribed, you see the main endpoint screen.

../_images/07-rapidapi-endpoint.png

Fig. 7.5 Pinnacle Odds endpoint page. I’ve blocked my API key with two different windows.#

At the top, you’ll see Endpoints, About, Tutorials, Discussions, and Pricing. Click around to read more about the API.

We are currently on Endpoints. Endpoints are basically like URLs. They are where different tables of data live. We are going to use this page to figure out the data that we need. And, the webpage page will also create the Python code needed to download the data!

You can start on the left of the screen. You’ll see a list of the different tables available. I’ll try List of Sports in this example. You’ll see why in a minute.

You’ll note that the middle section now changed. This is where you can filter and ask for particular types of data from that table. In this case, there are no options to change.

On the right, you’ll see Code Snippets. The default is Node.js, a type of Javascript. We don’t want that. Click the dropdown box and look for Python. They have three ways, using three different packages, to interface with the API from Python and download the data. I’ll pick Requests - it seemed to work below.

This will change the code. You’ll see the package import, your API key, the host, and the data request. You can click Copy Code.

But, before we run this on our end, let’s click Test Endpoint. That’s the blue box in the middle. Then, click Results on the left and Body. By doing this, we essentially just ran that code in the browser. We can see what data we’re going to get. This is a JSON file with 9 items. Each item has 6 keys. You can see what the keys are - they are giving us the ids for each sport. For example, “Soccer” is “id = 1”.

This is very helpful! We need to know these id values if we want to pull particular sports.

For fun, let’s pull this simple JSON file on our end. I’ve copied and pasted the code below. It didn’t like the print function, so I just dropped it. I am again loading in my API key from an separate file. You’ll use your own.

import requests
from dotenv import load_dotenv # For my .env file which contains my API keys locally
import os # For my .env file which contains my API keys locally

load_dotenv() # For my .env file which contains my API keys locally
RAPID_API_KEY = os.getenv('RAPID_API_KEY')

url = "https://pinnacle-odds.p.rapidapi.com/kit/v1/sports"

headers = {
	"X-RapidAPI-Key": RAPID_API_KEY,
	"X-RapidAPI-Host": "pinnacle-odds.p.rapidapi.com"
}

sports_ids = requests.request("GET", url, headers=headers)

print(sports_ids.text)
[{"id":1,"p_id":29,"name":"Soccer","last":1681571699,"special_last":1681571658,"last_call":1681571702},{"id":2,"p_id":33,"name":"Tennis","last":1681571703,"special_last":1681556172,"last_call":1681571705},{"id":3,"p_id":4,"name":"Basketball","last":1681571705,"special_last":1681571632,"last_call":1681571706},{"id":4,"p_id":19,"name":"Hockey","last":1681571474,"special_last":1681568468,"last_call":1681571707},{"id":5,"p_id":34,"name":"Volleyball","last":1681571707,"last_call":1681571709},{"id":6,"p_id":18,"name":"Handball","last":1681571709,"last_call":1681571710},{"id":7,"p_id":15,"name":"American Football","last":1681571125,"special_last":1681520390,"last_call":1681571711},{"id":8,"p_id":22,"name":"Mixed Martial Arts","last":1681571386,"special_last":1681571395,"last_call":1681571697},{"id":9,"p_id":3,"name":"Baseball","last":1681571697,"special_last":1681571666,"last_call":1681571698}]

We can turn that response file into a JSON file. This is what it wants to be!

All of the code that follows is also commented out so that it doesn’t run every time I edit this online book. The output from the code is still there, however.

sports_ids_json = sports_ids.json()
sports_ids_json
[{'id': 1,
  'p_id': 29,
  'name': 'Soccer',
  'last': 1681571699,
  'special_last': 1681571658,
  'last_call': 1681571702},
 {'id': 2,
  'p_id': 33,
  'name': 'Tennis',
  'last': 1681571703,
  'special_last': 1681556172,
  'last_call': 1681571705},
 {'id': 3,
  'p_id': 4,
  'name': 'Basketball',
  'last': 1681571705,
  'special_last': 1681571632,
  'last_call': 1681571706},
 {'id': 4,
  'p_id': 19,
  'name': 'Hockey',
  'last': 1681571474,
  'special_last': 1681568468,
  'last_call': 1681571707},
 {'id': 5,
  'p_id': 34,
  'name': 'Volleyball',
  'last': 1681571707,
  'last_call': 1681571709},
 {'id': 6,
  'p_id': 18,
  'name': 'Handball',
  'last': 1681571709,
  'last_call': 1681571710},
 {'id': 7,
  'p_id': 15,
  'name': 'American Football',
  'last': 1681571125,
  'special_last': 1681520390,
  'last_call': 1681571711},
 {'id': 8,
  'p_id': 22,
  'name': 'Mixed Martial Arts',
  'last': 1681571386,
  'special_last': 1681571395,
  'last_call': 1681571697},
 {'id': 9,
  'p_id': 3,
  'name': 'Baseball',
  'last': 1681571697,
  'special_last': 1681571666,
  'last_call': 1681571698}]

That’s JSON. I was able to show the whole thing in the notebook.

Let’s get that into a pandas DataFrame now. To do that, we have to know a bit about how JSON files are structured. This one is easy. pd.json_normalize is a useful tool here.

sports_ids_df = pd.json_normalize(data = sports_ids_json)
sports_ids_df
id p_id name last special_last last_call
0 1 29 Soccer 1681571699 1.681572e+09 1681571702
1 2 33 Tennis 1681571703 1.681556e+09 1681571705
2 3 4 Basketball 1681571705 1.681572e+09 1681571706
3 4 19 Hockey 1681571474 1.681568e+09 1681571707
4 5 34 Volleyball 1681571707 NaN 1681571709
5 6 18 Handball 1681571709 NaN 1681571710
6 7 15 American Football 1681571125 1.681520e+09 1681571711
7 8 22 Mixed Martial Arts 1681571386 1.681571e+09 1681571697
8 9 3 Baseball 1681571697 1.681572e+09 1681571698

What do all of those columns mean? I don’t know! You’d want to read the documentation for your API.

Also, note how I’m changing the names of my objects as I go. I want to keep each data structure in memory - what I originally downloaded, the JSON file, the DataFrame. This way, I don’t overwrite anything and I won’t be forced to download the data all over again.

Now, let’s see if we can pull some actual data. I notice that id = 3 is Basketball. Cool. Let’s try for some NBA data. Go back to the left of the Endpoint page and click on List of archive events. The middle will change and you’ll have some required and optional inputs. I know I want sport_id to be 3. But I don’t want all basketball. Just the NBA. So, I notice the league_ids option below. But I don’t know the number of the NBA.

OK, back to the left side. See List of leagues? Click that. I put in sport_id = 3. I then click Test Endpoint. I go to Results, select Body, and then Expand All. I do a CTRL-F to look for “NBA”.

And I find a bunch of possibilities! NBA games. Summer League. D-League. Summer League! If you’re betting on NBA Summer League, please seek help. Let’s use the regular NBA. That’s league_id = 487.

Back to List of archive events. I’ll add that league ID to the bottom of the middle. I set the page_num to 1000. I then click Test Endpoint and look at what I get.

Nothing! That’s an empty looking file on the right. Maybe this API doesn’t keep archived NBA? Who knows.

Let’s try another endpoint. Click on List of markets. Let’s see what this one has. In the middle, I’ll again use the codes for basketball and the NBA. I’ll set is_have_odds to True. Let’s test the endpoint and see what we get.

../_images/07-rapidapi-nba.png

Fig. 7.6 Some NBA odds for this weekend.#

We can expand the result and look at the data structure. This is a more complicated one. I see 8 items under events. These correspond to the 8 games this weekend. Then, under each event, you can keep drilling down. The level 0 is kind of like the header for that event. It has the game, the start time, the teams, etc. You’ll see 4 more keys under periods. Each of these is a different betting line, with money lines, spreads, what I think are over/under point totals, etc.

Anyway, the main thing here is that we have indeed pulled some rather complex looking data. That data is current for upcoming games, not historical. But, we can still pull this in and use it to see how to work with a more complex JSON structure.

I’ll copy and paste the code again.

import requests

url = "https://pinnacle-odds.p.rapidapi.com/kit/v1/markets"

querystring = {"sport_id":"3","league_ids":"487","is_have_odds":"true"}

headers = {
	"X-RapidAPI-Key": RAPID_API_KEY,
	"X-RapidAPI-Host": "pinnacle-odds.p.rapidapi.com"
}

current = requests.request("GET", url, headers=headers, params=querystring)

print(current.text)
{"sport_id":3,"sport_name":"Basketball","last":1681571705,"last_call":1681571706,"events":[{"event_id":1570671674,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-15T17:10:00","last":1681571077,"home":"Philadelphia 76ers","away":"Brooklyn Nets","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2067360473,"number":0,"cutoff":"2023-04-15T17:10:00Z","period_status":1,"money_line":{"home":1.263,"draw":null,"away":4.18},"spreads":{"-8.5":{"hdp":-8.5,"home":1.909,"away":2.0,"max":25000.0},"-6.0":{"hdp":-6.0,"home":1.588,"away":2.48,"max":25000.0},"-6.5":{"hdp":-6.5,"home":1.636,"away":2.37,"max":25000.0},"-7.0":{"hdp":-7.0,"home":1.684,"away":2.28,"max":25000.0},"-7.5":{"hdp":-7.5,"home":1.746,"away":2.19,"max":25000.0},"-8.0":{"hdp":-8.0,"home":1.819,"away":2.09,"max":25000.0},"-9.0":{"hdp":-9.0,"home":1.99,"away":1.9,"max":25000.0},"-9.5":{"hdp":-9.5,"home":2.08,"away":1.826,"max":25000.0},"-10.0":{"hdp":-10.0,"home":2.16,"away":1.757,"max":25000.0},"-10.5":{"hdp":-10.5,"home":2.25,"away":1.704,"max":25000.0},"-11.0":{"hdp":-11.0,"home":2.34,"away":1.653,"max":25000.0}},"totals":{"213.5":{"points":213.5,"over":1.862,"under":2.03,"max":5000.0},"211.0":{"points":211.0,"over":1.632,"under":2.35,"max":5000.0},"211.5":{"points":211.5,"over":1.68,"under":2.27,"max":5000.0},"212.0":{"points":212.0,"over":1.714,"under":2.21,"max":5000.0},"212.5":{"points":212.5,"over":1.763,"under":2.15,"max":5000.0},"213.0":{"points":213.0,"over":1.806,"under":2.09,"max":5000.0},"214.0":{"points":214.0,"over":1.9,"under":1.98,"max":5000.0},"214.5":{"points":214.5,"over":1.952,"under":1.925,"max":5000.0},"215.0":{"points":215.0,"over":2.01,"under":1.869,"max":5000.0},"215.5":{"points":215.5,"over":2.06,"under":1.826,"max":5000.0},"216.0":{"points":216.0,"over":2.11,"under":1.775,"max":5000.0}},"team_total":{"home":{"points":111.5,"over":1.909,"under":1.943},"away":{"points":102.5,"over":1.869,"under":1.98}},"meta":{"number":0,"max_spread":25000.0,"max_money_line":15000.0,"max_total":5000.0,"max_team_total":2000.0}},"num_1":{"line_id":2067360475,"number":1,"cutoff":"2023-04-15T17:10:00Z","period_status":1,"money_line":{"home":1.363,"draw":null,"away":3.32},"spreads":{"-5.0":{"hdp":-5.0,"home":1.909,"away":1.97,"max":6500.0},"-3.0":{"hdp":-3.0,"home":1.649,"away":2.32,"max":6500.0},"-3.5":{"hdp":-3.5,"home":1.699,"away":2.23,"max":6500.0},"-4.0":{"hdp":-4.0,"home":1.763,"away":2.14,"max":6500.0},"-4.5":{"hdp":-4.5,"home":1.833,"away":2.06,"max":6500.0},"-5.5":{"hdp":-5.5,"home":1.99,"away":1.892,"max":6500.0},"-6.0":{"hdp":-6.0,"home":2.07,"away":1.819,"max":6500.0},"-6.5":{"hdp":-6.5,"home":2.15,"away":1.751,"max":6500.0},"-7.0":{"hdp":-7.0,"home":2.24,"away":1.694,"max":6500.0}},"totals":{"109.0":{"points":109.0,"over":1.9,"under":1.99,"max":2000.0},"107.0":{"points":107.0,"over":1.675,"under":2.28,"max":2000.0},"107.5":{"points":107.5,"over":1.735,"under":2.19,"max":2000.0},"108.0":{"points":108.0,"over":1.781,"under":2.12,"max":2000.0},"108.5":{"points":108.5,"over":1.84,"under":2.05,"max":2000.0},"109.5":{"points":109.5,"over":1.952,"under":1.917,"max":2000.0},"110.0":{"points":110.0,"over":2.02,"under":1.862,"max":2000.0},"110.5":{"points":110.5,"over":2.08,"under":1.806,"max":2000.0},"111.0":{"points":111.0,"over":2.16,"under":1.746,"max":2000.0}},"team_total":{"home":{"points":57.5,"over":1.943,"under":1.909},"away":{"points":52.5,"over":2.01,"under":1.854}},"meta":{"number":1,"max_spread":6500.0,"max_money_line":3500.0,"max_total":2000.0,"max_team_total":1000.0}},"num_3":{"line_id":2067360478,"number":3,"cutoff":"2023-04-15T17:10:00Z","period_status":1,"money_line":{"home":1.465,"draw":null,"away":2.86},"spreads":{"-3.0":{"hdp":-3.0,"home":1.909,"away":1.98,"max":3000.0},"-1.0":{"hdp":-1.0,"home":1.578,"away":2.47,"max":3000.0},"-1.5":{"hdp":-1.5,"home":1.657,"away":2.3,"max":3000.0},"-2.0":{"hdp":-2.0,"home":1.724,"away":2.2,"max":3000.0},"-2.5":{"hdp":-2.5,"home":1.813,"away":2.07,"max":3000.0},"-3.5":{"hdp":-3.5,"home":1.99,"away":1.877,"max":3000.0},"-4.0":{"hdp":-4.0,"home":2.11,"away":1.787,"max":3000.0},"-4.5":{"hdp":-4.5,"home":2.2,"away":1.714,"max":3000.0},"-5.0":{"hdp":-5.0,"home":2.35,"away":1.632,"max":3000.0}},"totals":{"55.0":{"points":55.0,"over":1.961,"under":1.925,"max":1000.0},"53.0":{"points":53.0,"over":1.675,"under":2.29,"max":1000.0},"53.5":{"points":53.5,"over":1.746,"under":2.17,"max":1000.0},"54.0":{"points":54.0,"over":1.806,"under":2.09,"max":1000.0},"54.5":{"points":54.5,"over":1.877,"under":2.0,"max":1000.0},"55.5":{"points":55.5,"over":2.04,"under":1.847,"max":1000.0},"56.0":{"points":56.0,"over":2.14,"under":1.769,"max":1000.0},"56.5":{"points":56.5,"over":2.22,"under":1.714,"max":1000.0},"57.0":{"points":57.0,"over":2.35,"under":1.641,"max":1000.0}},"team_total":{"home":{"points":29.0,"over":1.917,"under":1.934},"away":{"points":26.0,"over":1.98,"under":1.877}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2067360489,"number":4,"cutoff":"2023-04-15T17:10:00Z","period_status":1,"money_line":{"home":1.581,"draw":null,"away":2.51},"spreads":{"-2.5":{"hdp":-2.5,"home":1.99,"away":1.9,"max":500.0},"-0.5":{"hdp":-0.5,"home":1.649,"away":2.32,"max":500.0},"-1.0":{"hdp":-1.0,"home":1.709,"away":2.21,"max":500.0},"-1.5":{"hdp":-1.5,"home":1.8,"away":2.09,"max":500.0},"-2.0":{"hdp":-2.0,"home":1.884,"away":1.99,"max":500.0},"-3.0":{"hdp":-3.0,"home":2.09,"away":1.8,"max":500.0},"-3.5":{"hdp":-3.5,"home":2.19,"away":1.729,"max":500.0},"-4.0":{"hdp":-4.0,"home":2.33,"away":1.645,"max":500.0},"-4.5":{"hdp":-4.5,"home":2.44,"away":1.591,"max":500.0}},"totals":{"54.5":{"points":54.5,"over":1.943,"under":1.943,"max":500.0},"52.5":{"points":52.5,"over":1.653,"under":2.33,"max":500.0},"53.0":{"points":53.0,"over":1.704,"under":2.23,"max":500.0},"53.5":{"points":53.5,"over":1.787,"under":2.12,"max":500.0},"54.0":{"points":54.0,"over":1.862,"under":2.03,"max":500.0},"55.0":{"points":55.0,"over":2.04,"under":1.847,"max":500.0},"55.5":{"points":55.5,"over":2.13,"under":1.775,"max":500.0},"56.0":{"points":56.0,"over":2.25,"under":1.694,"max":500.0},"56.5":{"points":56.5,"over":2.36,"under":1.636,"max":500.0}},"team_total":{"home":{"points":28.5,"over":1.961,"under":1.892},"away":{"points":26.5,"over":2.03,"under":1.833}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1570671683,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-16T00:40:00","last":1681570378,"home":"Sacramento Kings","away":"Golden State Warriors","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2067336986,"number":0,"cutoff":"2023-04-16T00:40:00Z","period_status":1,"money_line":{"home":1.952,"draw":null,"away":1.952},"spreads":{"-1.0":{"hdp":-1.0,"home":1.98,"away":1.925,"max":25000.0},"3.0":{"hdp":3.0,"home":1.657,"away":2.33,"max":25000.0},"2.5":{"hdp":2.5,"home":1.709,"away":2.23,"max":25000.0},"2.0":{"hdp":2.0,"home":1.763,"away":2.15,"max":25000.0},"1.5":{"hdp":1.5,"home":1.826,"away":2.08,"max":25000.0},"1.0":{"hdp":1.0,"home":1.869,"away":2.03,"max":25000.0},"-1.5":{"hdp":-1.5,"home":2.04,"away":1.869,"max":25000.0},"-2.0":{"hdp":-2.0,"home":2.12,"away":1.793,"max":25000.0},"-2.5":{"hdp":-2.5,"home":2.2,"away":1.735,"max":25000.0},"-3.0":{"hdp":-3.0,"home":2.29,"away":1.675,"max":25000.0},"-3.5":{"hdp":-3.5,"home":2.4,"away":1.625,"max":25000.0}},"totals":{"237.5":{"points":237.5,"over":1.917,"under":1.97,"max":5000.0},"235.0":{"points":235.0,"over":1.689,"under":2.25,"max":5000.0},"235.5":{"points":235.5,"over":1.735,"under":2.18,"max":5000.0},"236.0":{"points":236.0,"over":1.769,"under":2.13,"max":5000.0},"236.5":{"points":236.5,"over":1.819,"under":2.08,"max":5000.0},"237.0":{"points":237.0,"over":1.862,"under":2.02,"max":5000.0},"238.0":{"points":238.0,"over":1.961,"under":1.917,"max":5000.0},"238.5":{"points":238.5,"over":2.01,"under":1.877,"max":5000.0},"239.0":{"points":239.0,"over":2.06,"under":1.826,"max":5000.0},"239.5":{"points":239.5,"over":2.11,"under":1.787,"max":5000.0},"240.0":{"points":240.0,"over":2.17,"under":1.74,"max":5000.0}},"team_total":{"home":{"points":118.5,"over":1.862,"under":2.0},"away":{"points":118.5,"over":1.877,"under":1.98}},"meta":{"number":0,"max_spread":25000.0,"max_money_line":15000.0,"max_total":5000.0,"max_team_total":2000.0}},"num_1":{"line_id":2067336990,"number":1,"cutoff":"2023-04-16T00:40:00Z","period_status":1,"money_line":{"home":1.892,"draw":null,"away":2.0},"spreads":{"-0.5":{"hdp":-0.5,"home":1.97,"away":1.917,"max":6500.0},"2.0":{"hdp":2.0,"home":1.645,"away":2.33,"max":6500.0},"1.5":{"hdp":1.5,"home":1.694,"away":2.24,"max":6500.0},"1.0":{"hdp":1.0,"home":1.751,"away":2.16,"max":6500.0},"0.5":{"hdp":0.5,"home":1.819,"away":2.08,"max":6500.0},"-1.0":{"hdp":-1.0,"home":2.05,"away":1.833,"max":6500.0},"-1.5":{"hdp":-1.5,"home":2.13,"away":1.769,"max":6500.0},"-2.0":{"hdp":-2.0,"home":2.22,"away":1.704,"max":6500.0},"-2.5":{"hdp":-2.5,"home":2.32,"away":1.653,"max":6500.0}},"totals":{"117.5":{"points":117.5,"over":1.952,"under":1.934,"max":2000.0},"115.5":{"points":115.5,"over":1.699,"under":2.24,"max":2000.0},"116.0":{"points":116.0,"over":1.746,"under":2.16,"max":2000.0},"116.5":{"points":116.5,"over":1.813,"under":2.08,"max":2000.0},"117.0":{"points":117.0,"over":1.877,"under":2.0,"max":2000.0},"118.0":{"points":118.0,"over":2.02,"under":1.862,"max":2000.0},"118.5":{"points":118.5,"over":2.09,"under":1.806,"max":2000.0},"119.0":{"points":119.0,"over":2.17,"under":1.746,"max":2000.0},"119.5":{"points":119.5,"over":2.24,"under":1.699,"max":2000.0}},"team_total":{"home":{"points":58.5,"over":1.847,"under":2.01},"away":{"points":58.5,"over":1.917,"under":1.934}},"meta":{"number":1,"max_spread":6500.0,"max_money_line":3500.0,"max_total":2000.0,"max_team_total":1000.0}},"num_3":{"line_id":2067327510,"number":3,"cutoff":"2023-04-16T00:40:00Z","period_status":1,"money_line":{"home":1.917,"draw":null,"away":1.97},"spreads":{"-0.5":{"hdp":-0.5,"home":2.02,"away":1.869,"max":3000.0},"2.0":{"hdp":2.0,"home":1.574,"away":2.48,"max":3000.0},"1.5":{"hdp":1.5,"home":1.657,"away":2.3,"max":3000.0},"1.0":{"hdp":1.0,"home":1.729,"away":2.19,"max":3000.0},"0.5":{"hdp":0.5,"home":1.819,"away":2.06,"max":3000.0},"-1.0":{"hdp":-1.0,"home":2.12,"away":1.775,"max":3000.0},"-1.5":{"hdp":-1.5,"home":2.22,"away":1.709,"max":3000.0},"-2.0":{"hdp":-2.0,"home":2.37,"away":1.625,"max":3000.0},"-2.5":{"hdp":-2.5,"home":2.48,"away":1.578,"max":3000.0}},"totals":{"58.5":{"points":58.5,"over":1.909,"under":1.98,"max":1000.0},"56.5":{"points":56.5,"over":1.649,"under":2.33,"max":1000.0},"57.0":{"points":57.0,"over":1.694,"under":2.25,"max":1000.0},"57.5":{"points":57.5,"over":1.763,"under":2.15,"max":1000.0},"58.0":{"points":58.0,"over":1.826,"under":2.07,"max":1000.0},"59.0":{"points":59.0,"over":1.98,"under":1.9,"max":1000.0},"59.5":{"points":59.5,"over":2.05,"under":1.833,"max":1000.0},"60.0":{"points":60.0,"over":2.15,"under":1.757,"max":1000.0},"60.5":{"points":60.5,"over":2.24,"under":1.704,"max":1000.0}},"team_total":{"home":{"points":29.5,"over":1.934,"under":1.917},"away":{"points":29.5,"over":1.952,"under":1.9}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2067327542,"number":4,"cutoff":"2023-04-16T00:40:00Z","period_status":1,"money_line":{"home":1.925,"draw":null,"away":1.961},"spreads":{"-0.5":{"hdp":-0.5,"home":2.02,"away":1.869,"max":500.0},"2.0":{"hdp":2.0,"home":1.598,"away":2.43,"max":500.0},"1.5":{"hdp":1.5,"home":1.675,"away":2.27,"max":500.0},"1.0":{"hdp":1.0,"home":1.746,"away":2.17,"max":500.0},"0.5":{"hdp":0.5,"home":1.833,"away":2.05,"max":500.0},"-1.0":{"hdp":-1.0,"home":2.13,"away":1.769,"max":500.0},"-1.5":{"hdp":-1.5,"home":2.23,"away":1.704,"max":500.0},"-2.0":{"hdp":-2.0,"home":2.38,"away":1.621,"max":500.0},"-2.5":{"hdp":-2.5,"home":2.49,"away":1.571,"max":500.0}},"totals":{"58.5":{"points":58.5,"over":2.01,"under":1.877,"max":500.0},"56.5":{"points":56.5,"over":1.714,"under":2.21,"max":500.0},"57.0":{"points":57.0,"over":1.775,"under":2.12,"max":500.0},"57.5":{"points":57.5,"over":1.854,"under":2.03,"max":500.0},"58.0":{"points":58.0,"over":1.925,"under":1.952,"max":500.0},"59.0":{"points":59.0,"over":2.11,"under":1.793,"max":500.0},"59.5":{"points":59.5,"over":2.19,"under":1.735,"max":500.0},"60.0":{"points":60.0,"over":2.31,"under":1.662,"max":500.0},"60.5":{"points":60.5,"over":2.41,"under":1.613,"max":500.0}},"team_total":{"home":{"points":29.5,"over":2.02,"under":1.84},"away":{"points":29.5,"over":2.04,"under":1.826}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1570671684,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-17T00:10:00","last":1681568411,"home":"Phoenix Suns","away":"Los Angeles Clippers","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2066957075,"number":0,"cutoff":"2023-04-17T00:10:00Z","period_status":1,"money_line":{"home":1.358,"draw":null,"away":3.42},"spreads":{"-7.5":{"hdp":-7.5,"home":2.0,"away":1.909,"max":20000.0},"-5.0":{"hdp":-5.0,"home":1.653,"away":2.34,"max":20000.0},"-5.5":{"hdp":-5.5,"home":1.704,"away":2.24,"max":20000.0},"-6.0":{"hdp":-6.0,"home":1.757,"away":2.16,"max":20000.0},"-6.5":{"hdp":-6.5,"home":1.826,"away":2.08,"max":20000.0},"-7.0":{"hdp":-7.0,"home":1.909,"away":1.99,"max":20000.0},"-8.0":{"hdp":-8.0,"home":2.1,"away":1.819,"max":20000.0},"-8.5":{"hdp":-8.5,"home":2.19,"away":1.746,"max":20000.0},"-9.0":{"hdp":-9.0,"home":2.28,"away":1.684,"max":20000.0},"-9.5":{"hdp":-9.5,"home":2.38,"away":1.632,"max":20000.0},"-10.0":{"hdp":-10.0,"home":2.48,"away":1.588,"max":20000.0}},"totals":{"226.0":{"points":226.0,"over":1.97,"under":1.917,"max":5000.0},"223.5":{"points":223.5,"over":1.735,"under":2.18,"max":5000.0},"224.0":{"points":224.0,"over":1.769,"under":2.13,"max":5000.0},"224.5":{"points":224.5,"over":1.819,"under":2.07,"max":5000.0},"225.0":{"points":225.0,"over":1.869,"under":2.02,"max":5000.0},"225.5":{"points":225.5,"over":1.917,"under":1.961,"max":5000.0},"226.5":{"points":226.5,"over":2.02,"under":1.862,"max":5000.0},"227.0":{"points":227.0,"over":2.08,"under":1.813,"max":5000.0},"227.5":{"points":227.5,"over":2.13,"under":1.769,"max":5000.0},"228.0":{"points":228.0,"over":2.19,"under":1.729,"max":5000.0},"228.5":{"points":228.5,"over":2.24,"under":1.694,"max":5000.0}},"team_total":{"home":{"points":116.5,"over":1.99,"under":1.869},"away":{"points":109.5,"over":1.917,"under":1.934}},"meta":{"number":0,"max_spread":20000.0,"max_money_line":12000.0,"max_total":5000.0,"max_team_total":2000.0}},"num_1":{"line_id":2065216317,"number":1,"cutoff":"2023-04-17T00:10:00Z","period_status":1,"money_line":{"home":1.446,"draw":null,"away":2.93},"spreads":{"-4.5":{"hdp":-4.5,"home":1.97,"away":1.917,"max":4000.0},"-2.5":{"hdp":-2.5,"home":1.694,"away":2.24,"max":4000.0},"-3.0":{"hdp":-3.0,"home":1.746,"away":2.15,"max":4000.0},"-3.5":{"hdp":-3.5,"home":1.813,"away":2.07,"max":4000.0},"-4.0":{"hdp":-4.0,"home":1.884,"away":1.99,"max":4000.0},"-5.0":{"hdp":-5.0,"home":2.05,"away":1.84,"max":4000.0},"-5.5":{"hdp":-5.5,"home":2.13,"away":1.769,"max":4000.0},"-6.0":{"hdp":-6.0,"home":2.22,"away":1.704,"max":4000.0},"-6.5":{"hdp":-6.5,"home":2.31,"away":1.653,"max":4000.0}},"totals":{"110.5":{"points":110.5,"over":1.97,"under":1.917,"max":1500.0},"108.5":{"points":108.5,"over":1.699,"under":2.24,"max":1500.0},"109.0":{"points":109.0,"over":1.751,"under":2.16,"max":1500.0},"109.5":{"points":109.5,"over":1.819,"under":2.07,"max":1500.0},"110.0":{"points":110.0,"over":1.884,"under":1.99,"max":1500.0},"111.0":{"points":111.0,"over":2.03,"under":1.854,"max":1500.0},"111.5":{"points":111.5,"over":2.1,"under":1.8,"max":1500.0},"112.0":{"points":112.0,"over":2.18,"under":1.735,"max":1500.0},"112.5":{"points":112.5,"over":2.25,"under":1.694,"max":1500.0}},"team_total":{"home":{"points":57.5,"over":1.952,"under":1.9},"away":{"points":53.5,"over":2.02,"under":1.84}},"meta":{"number":1,"max_spread":4000.0,"max_money_line":2000.0,"max_total":1500.0,"max_team_total":1000.0}},"num_3":{"line_id":2066958217,"number":3,"cutoff":"2023-04-17T00:10:00Z","period_status":1,"money_line":{"home":1.543,"draw":null,"away":2.61},"spreads":{"-2.5":{"hdp":-2.5,"home":1.943,"away":1.943,"max":3000.0},"-0.5":{"hdp":-0.5,"home":1.613,"away":2.39,"max":3000.0},"-1.0":{"hdp":-1.0,"home":1.671,"away":2.28,"max":3000.0},"-1.5":{"hdp":-1.5,"home":1.763,"away":2.14,"max":3000.0},"-2.0":{"hdp":-2.0,"home":1.84,"away":2.04,"max":3000.0},"-3.0":{"hdp":-3.0,"home":2.04,"away":1.84,"max":3000.0},"-3.5":{"hdp":-3.5,"home":2.14,"away":1.763,"max":3000.0},"-4.0":{"hdp":-4.0,"home":2.27,"away":1.675,"max":3000.0},"-4.5":{"hdp":-4.5,"home":2.38,"away":1.621,"max":3000.0}},"totals":{"55.5":{"points":55.5,"over":1.943,"under":1.943,"max":1000.0},"53.5":{"points":53.5,"over":1.671,"under":2.29,"max":1000.0},"54.0":{"points":54.0,"over":1.724,"under":2.2,"max":1000.0},"54.5":{"points":54.5,"over":1.8,"under":2.1,"max":1000.0},"55.0":{"points":55.0,"over":1.862,"under":2.02,"max":1000.0},"56.0":{"points":56.0,"over":2.03,"under":1.854,"max":1000.0},"56.5":{"points":56.5,"over":2.11,"under":1.787,"max":1000.0},"57.0":{"points":57.0,"over":2.21,"under":1.719,"max":1000.0},"57.5":{"points":57.5,"over":2.3,"under":1.666,"max":1000.0}},"team_total":{"home":{"points":29.0,"over":1.934,"under":1.917},"away":{"points":26.5,"over":1.925,"under":1.925}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2067164531,"number":4,"cutoff":"2023-04-17T00:10:00Z","period_status":1,"money_line":{"home":1.649,"draw":null,"away":2.36},"spreads":{"-1.5":{"hdp":-1.5,"home":1.892,"away":2.0,"max":500.0},"1.0":{"hdp":1.0,"home":1.515,"away":2.63,"max":500.0},"0.5":{"hdp":0.5,"home":1.588,"away":2.45,"max":500.0},"-0.5":{"hdp":-0.5,"home":1.724,"away":2.2,"max":500.0},"-1.0":{"hdp":-1.0,"home":1.793,"away":2.1,"max":500.0},"-2.0":{"hdp":-2.0,"home":1.98,"away":1.892,"max":500.0},"-2.5":{"hdp":-2.5,"home":2.08,"away":1.806,"max":500.0},"-3.0":{"hdp":-3.0,"home":2.2,"away":1.719,"max":500.0},"-3.5":{"hdp":-3.5,"home":2.31,"away":1.653,"max":500.0}},"totals":{"55.0":{"points":55.0,"over":1.97,"under":1.917,"max":500.0},"53.0":{"points":53.0,"over":1.649,"under":2.33,"max":500.0},"53.5":{"points":53.5,"over":1.724,"under":2.2,"max":500.0},"54.0":{"points":54.0,"over":1.793,"under":2.11,"max":500.0},"54.5":{"points":54.5,"over":1.884,"under":2.0,"max":500.0},"55.5":{"points":55.5,"over":2.06,"under":1.833,"max":500.0},"56.0":{"points":56.0,"over":2.17,"under":1.751,"max":500.0},"56.5":{"points":56.5,"over":2.26,"under":1.689,"max":500.0},"57.0":{"points":57.0,"over":2.4,"under":1.617,"max":500.0}},"team_total":{"home":{"points":28.5,"over":1.961,"under":1.892},"away":{"points":27.0,"over":2.06,"under":1.806}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1570671685,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-15T22:10:00","last":1681571621,"home":"Cleveland Cavaliers","away":"New York Knicks","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2067381755,"number":0,"cutoff":"2023-04-15T22:10:00Z","period_status":1,"money_line":{"home":1.473,"draw":null,"away":2.87},"spreads":{"-5.5":{"hdp":-5.5,"home":1.961,"away":1.943,"max":15000.0},"-3.0":{"hdp":-3.0,"home":1.625,"away":2.4,"max":15000.0},"-3.5":{"hdp":-3.5,"home":1.675,"away":2.3,"max":15000.0},"-4.0":{"hdp":-4.0,"home":1.729,"away":2.21,"max":15000.0},"-4.5":{"hdp":-4.5,"home":1.793,"away":2.12,"max":15000.0},"-5.0":{"hdp":-5.0,"home":1.869,"away":2.03,"max":15000.0},"-6.0":{"hdp":-6.0,"home":2.05,"away":1.854,"max":15000.0},"-6.5":{"hdp":-6.5,"home":2.14,"away":1.781,"max":15000.0},"-7.0":{"hdp":-7.0,"home":2.23,"away":1.714,"max":15000.0},"-7.5":{"hdp":-7.5,"home":2.32,"away":1.662,"max":15000.0},"-8.0":{"hdp":-8.0,"home":2.42,"away":1.613,"max":15000.0}},"totals":{"217.0":{"points":217.0,"over":1.917,"under":1.97,"max":4000.0},"214.5":{"points":214.5,"over":1.704,"under":2.23,"max":4000.0},"215.0":{"points":215.0,"over":1.74,"under":2.18,"max":4000.0},"215.5":{"points":215.5,"over":1.781,"under":2.12,"max":4000.0},"216.0":{"points":216.0,"over":1.819,"under":2.07,"max":4000.0},"216.5":{"points":216.5,"over":1.869,"under":2.02,"max":4000.0},"217.5":{"points":217.5,"over":1.97,"under":1.909,"max":4000.0},"218.0":{"points":218.0,"over":2.03,"under":1.854,"max":4000.0},"218.5":{"points":218.5,"over":2.08,"under":1.806,"max":4000.0},"219.0":{"points":219.0,"over":2.15,"under":1.757,"max":4000.0},"219.5":{"points":219.5,"over":2.2,"under":1.719,"max":4000.0}},"team_total":{"home":{"points":110.5,"over":1.84,"under":2.02},"away":{"points":106.5,"over":1.98,"under":1.877}},"meta":{"number":0,"max_spread":15000.0,"max_money_line":7500.0,"max_total":4000.0,"max_team_total":2000.0}},"num_1":{"line_id":2067398065,"number":1,"cutoff":"2023-04-15T22:10:00Z","period_status":1,"money_line":{"home":1.552,"draw":null,"away":2.58},"spreads":{"-2.5":{"hdp":-2.5,"home":1.869,"away":2.03,"max":5000.0},"-0.5":{"hdp":-0.5,"home":1.613,"away":2.39,"max":5000.0},"-1.0":{"hdp":-1.0,"home":1.666,"away":2.29,"max":5000.0},"-1.5":{"hdp":-1.5,"home":1.724,"away":2.2,"max":5000.0},"-2.0":{"hdp":-2.0,"home":1.793,"away":2.11,"max":5000.0},"-3.0":{"hdp":-3.0,"home":1.943,"away":1.934,"max":5000.0},"-3.5":{"hdp":-3.5,"home":2.01,"away":1.862,"max":5000.0},"-4.0":{"hdp":-4.0,"home":2.09,"away":1.793,"max":5000.0},"-4.5":{"hdp":-4.5,"home":2.18,"away":1.735,"max":5000.0}},"totals":{"111.0":{"points":111.0,"over":2.0,"under":1.892,"max":2000.0},"109.0":{"points":109.0,"over":1.751,"under":2.16,"max":2000.0},"109.5":{"points":109.5,"over":1.806,"under":2.08,"max":2000.0},"110.0":{"points":110.0,"over":1.862,"under":2.02,"max":2000.0},"110.5":{"points":110.5,"over":1.917,"under":1.961,"max":2000.0},"111.5":{"points":111.5,"over":2.06,"under":1.826,"max":2000.0},"112.0":{"points":112.0,"over":2.16,"under":1.757,"max":2000.0},"112.5":{"points":112.5,"over":2.23,"under":1.704,"max":2000.0},"113.0":{"points":113.0,"over":2.34,"under":1.645,"max":2000.0}},"team_total":{"home":{"points":57.0,"over":1.925,"under":1.925},"away":{"points":53.5,"over":1.869,"under":1.98}},"meta":{"number":1,"max_spread":5000.0,"max_money_line":2000.0,"max_total":2000.0,"max_team_total":1000.0}},"num_3":{"line_id":2067372965,"number":3,"cutoff":"2023-04-15T22:10:00Z","period_status":1,"money_line":{"home":1.625,"draw":null,"away":2.41},"spreads":{"-2.0":{"hdp":-2.0,"home":1.952,"away":1.934,"max":3000.0},"0.5":{"hdp":0.5,"home":1.558,"away":2.52,"max":3000.0},"-0.5":{"hdp":-0.5,"home":1.694,"away":2.24,"max":3000.0},"-1.0":{"hdp":-1.0,"home":1.763,"away":2.14,"max":3000.0},"-1.5":{"hdp":-1.5,"home":1.854,"away":2.02,"max":3000.0},"-2.5":{"hdp":-2.5,"home":2.04,"away":1.833,"max":3000.0},"-3.0":{"hdp":-3.0,"home":2.17,"away":1.746,"max":3000.0},"-3.5":{"hdp":-3.5,"home":2.27,"away":1.675,"max":3000.0},"-4.0":{"hdp":-4.0,"home":2.43,"away":1.595,"max":3000.0}},"totals":{"56.0":{"points":56.0,"over":2.01,"under":1.884,"max":1000.0},"54.0":{"points":54.0,"over":1.704,"under":2.24,"max":1000.0},"54.5":{"points":54.5,"over":1.775,"under":2.13,"max":1000.0},"55.0":{"points":55.0,"over":1.84,"under":2.05,"max":1000.0},"55.5":{"points":55.5,"over":1.917,"under":1.961,"max":1000.0},"56.5":{"points":56.5,"over":2.1,"under":1.8,"max":1000.0},"57.0":{"points":57.0,"over":2.21,"under":1.729,"max":1000.0},"57.5":{"points":57.5,"over":2.29,"under":1.671,"max":1000.0},"58.0":{"points":58.0,"over":2.43,"under":1.602,"max":1000.0}},"team_total":{"home":{"points":29.0,"over":1.98,"under":1.877},"away":{"points":26.5,"over":1.854,"under":2.0}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2067398089,"number":4,"cutoff":"2023-04-15T22:10:00Z","period_status":1,"money_line":{"home":1.694,"draw":null,"away":2.27},"spreads":{"-1.0":{"hdp":-1.0,"home":1.862,"away":2.03,"max":500.0},"1.5":{"hdp":1.5,"home":1.51,"away":2.65,"max":500.0},"1.0":{"hdp":1.0,"home":1.552,"away":2.53,"max":500.0},"0.5":{"hdp":0.5,"home":1.632,"away":2.37,"max":500.0},"-0.5":{"hdp":-0.5,"home":1.775,"away":2.13,"max":500.0},"-1.5":{"hdp":-1.5,"home":1.943,"away":1.925,"max":500.0},"-2.0":{"hdp":-2.0,"home":2.05,"away":1.833,"max":500.0},"-2.5":{"hdp":-2.5,"home":2.15,"away":1.751,"max":500.0},"-3.0":{"hdp":-3.0,"home":2.28,"away":1.671,"max":500.0}},"totals":{"55.5":{"points":55.5,"over":1.99,"under":1.9,"max":500.0},"53.5":{"points":53.5,"over":1.671,"under":2.29,"max":500.0},"54.0":{"points":54.0,"over":1.724,"under":2.2,"max":500.0},"54.5":{"points":54.5,"over":1.806,"under":2.09,"max":500.0},"55.0":{"points":55.0,"over":1.884,"under":1.99,"max":500.0},"56.0":{"points":56.0,"over":2.09,"under":1.806,"max":500.0},"56.5":{"points":56.5,"over":2.19,"under":1.74,"max":500.0},"57.0":{"points":57.0,"over":2.32,"under":1.657,"max":500.0},"57.5":{"points":57.5,"over":2.43,"under":1.606,"max":500.0}},"team_total":{"home":{"points":28.5,"over":1.97,"under":1.884},"away":{"points":27.0,"over":1.952,"under":1.9}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1570794181,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-15T19:40:00","last":1681570462,"home":"Boston Celtics","away":"Atlanta Hawks","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2067326363,"number":0,"cutoff":"2023-04-15T19:40:00Z","period_status":1,"money_line":{"home":1.247,"draw":null,"away":4.36},"spreads":{"-9.5":{"hdp":-9.5,"home":1.97,"away":1.934,"max":25000.0},"-7.0":{"hdp":-7.0,"home":1.632,"away":2.38,"max":25000.0},"-7.5":{"hdp":-7.5,"home":1.68,"away":2.28,"max":25000.0},"-8.0":{"hdp":-8.0,"home":1.735,"away":2.2,"max":25000.0},"-8.5":{"hdp":-8.5,"home":1.8,"away":2.11,"max":25000.0},"-9.0":{"hdp":-9.0,"home":1.877,"away":2.02,"max":25000.0},"-10.0":{"hdp":-10.0,"home":2.06,"away":1.847,"max":25000.0},"-10.5":{"hdp":-10.5,"home":2.15,"away":1.769,"max":25000.0},"-11.0":{"hdp":-11.0,"home":2.24,"away":1.709,"max":25000.0},"-11.5":{"hdp":-11.5,"home":2.33,"away":1.657,"max":25000.0},"-12.0":{"hdp":-12.0,"home":2.44,"away":1.606,"max":25000.0}},"totals":{"231.0":{"points":231.0,"over":1.98,"under":1.909,"max":5000.0},"228.5":{"points":228.5,"over":1.74,"under":2.16,"max":5000.0},"229.0":{"points":229.0,"over":1.781,"under":2.11,"max":5000.0},"229.5":{"points":229.5,"over":1.826,"under":2.06,"max":5000.0},"230.0":{"points":230.0,"over":1.877,"under":2.01,"max":5000.0},"230.5":{"points":230.5,"over":1.917,"under":1.952,"max":5000.0},"231.5":{"points":231.5,"over":2.03,"under":1.854,"max":5000.0},"232.0":{"points":232.0,"over":2.09,"under":1.806,"max":5000.0},"232.5":{"points":232.5,"over":2.14,"under":1.769,"max":5000.0},"233.0":{"points":233.0,"over":2.21,"under":1.719,"max":5000.0},"233.5":{"points":233.5,"over":2.26,"under":1.684,"max":5000.0}},"team_total":{"home":{"points":119.5,"over":1.854,"under":2.0},"away":{"points":110.5,"over":1.925,"under":1.925}},"meta":{"number":0,"max_spread":25000.0,"max_money_line":15000.0,"max_total":5000.0,"max_team_total":2000.0}},"num_1":{"line_id":2067339777,"number":1,"cutoff":"2023-04-15T19:40:00Z","period_status":1,"money_line":{"home":1.369,"draw":null,"away":3.29},"spreads":{"-5.0":{"hdp":-5.0,"home":1.917,"away":1.97,"max":6500.0},"-3.0":{"hdp":-3.0,"home":1.649,"away":2.32,"max":6500.0},"-3.5":{"hdp":-3.5,"home":1.704,"away":2.22,"max":6500.0},"-4.0":{"hdp":-4.0,"home":1.769,"away":2.14,"max":6500.0},"-4.5":{"hdp":-4.5,"home":1.833,"away":2.05,"max":6500.0},"-5.5":{"hdp":-5.5,"home":1.99,"away":1.884,"max":6500.0},"-6.0":{"hdp":-6.0,"home":2.07,"away":1.813,"max":6500.0},"-6.5":{"hdp":-6.5,"home":2.15,"away":1.746,"max":6500.0},"-7.0":{"hdp":-7.0,"home":2.24,"away":1.694,"max":6500.0}},"totals":{"118.0":{"points":118.0,"over":1.943,"under":1.943,"max":2000.0},"116.0":{"points":116.0,"over":1.714,"under":2.22,"max":2000.0},"116.5":{"points":116.5,"over":1.763,"under":2.14,"max":2000.0},"117.0":{"points":117.0,"over":1.813,"under":2.08,"max":2000.0},"117.5":{"points":117.5,"over":1.869,"under":2.01,"max":2000.0},"118.5":{"points":118.5,"over":2.01,"under":1.869,"max":2000.0},"119.0":{"points":119.0,"over":2.1,"under":1.8,"max":2000.0},"119.5":{"points":119.5,"over":2.17,"under":1.746,"max":2000.0},"120.0":{"points":120.0,"over":2.27,"under":1.68,"max":2000.0}},"team_total":{"home":{"points":61.5,"over":1.877,"under":1.98},"away":{"points":56.5,"over":1.961,"under":1.892}},"meta":{"number":1,"max_spread":6500.0,"max_money_line":3500.0,"max_total":2000.0,"max_team_total":1000.0}},"num_3":{"line_id":2067247663,"number":3,"cutoff":"2023-04-15T19:40:00Z","period_status":1,"money_line":{"home":1.478,"draw":null,"away":2.81},"spreads":{"-3.0":{"hdp":-3.0,"home":1.934,"away":1.952,"max":3000.0},"-1.0":{"hdp":-1.0,"home":1.598,"away":2.43,"max":3000.0},"-1.5":{"hdp":-1.5,"home":1.68,"away":2.26,"max":3000.0},"-2.0":{"hdp":-2.0,"home":1.751,"away":2.16,"max":3000.0},"-2.5":{"hdp":-2.5,"home":1.84,"away":2.04,"max":3000.0},"-3.5":{"hdp":-3.5,"home":2.02,"away":1.854,"max":3000.0},"-4.0":{"hdp":-4.0,"home":2.14,"away":1.763,"max":3000.0},"-4.5":{"hdp":-4.5,"home":2.24,"away":1.694,"max":3000.0},"-5.0":{"hdp":-5.0,"home":2.39,"away":1.613,"max":3000.0}},"totals":{"59.0":{"points":59.0,"over":1.9,"under":1.98,"max":1000.0},"57.0":{"points":57.0,"over":1.645,"under":2.34,"max":1000.0},"57.5":{"points":57.5,"over":1.709,"under":2.22,"max":1000.0},"58.0":{"points":58.0,"over":1.763,"under":2.15,"max":1000.0},"58.5":{"points":58.5,"over":1.833,"under":2.06,"max":1000.0},"59.5":{"points":59.5,"over":1.98,"under":1.9,"max":1000.0},"60.0":{"points":60.0,"over":2.06,"under":1.826,"max":1000.0},"60.5":{"points":60.5,"over":2.14,"under":1.763,"max":1000.0},"61.0":{"points":61.0,"over":2.25,"under":1.694,"max":1000.0}},"team_total":{"home":{"points":31.0,"over":1.9,"under":1.952},"away":{"points":28.0,"over":1.892,"under":1.961}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2067247692,"number":4,"cutoff":"2023-04-15T19:40:00Z","period_status":1,"money_line":{"home":1.546,"draw":null,"away":2.6},"spreads":{"-2.5":{"hdp":-2.5,"home":1.934,"away":1.952,"max":500.0},"-0.5":{"hdp":-0.5,"home":1.613,"away":2.39,"max":500.0},"-1.0":{"hdp":-1.0,"home":1.666,"away":2.28,"max":500.0},"-1.5":{"hdp":-1.5,"home":1.751,"away":2.15,"max":500.0},"-2.0":{"hdp":-2.0,"home":1.833,"away":2.05,"max":500.0},"-3.0":{"hdp":-3.0,"home":2.02,"away":1.854,"max":500.0},"-3.5":{"hdp":-3.5,"home":2.13,"away":1.775,"max":500.0},"-4.0":{"hdp":-4.0,"home":2.25,"away":1.684,"max":500.0},"-4.5":{"hdp":-4.5,"home":2.36,"away":1.628,"max":500.0}},"totals":{"58.5":{"points":58.5,"over":1.884,"under":2.0,"max":500.0},"56.5":{"points":56.5,"over":1.625,"under":2.39,"max":500.0},"57.0":{"points":57.0,"over":1.671,"under":2.29,"max":500.0},"57.5":{"points":57.5,"over":1.746,"under":2.18,"max":500.0},"58.0":{"points":58.0,"over":1.806,"under":2.09,"max":500.0},"59.0":{"points":59.0,"over":1.97,"under":1.909,"max":500.0},"59.5":{"points":59.5,"over":2.06,"under":1.826,"max":500.0},"60.0":{"points":60.0,"over":2.17,"under":1.746,"max":500.0},"60.5":{"points":60.5,"over":2.27,"under":1.684,"max":500.0}},"team_total":{"home":{"points":30.5,"over":1.884,"under":1.97},"away":{"points":28.5,"over":2.02,"under":1.84}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1570800108,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-16T19:10:00","last":1681567037,"home":"Memphis Grizzlies","away":"Los Angeles Lakers","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2067039020,"number":0,"cutoff":"2023-04-16T19:10:00Z","period_status":1,"money_line":{"home":1.613,"draw":null,"away":2.46},"spreads":{"-3.5":{"hdp":-3.5,"home":1.9,"away":2.01,"max":20000.0},"-1.0":{"hdp":-1.0,"home":1.609,"away":2.42,"max":20000.0},"-1.5":{"hdp":-1.5,"home":1.641,"away":2.37,"max":20000.0},"-2.0":{"hdp":-2.0,"home":1.684,"away":2.28,"max":20000.0},"-2.5":{"hdp":-2.5,"home":1.74,"away":2.2,"max":20000.0},"-3.0":{"hdp":-3.0,"home":1.813,"away":2.1,"max":20000.0},"-4.0":{"hdp":-4.0,"home":1.98,"away":1.909,"max":20000.0},"-4.5":{"hdp":-4.5,"home":2.07,"away":1.833,"max":20000.0},"-5.0":{"hdp":-5.0,"home":2.15,"away":1.763,"max":20000.0},"-5.5":{"hdp":-5.5,"home":2.24,"away":1.709,"max":20000.0},"-6.0":{"hdp":-6.0,"home":2.33,"away":1.657,"max":20000.0}},"totals":{"227.5":{"points":227.5,"over":1.9,"under":1.99,"max":5000.0},"225.0":{"points":225.0,"over":1.675,"under":2.27,"max":5000.0},"225.5":{"points":225.5,"over":1.719,"under":2.2,"max":5000.0},"226.0":{"points":226.0,"over":1.757,"under":2.15,"max":5000.0},"226.5":{"points":226.5,"over":1.806,"under":2.09,"max":5000.0},"227.0":{"points":227.0,"over":1.847,"under":2.04,"max":5000.0},"228.0":{"points":228.0,"over":1.943,"under":1.934,"max":5000.0},"228.5":{"points":228.5,"over":1.99,"under":1.884,"max":5000.0},"229.0":{"points":229.0,"over":2.04,"under":1.84,"max":5000.0},"229.5":{"points":229.5,"over":2.09,"under":1.8,"max":5000.0},"230.0":{"points":230.0,"over":2.15,"under":1.751,"max":5000.0}},"team_total":{"home":{"points":115.5,"over":1.884,"under":1.97},"away":{"points":112.5,"over":1.952,"under":1.9}},"meta":{"number":0,"max_spread":20000.0,"max_money_line":12000.0,"max_total":5000.0,"max_team_total":2000.0}},"num_1":{"line_id":2067039017,"number":1,"cutoff":"2023-04-16T19:10:00Z","period_status":1,"money_line":{"home":1.645,"draw":null,"away":2.37},"spreads":{"-2.0":{"hdp":-2.0,"home":1.909,"away":1.98,"max":5000.0},"0.5":{"hdp":0.5,"home":1.602,"away":2.42,"max":5000.0},"-0.5":{"hdp":-0.5,"home":1.699,"away":2.23,"max":5000.0},"-1.0":{"hdp":-1.0,"home":1.763,"away":2.14,"max":5000.0},"-1.5":{"hdp":-1.5,"home":1.833,"away":2.06,"max":5000.0},"-2.5":{"hdp":-2.5,"home":1.99,"away":1.892,"max":5000.0},"-3.0":{"hdp":-3.0,"home":2.06,"away":1.819,"max":5000.0},"-3.5":{"hdp":-3.5,"home":2.15,"away":1.751,"max":5000.0},"-4.0":{"hdp":-4.0,"home":2.23,"away":1.699,"max":5000.0}},"totals":{"117.0":{"points":117.0,"over":1.952,"under":1.934,"max":2000.0},"115.0":{"points":115.0,"over":1.729,"under":2.19,"max":2000.0},"115.5":{"points":115.5,"over":1.781,"under":2.11,"max":2000.0},"116.0":{"points":116.0,"over":1.833,"under":2.06,"max":2000.0},"116.5":{"points":116.5,"over":1.884,"under":1.99,"max":2000.0},"117.5":{"points":117.5,"over":2.01,"under":1.869,"max":2000.0},"118.0":{"points":118.0,"over":2.1,"under":1.8,"max":2000.0},"118.5":{"points":118.5,"over":2.17,"under":1.74,"max":2000.0},"119.0":{"points":119.0,"over":2.28,"under":1.68,"max":2000.0}},"team_total":{"home":{"points":59.0,"over":1.9,"under":1.952},"away":{"points":57.0,"over":1.934,"under":1.917}},"meta":{"number":1,"max_spread":5000.0,"max_money_line":2000.0,"max_total":2000.0,"max_team_total":1000.0}},"num_3":{"line_id":2067039018,"number":3,"cutoff":"2023-04-16T19:10:00Z","period_status":1,"money_line":{"home":1.68,"draw":null,"away":2.3},"spreads":{"-1.5":{"hdp":-1.5,"home":1.934,"away":1.952,"max":3000.0},"1.0":{"hdp":1.0,"home":1.531,"away":2.59,"max":3000.0},"0.5":{"hdp":0.5,"home":1.613,"away":2.4,"max":3000.0},"-0.5":{"hdp":-0.5,"home":1.757,"away":2.15,"max":3000.0},"-1.0":{"hdp":-1.0,"home":1.833,"away":2.05,"max":3000.0},"-2.0":{"hdp":-2.0,"home":2.03,"away":1.847,"max":3000.0},"-2.5":{"hdp":-2.5,"home":2.13,"away":1.775,"max":3000.0},"-3.0":{"hdp":-3.0,"home":2.26,"away":1.684,"max":3000.0},"-3.5":{"hdp":-3.5,"home":2.37,"away":1.625,"max":3000.0}},"totals":{"58.5":{"points":58.5,"over":1.9,"under":1.99,"max":1000.0},"56.5":{"points":56.5,"over":1.649,"under":2.33,"max":1000.0},"57.0":{"points":57.0,"over":1.699,"under":2.24,"max":1000.0},"57.5":{"points":57.5,"over":1.769,"under":2.14,"max":1000.0},"58.0":{"points":58.0,"over":1.826,"under":2.06,"max":1000.0},"59.0":{"points":59.0,"over":1.98,"under":1.9,"max":1000.0},"59.5":{"points":59.5,"over":2.06,"under":1.833,"max":1000.0},"60.0":{"points":60.0,"over":2.15,"under":1.757,"max":1000.0},"60.5":{"points":60.5,"over":2.23,"under":1.704,"max":1000.0}},"team_total":{"home":{"points":30.0,"over":1.9,"under":1.952},"away":{"points":28.5,"over":1.892,"under":1.961}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2067039019,"number":4,"cutoff":"2023-04-16T19:10:00Z","period_status":1,"money_line":{"home":1.793,"draw":null,"away":2.12},"spreads":{"-0.5":{"hdp":-0.5,"home":1.877,"away":2.01,"max":500.0},"2.0":{"hdp":2.0,"home":1.512,"away":2.65,"max":500.0},"1.5":{"hdp":1.5,"home":1.581,"away":2.46,"max":500.0},"1.0":{"hdp":1.0,"home":1.636,"away":2.36,"max":500.0},"0.5":{"hdp":0.5,"home":1.714,"away":2.21,"max":500.0},"-1.0":{"hdp":-1.0,"home":1.97,"away":1.9,"max":500.0},"-1.5":{"hdp":-1.5,"home":2.07,"away":1.819,"max":500.0},"-2.0":{"hdp":-2.0,"home":2.19,"away":1.724,"max":500.0},"-2.5":{"hdp":-2.5,"home":2.3,"away":1.662,"max":500.0}},"totals":{"58.5":{"points":58.5,"over":1.99,"under":1.9,"max":500.0},"56.5":{"points":56.5,"over":1.694,"under":2.25,"max":500.0},"57.0":{"points":57.0,"over":1.751,"under":2.16,"max":500.0},"57.5":{"points":57.5,"over":1.833,"under":2.06,"max":500.0},"58.0":{"points":58.0,"over":1.9,"under":1.97,"max":500.0},"59.0":{"points":59.0,"over":2.09,"under":1.813,"max":500.0},"59.5":{"points":59.5,"over":2.18,"under":1.74,"max":500.0},"60.0":{"points":60.0,"over":2.31,"under":1.662,"max":500.0},"60.5":{"points":60.5,"over":2.41,"under":1.613,"max":500.0}},"team_total":{"home":{"points":29.5,"over":1.909,"under":1.943},"away":{"points":29.0,"over":2.03,"under":1.833}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1571130758,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-16T21:40:00","last":1681565359,"home":"Milwaukee Bucks","away":"Miami Heat","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2066966502,"number":0,"cutoff":"2023-04-16T21:40:00Z","period_status":1,"money_line":{"home":1.256,"draw":null,"away":4.26},"spreads":{"-9.0":{"hdp":-9.0,"home":1.917,"away":1.99,"max":15000.0},"-6.5":{"hdp":-6.5,"home":1.595,"away":2.46,"max":15000.0},"-7.0":{"hdp":-7.0,"home":1.641,"away":2.36,"max":15000.0},"-7.5":{"hdp":-7.5,"home":1.694,"away":2.26,"max":15000.0},"-8.0":{"hdp":-8.0,"home":1.757,"away":2.17,"max":15000.0},"-8.5":{"hdp":-8.5,"home":1.826,"away":2.08,"max":15000.0},"-9.5":{"hdp":-9.5,"home":2.0,"away":1.892,"max":15000.0},"-10.0":{"hdp":-10.0,"home":2.09,"away":1.813,"max":15000.0},"-10.5":{"hdp":-10.5,"home":2.17,"away":1.751,"max":15000.0},"-11.0":{"hdp":-11.0,"home":2.26,"away":1.694,"max":15000.0},"-11.5":{"hdp":-11.5,"home":2.36,"away":1.645,"max":15000.0}},"totals":{"219.0":{"points":219.0,"over":1.952,"under":1.934,"max":3000.0},"216.5":{"points":216.5,"over":1.719,"under":2.2,"max":3000.0},"217.0":{"points":217.0,"over":1.757,"under":2.15,"max":3000.0},"217.5":{"points":217.5,"over":1.806,"under":2.08,"max":3000.0},"218.0":{"points":218.0,"over":1.847,"under":2.04,"max":3000.0},"218.5":{"points":218.5,"over":1.892,"under":1.98,"max":3000.0},"219.5":{"points":219.5,"over":2.0,"under":1.877,"max":3000.0},"220.0":{"points":220.0,"over":2.06,"under":1.833,"max":3000.0},"220.5":{"points":220.5,"over":2.11,"under":1.787,"max":3000.0},"221.0":{"points":221.0,"over":2.17,"under":1.74,"max":3000.0},"221.5":{"points":221.5,"over":2.22,"under":1.704,"max":3000.0}},"team_total":{"home":{"points":113.5,"over":1.877,"under":1.97},"away":{"points":104.5,"over":1.869,"under":1.99}},"meta":{"number":0,"max_spread":15000.0,"max_total":3000.0,"max_money_line":7500.0,"max_team_total":1500.0}},"num_1":{"line_id":2066966507,"number":1,"cutoff":"2023-04-16T21:40:00Z","period_status":1,"money_line":{"home":1.366,"draw":null,"away":3.31},"spreads":{"-5.5":{"hdp":-5.5,"home":1.952,"away":1.934,"max":5000.0},"-3.5":{"hdp":-3.5,"home":1.666,"away":2.29,"max":5000.0},"-4.0":{"hdp":-4.0,"home":1.719,"away":2.2,"max":5000.0},"-4.5":{"hdp":-4.5,"home":1.781,"away":2.11,"max":5000.0},"-5.0":{"hdp":-5.0,"home":1.854,"away":2.03,"max":5000.0},"-6.0":{"hdp":-6.0,"home":2.04,"away":1.847,"max":5000.0},"-6.5":{"hdp":-6.5,"home":2.13,"away":1.775,"max":5000.0},"-7.0":{"hdp":-7.0,"home":2.21,"away":1.709,"max":5000.0},"-7.5":{"hdp":-7.5,"home":2.3,"away":1.657,"max":5000.0}},"totals":{"112.5":{"points":112.5,"over":1.917,"under":1.97,"max":1500.0},"110.5":{"points":110.5,"over":1.714,"under":2.22,"max":1500.0},"111.0":{"points":111.0,"over":1.751,"under":2.16,"max":1500.0},"111.5":{"points":111.5,"over":1.813,"under":2.09,"max":1500.0},"112.0":{"points":112.0,"over":1.862,"under":2.02,"max":1500.0},"113.0":{"points":113.0,"over":1.99,"under":1.884,"max":1500.0},"113.5":{"points":113.5,"over":2.07,"under":1.819,"max":1500.0},"114.0":{"points":114.0,"over":2.16,"under":1.746,"max":1500.0},"114.5":{"points":114.5,"over":2.25,"under":1.694,"max":1500.0}},"team_total":{"home":{"points":59.0,"over":1.98,"under":1.877},"away":{"points":53.5,"over":1.952,"under":1.892}},"meta":{"number":1,"max_spread":5000.0,"max_money_line":2500.0,"max_total":1500.0,"max_team_total":1000.0}},"num_3":{"line_id":2066955419,"number":3,"cutoff":"2023-04-16T21:40:00Z","period_status":1,"money_line":{"home":1.446,"draw":null,"away":2.93},"spreads":{"-3.5":{"hdp":-3.5,"home":1.97,"away":1.917,"max":3000.0},"-1.5":{"hdp":-1.5,"home":1.636,"away":2.35,"max":3000.0},"-2.0":{"hdp":-2.0,"home":1.694,"away":2.24,"max":3000.0},"-2.5":{"hdp":-2.5,"home":1.787,"away":2.11,"max":3000.0},"-3.0":{"hdp":-3.0,"home":1.862,"away":2.01,"max":3000.0},"-4.0":{"hdp":-4.0,"home":2.07,"away":1.819,"max":3000.0},"-4.5":{"hdp":-4.5,"home":2.17,"away":1.746,"max":3000.0},"-5.0":{"hdp":-5.0,"home":2.31,"away":1.657,"max":3000.0},"-5.5":{"hdp":-5.5,"home":2.42,"away":1.602,"max":3000.0}},"totals":{"56.5":{"points":56.5,"over":1.917,"under":1.97,"max":1000.0},"54.5":{"points":54.5,"over":1.662,"under":2.31,"max":1000.0},"55.0":{"points":55.0,"over":1.709,"under":2.22,"max":1000.0},"55.5":{"points":55.5,"over":1.781,"under":2.12,"max":1000.0},"56.0":{"points":56.0,"over":1.847,"under":2.04,"max":1000.0},"57.0":{"points":57.0,"over":2.0,"under":1.884,"max":1000.0},"57.5":{"points":57.5,"over":2.09,"under":1.813,"max":1000.0},"58.0":{"points":58.0,"over":2.18,"under":1.735,"max":1000.0},"58.5":{"points":58.5,"over":2.27,"under":1.684,"max":1000.0}},"team_total":{"home":{"points":30.0,"over":1.934,"under":1.917},"away":{"points":26.5,"over":1.884,"under":1.97}},"meta":{"number":3,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":1000.0}},"num_4":{"line_id":2066966510,"number":4,"cutoff":"2023-04-16T21:40:00Z","period_status":1,"money_line":{"home":1.571,"draw":null,"away":2.53},"spreads":{"-2.5":{"hdp":-2.5,"home":1.97,"away":1.917,"max":500.0},"-0.5":{"hdp":-0.5,"home":1.641,"away":2.34,"max":500.0},"-1.0":{"hdp":-1.0,"home":1.699,"away":2.23,"max":500.0},"-1.5":{"hdp":-1.5,"home":1.787,"away":2.11,"max":500.0},"-2.0":{"hdp":-2.0,"home":1.869,"away":2.0,"max":500.0},"-3.0":{"hdp":-3.0,"home":2.07,"away":1.813,"max":500.0},"-3.5":{"hdp":-3.5,"home":2.17,"away":1.74,"max":500.0},"-4.0":{"hdp":-4.0,"home":2.31,"away":1.657,"max":500.0},"-4.5":{"hdp":-4.5,"home":2.42,"away":1.602,"max":500.0}},"totals":{"56.0":{"points":56.0,"over":1.934,"under":1.952,"max":500.0},"54.0":{"points":54.0,"over":1.636,"under":2.36,"max":500.0},"54.5":{"points":54.5,"over":1.709,"under":2.23,"max":500.0},"55.0":{"points":55.0,"over":1.769,"under":2.14,"max":500.0},"55.5":{"points":55.5,"over":1.847,"under":2.04,"max":500.0},"56.5":{"points":56.5,"over":2.01,"under":1.869,"max":500.0},"57.0":{"points":57.0,"over":2.12,"under":1.781,"max":500.0},"57.5":{"points":57.5,"over":2.22,"under":1.714,"max":500.0},"58.0":{"points":58.0,"over":2.36,"under":1.636,"max":500.0}},"team_total":{"home":{"points":29.0,"over":1.9,"under":1.952},"away":{"points":26.5,"over":1.833,"under":2.03}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}},{"event_id":1571135863,"sport_id":3,"league_id":487,"league_name":"NBA","starts":"2023-04-17T02:40:00","last":1681571641,"home":"Denver Nuggets","away":"Minnesota Timberwolves","event_type":"prematch","parent_id":null,"resulting_unit":"Regular","is_have_odds":true,"periods":{"num_0":{"line_id":2067398680,"number":0,"cutoff":"2023-04-17T02:40:00Z","period_status":1,"money_line":{"home":1.353,"draw":null,"away":3.45},"spreads":{"-7.5":{"hdp":-7.5,"home":1.961,"away":1.943,"max":6500.0},"-5.0":{"hdp":-5.0,"home":1.621,"away":2.4,"max":6500.0},"-5.5":{"hdp":-5.5,"home":1.671,"away":2.3,"max":6500.0},"-6.0":{"hdp":-6.0,"home":1.724,"away":2.21,"max":6500.0},"-6.5":{"hdp":-6.5,"home":1.787,"away":2.12,"max":6500.0},"-7.0":{"hdp":-7.0,"home":1.869,"away":2.04,"max":6500.0},"-8.0":{"hdp":-8.0,"home":2.05,"away":1.854,"max":6500.0},"-8.5":{"hdp":-8.5,"home":2.14,"away":1.781,"max":6500.0},"-9.0":{"hdp":-9.0,"home":2.22,"away":1.714,"max":6500.0},"-9.5":{"hdp":-9.5,"home":2.32,"away":1.666,"max":6500.0},"-10.0":{"hdp":-10.0,"home":2.42,"away":1.613,"max":6500.0}},"totals":{"224.5":{"points":224.5,"over":1.943,"under":1.943,"max":2000.0},"222.0":{"points":222.0,"over":1.714,"under":2.21,"max":2000.0},"222.5":{"points":222.5,"over":1.757,"under":2.15,"max":2000.0},"223.0":{"points":223.0,"over":1.8,"under":2.09,"max":2000.0},"223.5":{"points":223.5,"over":1.847,"under":2.04,"max":2000.0},"224.0":{"points":224.0,"over":1.892,"under":1.99,"max":2000.0},"225.0":{"points":225.0,"over":1.99,"under":1.884,"max":2000.0},"225.5":{"points":225.5,"over":2.04,"under":1.84,"max":2000.0},"226.0":{"points":226.0,"over":2.1,"under":1.793,"max":2000.0},"226.5":{"points":226.5,"over":2.15,"under":1.757,"max":2000.0},"227.0":{"points":227.0,"over":2.21,"under":1.709,"max":2000.0}},"team_total":{"home":{"points":115.5,"over":1.877,"under":1.98},"away":{"points":108.5,"over":1.917,"under":1.934}},"meta":{"number":0,"max_spread":6500.0,"max_money_line":3500.0,"max_total":2000.0,"max_team_total":1000.0}},"num_1":{"line_id":2067398688,"number":1,"cutoff":"2023-04-17T02:40:00Z","period_status":1,"money_line":{"home":1.467,"draw":null,"away":2.85},"spreads":{"-4.0":{"hdp":-4.0,"home":1.917,"away":1.97,"max":3000.0},"-2.0":{"hdp":-2.0,"home":1.645,"away":2.33,"max":3000.0},"-2.5":{"hdp":-2.5,"home":1.694,"away":2.24,"max":3000.0},"-3.0":{"hdp":-3.0,"home":1.757,"away":2.15,"max":3000.0},"-3.5":{"hdp":-3.5,"home":1.833,"away":2.06,"max":3000.0},"-4.5":{"hdp":-4.5,"home":2.01,"away":1.877,"max":3000.0},"-5.0":{"hdp":-5.0,"home":2.09,"away":1.8,"max":3000.0},"-5.5":{"hdp":-5.5,"home":2.18,"away":1.729,"max":3000.0},"-6.0":{"hdp":-6.0,"home":2.26,"away":1.68,"max":3000.0}},"totals":{"115.0":{"points":115.0,"over":1.952,"under":1.934,"max":1000.0},"113.0":{"points":113.0,"over":1.724,"under":2.2,"max":1000.0},"113.5":{"points":113.5,"over":1.775,"under":2.12,"max":1000.0},"114.0":{"points":114.0,"over":1.826,"under":2.06,"max":1000.0},"114.5":{"points":114.5,"over":1.884,"under":2.0,"max":1000.0},"115.5":{"points":115.5,"over":2.01,"under":1.869,"max":1000.0},"116.0":{"points":116.0,"over":2.1,"under":1.8,"max":1000.0},"116.5":{"points":116.5,"over":2.17,"under":1.74,"max":1000.0},"117.0":{"points":117.0,"over":2.28,"under":1.68,"max":1000.0}},"team_total":{"home":{"points":59.5,"over":1.917,"under":1.934},"away":{"points":55.5,"over":1.943,"under":1.909}},"meta":{"number":1,"max_spread":3000.0,"max_money_line":1500.0,"max_total":1000.0,"max_team_total":500.0}},"num_3":{"line_id":2067398001,"number":3,"cutoff":"2023-04-17T02:40:00Z","period_status":1,"money_line":{"home":1.54,"draw":null,"away":2.62},"spreads":{"-2.5":{"hdp":-2.5,"home":1.934,"away":1.952,"max":1500.0},"-0.5":{"hdp":-0.5,"home":1.609,"away":2.4,"max":1500.0},"-1.0":{"hdp":-1.0,"home":1.666,"away":2.29,"max":1500.0},"-1.5":{"hdp":-1.5,"home":1.757,"away":2.15,"max":1500.0},"-2.0":{"hdp":-2.0,"home":1.833,"away":2.05,"max":1500.0},"-3.0":{"hdp":-3.0,"home":2.03,"away":1.847,"max":1500.0},"-3.5":{"hdp":-3.5,"home":2.13,"away":1.775,"max":1500.0},"-4.0":{"hdp":-4.0,"home":2.26,"away":1.684,"max":1500.0},"-4.5":{"hdp":-4.5,"home":2.37,"away":1.625,"max":1500.0}},"totals":{"57.5":{"points":57.5,"over":1.9,"under":1.99,"max":750.0},"55.5":{"points":55.5,"over":1.645,"under":2.34,"max":750.0},"56.0":{"points":56.0,"over":1.694,"under":2.25,"max":750.0},"56.5":{"points":56.5,"over":1.769,"under":2.14,"max":750.0},"57.0":{"points":57.0,"over":1.826,"under":2.07,"max":750.0},"58.0":{"points":58.0,"over":1.98,"under":1.9,"max":750.0},"58.5":{"points":58.5,"over":2.06,"under":1.826,"max":750.0},"59.0":{"points":59.0,"over":2.15,"under":1.757,"max":750.0},"59.5":{"points":59.5,"over":2.24,"under":1.704,"max":750.0}},"team_total":{"home":{"points":30.0,"over":1.884,"under":1.961},"away":{"points":27.5,"over":1.9,"under":1.952}},"meta":{"number":3,"max_spread":1500.0,"max_money_line":750.0,"max_total":750.0,"max_team_total":500.0}},"num_4":{"line_id":2067398697,"number":4,"cutoff":"2023-04-17T02:40:00Z","period_status":1,"money_line":{"home":1.68,"draw":null,"away":2.3},"spreads":{"-1.5":{"hdp":-1.5,"home":1.934,"away":1.952,"max":500.0},"1.0":{"hdp":1.0,"home":1.54,"away":2.56,"max":500.0},"0.5":{"hdp":0.5,"home":1.617,"away":2.39,"max":500.0},"-0.5":{"hdp":-0.5,"home":1.757,"away":2.15,"max":500.0},"-1.0":{"hdp":-1.0,"home":1.833,"away":2.05,"max":500.0},"-2.0":{"hdp":-2.0,"home":2.03,"away":1.847,"max":500.0},"-2.5":{"hdp":-2.5,"home":2.13,"away":1.775,"max":500.0},"-3.0":{"hdp":-3.0,"home":2.26,"away":1.684,"max":500.0},"-3.5":{"hdp":-3.5,"home":2.36,"away":1.625,"max":500.0}},"totals":{"57.0":{"points":57.0,"over":1.97,"under":1.917,"max":500.0},"55.0":{"points":55.0,"over":1.671,"under":2.29,"max":500.0},"55.5":{"points":55.5,"over":1.746,"under":2.17,"max":500.0},"56.0":{"points":56.0,"over":1.813,"under":2.09,"max":500.0},"56.5":{"points":56.5,"over":1.892,"under":1.99,"max":500.0},"57.5":{"points":57.5,"over":2.05,"under":1.84,"max":500.0},"58.0":{"points":58.0,"over":2.16,"under":1.757,"max":500.0},"58.5":{"points":58.5,"over":2.25,"under":1.694,"max":500.0},"59.0":{"points":59.0,"over":2.39,"under":1.621,"max":500.0}},"team_total":{"home":{"points":29.5,"over":2.0,"under":1.854},"away":{"points":28.0,"over":2.02,"under":1.84}},"meta":{"number":4,"max_spread":500.0,"max_money_line":500.0,"max_total":500.0,"max_team_total":500.0}}}}]}

Does that query string above make sense now?

I’ll convert that data to JSON below and peak at it.

current_json = current.json()
current_json
{'sport_id': 3,
 'sport_name': 'Basketball',
 'last': 1681571705,
 'last_call': 1681571706,
 'events': [{'event_id': 1570671674,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-15T17:10:00',
   'last': 1681571077,
   'home': 'Philadelphia 76ers',
   'away': 'Brooklyn Nets',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2067360473,
     'number': 0,
     'cutoff': '2023-04-15T17:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.263, 'draw': None, 'away': 4.18},
     'spreads': {'-8.5': {'hdp': -8.5,
       'home': 1.909,
       'away': 2.0,
       'max': 25000.0},
      '-6.0': {'hdp': -6.0, 'home': 1.588, 'away': 2.48, 'max': 25000.0},
      '-6.5': {'hdp': -6.5, 'home': 1.636, 'away': 2.37, 'max': 25000.0},
      '-7.0': {'hdp': -7.0, 'home': 1.684, 'away': 2.28, 'max': 25000.0},
      '-7.5': {'hdp': -7.5, 'home': 1.746, 'away': 2.19, 'max': 25000.0},
      '-8.0': {'hdp': -8.0, 'home': 1.819, 'away': 2.09, 'max': 25000.0},
      '-9.0': {'hdp': -9.0, 'home': 1.99, 'away': 1.9, 'max': 25000.0},
      '-9.5': {'hdp': -9.5, 'home': 2.08, 'away': 1.826, 'max': 25000.0},
      '-10.0': {'hdp': -10.0, 'home': 2.16, 'away': 1.757, 'max': 25000.0},
      '-10.5': {'hdp': -10.5, 'home': 2.25, 'away': 1.704, 'max': 25000.0},
      '-11.0': {'hdp': -11.0, 'home': 2.34, 'away': 1.653, 'max': 25000.0}},
     'totals': {'213.5': {'points': 213.5,
       'over': 1.862,
       'under': 2.03,
       'max': 5000.0},
      '211.0': {'points': 211.0, 'over': 1.632, 'under': 2.35, 'max': 5000.0},
      '211.5': {'points': 211.5, 'over': 1.68, 'under': 2.27, 'max': 5000.0},
      '212.0': {'points': 212.0, 'over': 1.714, 'under': 2.21, 'max': 5000.0},
      '212.5': {'points': 212.5, 'over': 1.763, 'under': 2.15, 'max': 5000.0},
      '213.0': {'points': 213.0, 'over': 1.806, 'under': 2.09, 'max': 5000.0},
      '214.0': {'points': 214.0, 'over': 1.9, 'under': 1.98, 'max': 5000.0},
      '214.5': {'points': 214.5, 'over': 1.952, 'under': 1.925, 'max': 5000.0},
      '215.0': {'points': 215.0, 'over': 2.01, 'under': 1.869, 'max': 5000.0},
      '215.5': {'points': 215.5, 'over': 2.06, 'under': 1.826, 'max': 5000.0},
      '216.0': {'points': 216.0, 'over': 2.11, 'under': 1.775, 'max': 5000.0}},
     'team_total': {'home': {'points': 111.5, 'over': 1.909, 'under': 1.943},
      'away': {'points': 102.5, 'over': 1.869, 'under': 1.98}},
     'meta': {'number': 0,
      'max_spread': 25000.0,
      'max_money_line': 15000.0,
      'max_total': 5000.0,
      'max_team_total': 2000.0}},
    'num_1': {'line_id': 2067360475,
     'number': 1,
     'cutoff': '2023-04-15T17:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.363, 'draw': None, 'away': 3.32},
     'spreads': {'-5.0': {'hdp': -5.0,
       'home': 1.909,
       'away': 1.97,
       'max': 6500.0},
      '-3.0': {'hdp': -3.0, 'home': 1.649, 'away': 2.32, 'max': 6500.0},
      '-3.5': {'hdp': -3.5, 'home': 1.699, 'away': 2.23, 'max': 6500.0},
      '-4.0': {'hdp': -4.0, 'home': 1.763, 'away': 2.14, 'max': 6500.0},
      '-4.5': {'hdp': -4.5, 'home': 1.833, 'away': 2.06, 'max': 6500.0},
      '-5.5': {'hdp': -5.5, 'home': 1.99, 'away': 1.892, 'max': 6500.0},
      '-6.0': {'hdp': -6.0, 'home': 2.07, 'away': 1.819, 'max': 6500.0},
      '-6.5': {'hdp': -6.5, 'home': 2.15, 'away': 1.751, 'max': 6500.0},
      '-7.0': {'hdp': -7.0, 'home': 2.24, 'away': 1.694, 'max': 6500.0}},
     'totals': {'109.0': {'points': 109.0,
       'over': 1.9,
       'under': 1.99,
       'max': 2000.0},
      '107.0': {'points': 107.0, 'over': 1.675, 'under': 2.28, 'max': 2000.0},
      '107.5': {'points': 107.5, 'over': 1.735, 'under': 2.19, 'max': 2000.0},
      '108.0': {'points': 108.0, 'over': 1.781, 'under': 2.12, 'max': 2000.0},
      '108.5': {'points': 108.5, 'over': 1.84, 'under': 2.05, 'max': 2000.0},
      '109.5': {'points': 109.5, 'over': 1.952, 'under': 1.917, 'max': 2000.0},
      '110.0': {'points': 110.0, 'over': 2.02, 'under': 1.862, 'max': 2000.0},
      '110.5': {'points': 110.5, 'over': 2.08, 'under': 1.806, 'max': 2000.0},
      '111.0': {'points': 111.0, 'over': 2.16, 'under': 1.746, 'max': 2000.0}},
     'team_total': {'home': {'points': 57.5, 'over': 1.943, 'under': 1.909},
      'away': {'points': 52.5, 'over': 2.01, 'under': 1.854}},
     'meta': {'number': 1,
      'max_spread': 6500.0,
      'max_money_line': 3500.0,
      'max_total': 2000.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2067360478,
     'number': 3,
     'cutoff': '2023-04-15T17:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.465, 'draw': None, 'away': 2.86},
     'spreads': {'-3.0': {'hdp': -3.0,
       'home': 1.909,
       'away': 1.98,
       'max': 3000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.578, 'away': 2.47, 'max': 3000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.657, 'away': 2.3, 'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.724, 'away': 2.2, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.813, 'away': 2.07, 'max': 3000.0},
      '-3.5': {'hdp': -3.5, 'home': 1.99, 'away': 1.877, 'max': 3000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.11, 'away': 1.787, 'max': 3000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.2, 'away': 1.714, 'max': 3000.0},
      '-5.0': {'hdp': -5.0, 'home': 2.35, 'away': 1.632, 'max': 3000.0}},
     'totals': {'55.0': {'points': 55.0,
       'over': 1.961,
       'under': 1.925,
       'max': 1000.0},
      '53.0': {'points': 53.0, 'over': 1.675, 'under': 2.29, 'max': 1000.0},
      '53.5': {'points': 53.5, 'over': 1.746, 'under': 2.17, 'max': 1000.0},
      '54.0': {'points': 54.0, 'over': 1.806, 'under': 2.09, 'max': 1000.0},
      '54.5': {'points': 54.5, 'over': 1.877, 'under': 2.0, 'max': 1000.0},
      '55.5': {'points': 55.5, 'over': 2.04, 'under': 1.847, 'max': 1000.0},
      '56.0': {'points': 56.0, 'over': 2.14, 'under': 1.769, 'max': 1000.0},
      '56.5': {'points': 56.5, 'over': 2.22, 'under': 1.714, 'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 2.35, 'under': 1.641, 'max': 1000.0}},
     'team_total': {'home': {'points': 29.0, 'over': 1.917, 'under': 1.934},
      'away': {'points': 26.0, 'over': 1.98, 'under': 1.877}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2067360489,
     'number': 4,
     'cutoff': '2023-04-15T17:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.581, 'draw': None, 'away': 2.51},
     'spreads': {'-2.5': {'hdp': -2.5,
       'home': 1.99,
       'away': 1.9,
       'max': 500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.649, 'away': 2.32, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.709, 'away': 2.21, 'max': 500.0},
      '-1.5': {'hdp': -1.5, 'home': 1.8, 'away': 2.09, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 1.884, 'away': 1.99, 'max': 500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.09, 'away': 1.8, 'max': 500.0},
      '-3.5': {'hdp': -3.5, 'home': 2.19, 'away': 1.729, 'max': 500.0},
      '-4.0': {'hdp': -4.0, 'home': 2.33, 'away': 1.645, 'max': 500.0},
      '-4.5': {'hdp': -4.5, 'home': 2.44, 'away': 1.591, 'max': 500.0}},
     'totals': {'54.5': {'points': 54.5,
       'over': 1.943,
       'under': 1.943,
       'max': 500.0},
      '52.5': {'points': 52.5, 'over': 1.653, 'under': 2.33, 'max': 500.0},
      '53.0': {'points': 53.0, 'over': 1.704, 'under': 2.23, 'max': 500.0},
      '53.5': {'points': 53.5, 'over': 1.787, 'under': 2.12, 'max': 500.0},
      '54.0': {'points': 54.0, 'over': 1.862, 'under': 2.03, 'max': 500.0},
      '55.0': {'points': 55.0, 'over': 2.04, 'under': 1.847, 'max': 500.0},
      '55.5': {'points': 55.5, 'over': 2.13, 'under': 1.775, 'max': 500.0},
      '56.0': {'points': 56.0, 'over': 2.25, 'under': 1.694, 'max': 500.0},
      '56.5': {'points': 56.5, 'over': 2.36, 'under': 1.636, 'max': 500.0}},
     'team_total': {'home': {'points': 28.5, 'over': 1.961, 'under': 1.892},
      'away': {'points': 26.5, 'over': 2.03, 'under': 1.833}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1570671683,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-16T00:40:00',
   'last': 1681570378,
   'home': 'Sacramento Kings',
   'away': 'Golden State Warriors',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2067336986,
     'number': 0,
     'cutoff': '2023-04-16T00:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.952, 'draw': None, 'away': 1.952},
     'spreads': {'-1.0': {'hdp': -1.0,
       'home': 1.98,
       'away': 1.925,
       'max': 25000.0},
      '3.0': {'hdp': 3.0, 'home': 1.657, 'away': 2.33, 'max': 25000.0},
      '2.5': {'hdp': 2.5, 'home': 1.709, 'away': 2.23, 'max': 25000.0},
      '2.0': {'hdp': 2.0, 'home': 1.763, 'away': 2.15, 'max': 25000.0},
      '1.5': {'hdp': 1.5, 'home': 1.826, 'away': 2.08, 'max': 25000.0},
      '1.0': {'hdp': 1.0, 'home': 1.869, 'away': 2.03, 'max': 25000.0},
      '-1.5': {'hdp': -1.5, 'home': 2.04, 'away': 1.869, 'max': 25000.0},
      '-2.0': {'hdp': -2.0, 'home': 2.12, 'away': 1.793, 'max': 25000.0},
      '-2.5': {'hdp': -2.5, 'home': 2.2, 'away': 1.735, 'max': 25000.0},
      '-3.0': {'hdp': -3.0, 'home': 2.29, 'away': 1.675, 'max': 25000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.4, 'away': 1.625, 'max': 25000.0}},
     'totals': {'237.5': {'points': 237.5,
       'over': 1.917,
       'under': 1.97,
       'max': 5000.0},
      '235.0': {'points': 235.0, 'over': 1.689, 'under': 2.25, 'max': 5000.0},
      '235.5': {'points': 235.5, 'over': 1.735, 'under': 2.18, 'max': 5000.0},
      '236.0': {'points': 236.0, 'over': 1.769, 'under': 2.13, 'max': 5000.0},
      '236.5': {'points': 236.5, 'over': 1.819, 'under': 2.08, 'max': 5000.0},
      '237.0': {'points': 237.0, 'over': 1.862, 'under': 2.02, 'max': 5000.0},
      '238.0': {'points': 238.0, 'over': 1.961, 'under': 1.917, 'max': 5000.0},
      '238.5': {'points': 238.5, 'over': 2.01, 'under': 1.877, 'max': 5000.0},
      '239.0': {'points': 239.0, 'over': 2.06, 'under': 1.826, 'max': 5000.0},
      '239.5': {'points': 239.5, 'over': 2.11, 'under': 1.787, 'max': 5000.0},
      '240.0': {'points': 240.0, 'over': 2.17, 'under': 1.74, 'max': 5000.0}},
     'team_total': {'home': {'points': 118.5, 'over': 1.862, 'under': 2.0},
      'away': {'points': 118.5, 'over': 1.877, 'under': 1.98}},
     'meta': {'number': 0,
      'max_spread': 25000.0,
      'max_money_line': 15000.0,
      'max_total': 5000.0,
      'max_team_total': 2000.0}},
    'num_1': {'line_id': 2067336990,
     'number': 1,
     'cutoff': '2023-04-16T00:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.892, 'draw': None, 'away': 2.0},
     'spreads': {'-0.5': {'hdp': -0.5,
       'home': 1.97,
       'away': 1.917,
       'max': 6500.0},
      '2.0': {'hdp': 2.0, 'home': 1.645, 'away': 2.33, 'max': 6500.0},
      '1.5': {'hdp': 1.5, 'home': 1.694, 'away': 2.24, 'max': 6500.0},
      '1.0': {'hdp': 1.0, 'home': 1.751, 'away': 2.16, 'max': 6500.0},
      '0.5': {'hdp': 0.5, 'home': 1.819, 'away': 2.08, 'max': 6500.0},
      '-1.0': {'hdp': -1.0, 'home': 2.05, 'away': 1.833, 'max': 6500.0},
      '-1.5': {'hdp': -1.5, 'home': 2.13, 'away': 1.769, 'max': 6500.0},
      '-2.0': {'hdp': -2.0, 'home': 2.22, 'away': 1.704, 'max': 6500.0},
      '-2.5': {'hdp': -2.5, 'home': 2.32, 'away': 1.653, 'max': 6500.0}},
     'totals': {'117.5': {'points': 117.5,
       'over': 1.952,
       'under': 1.934,
       'max': 2000.0},
      '115.5': {'points': 115.5, 'over': 1.699, 'under': 2.24, 'max': 2000.0},
      '116.0': {'points': 116.0, 'over': 1.746, 'under': 2.16, 'max': 2000.0},
      '116.5': {'points': 116.5, 'over': 1.813, 'under': 2.08, 'max': 2000.0},
      '117.0': {'points': 117.0, 'over': 1.877, 'under': 2.0, 'max': 2000.0},
      '118.0': {'points': 118.0, 'over': 2.02, 'under': 1.862, 'max': 2000.0},
      '118.5': {'points': 118.5, 'over': 2.09, 'under': 1.806, 'max': 2000.0},
      '119.0': {'points': 119.0, 'over': 2.17, 'under': 1.746, 'max': 2000.0},
      '119.5': {'points': 119.5, 'over': 2.24, 'under': 1.699, 'max': 2000.0}},
     'team_total': {'home': {'points': 58.5, 'over': 1.847, 'under': 2.01},
      'away': {'points': 58.5, 'over': 1.917, 'under': 1.934}},
     'meta': {'number': 1,
      'max_spread': 6500.0,
      'max_money_line': 3500.0,
      'max_total': 2000.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2067327510,
     'number': 3,
     'cutoff': '2023-04-16T00:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.917, 'draw': None, 'away': 1.97},
     'spreads': {'-0.5': {'hdp': -0.5,
       'home': 2.02,
       'away': 1.869,
       'max': 3000.0},
      '2.0': {'hdp': 2.0, 'home': 1.574, 'away': 2.48, 'max': 3000.0},
      '1.5': {'hdp': 1.5, 'home': 1.657, 'away': 2.3, 'max': 3000.0},
      '1.0': {'hdp': 1.0, 'home': 1.729, 'away': 2.19, 'max': 3000.0},
      '0.5': {'hdp': 0.5, 'home': 1.819, 'away': 2.06, 'max': 3000.0},
      '-1.0': {'hdp': -1.0, 'home': 2.12, 'away': 1.775, 'max': 3000.0},
      '-1.5': {'hdp': -1.5, 'home': 2.22, 'away': 1.709, 'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 2.37, 'away': 1.625, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 2.48, 'away': 1.578, 'max': 3000.0}},
     'totals': {'58.5': {'points': 58.5,
       'over': 1.909,
       'under': 1.98,
       'max': 1000.0},
      '56.5': {'points': 56.5, 'over': 1.649, 'under': 2.33, 'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 1.694, 'under': 2.25, 'max': 1000.0},
      '57.5': {'points': 57.5, 'over': 1.763, 'under': 2.15, 'max': 1000.0},
      '58.0': {'points': 58.0, 'over': 1.826, 'under': 2.07, 'max': 1000.0},
      '59.0': {'points': 59.0, 'over': 1.98, 'under': 1.9, 'max': 1000.0},
      '59.5': {'points': 59.5, 'over': 2.05, 'under': 1.833, 'max': 1000.0},
      '60.0': {'points': 60.0, 'over': 2.15, 'under': 1.757, 'max': 1000.0},
      '60.5': {'points': 60.5, 'over': 2.24, 'under': 1.704, 'max': 1000.0}},
     'team_total': {'home': {'points': 29.5, 'over': 1.934, 'under': 1.917},
      'away': {'points': 29.5, 'over': 1.952, 'under': 1.9}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2067327542,
     'number': 4,
     'cutoff': '2023-04-16T00:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.925, 'draw': None, 'away': 1.961},
     'spreads': {'-0.5': {'hdp': -0.5,
       'home': 2.02,
       'away': 1.869,
       'max': 500.0},
      '2.0': {'hdp': 2.0, 'home': 1.598, 'away': 2.43, 'max': 500.0},
      '1.5': {'hdp': 1.5, 'home': 1.675, 'away': 2.27, 'max': 500.0},
      '1.0': {'hdp': 1.0, 'home': 1.746, 'away': 2.17, 'max': 500.0},
      '0.5': {'hdp': 0.5, 'home': 1.833, 'away': 2.05, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 2.13, 'away': 1.769, 'max': 500.0},
      '-1.5': {'hdp': -1.5, 'home': 2.23, 'away': 1.704, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 2.38, 'away': 1.621, 'max': 500.0},
      '-2.5': {'hdp': -2.5, 'home': 2.49, 'away': 1.571, 'max': 500.0}},
     'totals': {'58.5': {'points': 58.5,
       'over': 2.01,
       'under': 1.877,
       'max': 500.0},
      '56.5': {'points': 56.5, 'over': 1.714, 'under': 2.21, 'max': 500.0},
      '57.0': {'points': 57.0, 'over': 1.775, 'under': 2.12, 'max': 500.0},
      '57.5': {'points': 57.5, 'over': 1.854, 'under': 2.03, 'max': 500.0},
      '58.0': {'points': 58.0, 'over': 1.925, 'under': 1.952, 'max': 500.0},
      '59.0': {'points': 59.0, 'over': 2.11, 'under': 1.793, 'max': 500.0},
      '59.5': {'points': 59.5, 'over': 2.19, 'under': 1.735, 'max': 500.0},
      '60.0': {'points': 60.0, 'over': 2.31, 'under': 1.662, 'max': 500.0},
      '60.5': {'points': 60.5, 'over': 2.41, 'under': 1.613, 'max': 500.0}},
     'team_total': {'home': {'points': 29.5, 'over': 2.02, 'under': 1.84},
      'away': {'points': 29.5, 'over': 2.04, 'under': 1.826}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1570671684,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-17T00:10:00',
   'last': 1681568411,
   'home': 'Phoenix Suns',
   'away': 'Los Angeles Clippers',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2066957075,
     'number': 0,
     'cutoff': '2023-04-17T00:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.358, 'draw': None, 'away': 3.42},
     'spreads': {'-7.5': {'hdp': -7.5,
       'home': 2.0,
       'away': 1.909,
       'max': 20000.0},
      '-5.0': {'hdp': -5.0, 'home': 1.653, 'away': 2.34, 'max': 20000.0},
      '-5.5': {'hdp': -5.5, 'home': 1.704, 'away': 2.24, 'max': 20000.0},
      '-6.0': {'hdp': -6.0, 'home': 1.757, 'away': 2.16, 'max': 20000.0},
      '-6.5': {'hdp': -6.5, 'home': 1.826, 'away': 2.08, 'max': 20000.0},
      '-7.0': {'hdp': -7.0, 'home': 1.909, 'away': 1.99, 'max': 20000.0},
      '-8.0': {'hdp': -8.0, 'home': 2.1, 'away': 1.819, 'max': 20000.0},
      '-8.5': {'hdp': -8.5, 'home': 2.19, 'away': 1.746, 'max': 20000.0},
      '-9.0': {'hdp': -9.0, 'home': 2.28, 'away': 1.684, 'max': 20000.0},
      '-9.5': {'hdp': -9.5, 'home': 2.38, 'away': 1.632, 'max': 20000.0},
      '-10.0': {'hdp': -10.0, 'home': 2.48, 'away': 1.588, 'max': 20000.0}},
     'totals': {'226.0': {'points': 226.0,
       'over': 1.97,
       'under': 1.917,
       'max': 5000.0},
      '223.5': {'points': 223.5, 'over': 1.735, 'under': 2.18, 'max': 5000.0},
      '224.0': {'points': 224.0, 'over': 1.769, 'under': 2.13, 'max': 5000.0},
      '224.5': {'points': 224.5, 'over': 1.819, 'under': 2.07, 'max': 5000.0},
      '225.0': {'points': 225.0, 'over': 1.869, 'under': 2.02, 'max': 5000.0},
      '225.5': {'points': 225.5, 'over': 1.917, 'under': 1.961, 'max': 5000.0},
      '226.5': {'points': 226.5, 'over': 2.02, 'under': 1.862, 'max': 5000.0},
      '227.0': {'points': 227.0, 'over': 2.08, 'under': 1.813, 'max': 5000.0},
      '227.5': {'points': 227.5, 'over': 2.13, 'under': 1.769, 'max': 5000.0},
      '228.0': {'points': 228.0, 'over': 2.19, 'under': 1.729, 'max': 5000.0},
      '228.5': {'points': 228.5, 'over': 2.24, 'under': 1.694, 'max': 5000.0}},
     'team_total': {'home': {'points': 116.5, 'over': 1.99, 'under': 1.869},
      'away': {'points': 109.5, 'over': 1.917, 'under': 1.934}},
     'meta': {'number': 0,
      'max_spread': 20000.0,
      'max_money_line': 12000.0,
      'max_total': 5000.0,
      'max_team_total': 2000.0}},
    'num_1': {'line_id': 2065216317,
     'number': 1,
     'cutoff': '2023-04-17T00:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.446, 'draw': None, 'away': 2.93},
     'spreads': {'-4.5': {'hdp': -4.5,
       'home': 1.97,
       'away': 1.917,
       'max': 4000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.694, 'away': 2.24, 'max': 4000.0},
      '-3.0': {'hdp': -3.0, 'home': 1.746, 'away': 2.15, 'max': 4000.0},
      '-3.5': {'hdp': -3.5, 'home': 1.813, 'away': 2.07, 'max': 4000.0},
      '-4.0': {'hdp': -4.0, 'home': 1.884, 'away': 1.99, 'max': 4000.0},
      '-5.0': {'hdp': -5.0, 'home': 2.05, 'away': 1.84, 'max': 4000.0},
      '-5.5': {'hdp': -5.5, 'home': 2.13, 'away': 1.769, 'max': 4000.0},
      '-6.0': {'hdp': -6.0, 'home': 2.22, 'away': 1.704, 'max': 4000.0},
      '-6.5': {'hdp': -6.5, 'home': 2.31, 'away': 1.653, 'max': 4000.0}},
     'totals': {'110.5': {'points': 110.5,
       'over': 1.97,
       'under': 1.917,
       'max': 1500.0},
      '108.5': {'points': 108.5, 'over': 1.699, 'under': 2.24, 'max': 1500.0},
      '109.0': {'points': 109.0, 'over': 1.751, 'under': 2.16, 'max': 1500.0},
      '109.5': {'points': 109.5, 'over': 1.819, 'under': 2.07, 'max': 1500.0},
      '110.0': {'points': 110.0, 'over': 1.884, 'under': 1.99, 'max': 1500.0},
      '111.0': {'points': 111.0, 'over': 2.03, 'under': 1.854, 'max': 1500.0},
      '111.5': {'points': 111.5, 'over': 2.1, 'under': 1.8, 'max': 1500.0},
      '112.0': {'points': 112.0, 'over': 2.18, 'under': 1.735, 'max': 1500.0},
      '112.5': {'points': 112.5, 'over': 2.25, 'under': 1.694, 'max': 1500.0}},
     'team_total': {'home': {'points': 57.5, 'over': 1.952, 'under': 1.9},
      'away': {'points': 53.5, 'over': 2.02, 'under': 1.84}},
     'meta': {'number': 1,
      'max_spread': 4000.0,
      'max_money_line': 2000.0,
      'max_total': 1500.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2066958217,
     'number': 3,
     'cutoff': '2023-04-17T00:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.543, 'draw': None, 'away': 2.61},
     'spreads': {'-2.5': {'hdp': -2.5,
       'home': 1.943,
       'away': 1.943,
       'max': 3000.0},
      '-0.5': {'hdp': -0.5, 'home': 1.613, 'away': 2.39, 'max': 3000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.671, 'away': 2.28, 'max': 3000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.763, 'away': 2.14, 'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.84, 'away': 2.04, 'max': 3000.0},
      '-3.0': {'hdp': -3.0, 'home': 2.04, 'away': 1.84, 'max': 3000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.14, 'away': 1.763, 'max': 3000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.27, 'away': 1.675, 'max': 3000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.38, 'away': 1.621, 'max': 3000.0}},
     'totals': {'55.5': {'points': 55.5,
       'over': 1.943,
       'under': 1.943,
       'max': 1000.0},
      '53.5': {'points': 53.5, 'over': 1.671, 'under': 2.29, 'max': 1000.0},
      '54.0': {'points': 54.0, 'over': 1.724, 'under': 2.2, 'max': 1000.0},
      '54.5': {'points': 54.5, 'over': 1.8, 'under': 2.1, 'max': 1000.0},
      '55.0': {'points': 55.0, 'over': 1.862, 'under': 2.02, 'max': 1000.0},
      '56.0': {'points': 56.0, 'over': 2.03, 'under': 1.854, 'max': 1000.0},
      '56.5': {'points': 56.5, 'over': 2.11, 'under': 1.787, 'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 2.21, 'under': 1.719, 'max': 1000.0},
      '57.5': {'points': 57.5, 'over': 2.3, 'under': 1.666, 'max': 1000.0}},
     'team_total': {'home': {'points': 29.0, 'over': 1.934, 'under': 1.917},
      'away': {'points': 26.5, 'over': 1.925, 'under': 1.925}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2067164531,
     'number': 4,
     'cutoff': '2023-04-17T00:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.649, 'draw': None, 'away': 2.36},
     'spreads': {'-1.5': {'hdp': -1.5,
       'home': 1.892,
       'away': 2.0,
       'max': 500.0},
      '1.0': {'hdp': 1.0, 'home': 1.515, 'away': 2.63, 'max': 500.0},
      '0.5': {'hdp': 0.5, 'home': 1.588, 'away': 2.45, 'max': 500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.724, 'away': 2.2, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.793, 'away': 2.1, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 1.98, 'away': 1.892, 'max': 500.0},
      '-2.5': {'hdp': -2.5, 'home': 2.08, 'away': 1.806, 'max': 500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.2, 'away': 1.719, 'max': 500.0},
      '-3.5': {'hdp': -3.5, 'home': 2.31, 'away': 1.653, 'max': 500.0}},
     'totals': {'55.0': {'points': 55.0,
       'over': 1.97,
       'under': 1.917,
       'max': 500.0},
      '53.0': {'points': 53.0, 'over': 1.649, 'under': 2.33, 'max': 500.0},
      '53.5': {'points': 53.5, 'over': 1.724, 'under': 2.2, 'max': 500.0},
      '54.0': {'points': 54.0, 'over': 1.793, 'under': 2.11, 'max': 500.0},
      '54.5': {'points': 54.5, 'over': 1.884, 'under': 2.0, 'max': 500.0},
      '55.5': {'points': 55.5, 'over': 2.06, 'under': 1.833, 'max': 500.0},
      '56.0': {'points': 56.0, 'over': 2.17, 'under': 1.751, 'max': 500.0},
      '56.5': {'points': 56.5, 'over': 2.26, 'under': 1.689, 'max': 500.0},
      '57.0': {'points': 57.0, 'over': 2.4, 'under': 1.617, 'max': 500.0}},
     'team_total': {'home': {'points': 28.5, 'over': 1.961, 'under': 1.892},
      'away': {'points': 27.0, 'over': 2.06, 'under': 1.806}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1570671685,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-15T22:10:00',
   'last': 1681571621,
   'home': 'Cleveland Cavaliers',
   'away': 'New York Knicks',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2067381755,
     'number': 0,
     'cutoff': '2023-04-15T22:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.473, 'draw': None, 'away': 2.87},
     'spreads': {'-5.5': {'hdp': -5.5,
       'home': 1.961,
       'away': 1.943,
       'max': 15000.0},
      '-3.0': {'hdp': -3.0, 'home': 1.625, 'away': 2.4, 'max': 15000.0},
      '-3.5': {'hdp': -3.5, 'home': 1.675, 'away': 2.3, 'max': 15000.0},
      '-4.0': {'hdp': -4.0, 'home': 1.729, 'away': 2.21, 'max': 15000.0},
      '-4.5': {'hdp': -4.5, 'home': 1.793, 'away': 2.12, 'max': 15000.0},
      '-5.0': {'hdp': -5.0, 'home': 1.869, 'away': 2.03, 'max': 15000.0},
      '-6.0': {'hdp': -6.0, 'home': 2.05, 'away': 1.854, 'max': 15000.0},
      '-6.5': {'hdp': -6.5, 'home': 2.14, 'away': 1.781, 'max': 15000.0},
      '-7.0': {'hdp': -7.0, 'home': 2.23, 'away': 1.714, 'max': 15000.0},
      '-7.5': {'hdp': -7.5, 'home': 2.32, 'away': 1.662, 'max': 15000.0},
      '-8.0': {'hdp': -8.0, 'home': 2.42, 'away': 1.613, 'max': 15000.0}},
     'totals': {'217.0': {'points': 217.0,
       'over': 1.917,
       'under': 1.97,
       'max': 4000.0},
      '214.5': {'points': 214.5, 'over': 1.704, 'under': 2.23, 'max': 4000.0},
      '215.0': {'points': 215.0, 'over': 1.74, 'under': 2.18, 'max': 4000.0},
      '215.5': {'points': 215.5, 'over': 1.781, 'under': 2.12, 'max': 4000.0},
      '216.0': {'points': 216.0, 'over': 1.819, 'under': 2.07, 'max': 4000.0},
      '216.5': {'points': 216.5, 'over': 1.869, 'under': 2.02, 'max': 4000.0},
      '217.5': {'points': 217.5, 'over': 1.97, 'under': 1.909, 'max': 4000.0},
      '218.0': {'points': 218.0, 'over': 2.03, 'under': 1.854, 'max': 4000.0},
      '218.5': {'points': 218.5, 'over': 2.08, 'under': 1.806, 'max': 4000.0},
      '219.0': {'points': 219.0, 'over': 2.15, 'under': 1.757, 'max': 4000.0},
      '219.5': {'points': 219.5, 'over': 2.2, 'under': 1.719, 'max': 4000.0}},
     'team_total': {'home': {'points': 110.5, 'over': 1.84, 'under': 2.02},
      'away': {'points': 106.5, 'over': 1.98, 'under': 1.877}},
     'meta': {'number': 0,
      'max_spread': 15000.0,
      'max_money_line': 7500.0,
      'max_total': 4000.0,
      'max_team_total': 2000.0}},
    'num_1': {'line_id': 2067398065,
     'number': 1,
     'cutoff': '2023-04-15T22:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.552, 'draw': None, 'away': 2.58},
     'spreads': {'-2.5': {'hdp': -2.5,
       'home': 1.869,
       'away': 2.03,
       'max': 5000.0},
      '-0.5': {'hdp': -0.5, 'home': 1.613, 'away': 2.39, 'max': 5000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.666, 'away': 2.29, 'max': 5000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.724, 'away': 2.2, 'max': 5000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.793, 'away': 2.11, 'max': 5000.0},
      '-3.0': {'hdp': -3.0, 'home': 1.943, 'away': 1.934, 'max': 5000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.01, 'away': 1.862, 'max': 5000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.09, 'away': 1.793, 'max': 5000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.18, 'away': 1.735, 'max': 5000.0}},
     'totals': {'111.0': {'points': 111.0,
       'over': 2.0,
       'under': 1.892,
       'max': 2000.0},
      '109.0': {'points': 109.0, 'over': 1.751, 'under': 2.16, 'max': 2000.0},
      '109.5': {'points': 109.5, 'over': 1.806, 'under': 2.08, 'max': 2000.0},
      '110.0': {'points': 110.0, 'over': 1.862, 'under': 2.02, 'max': 2000.0},
      '110.5': {'points': 110.5, 'over': 1.917, 'under': 1.961, 'max': 2000.0},
      '111.5': {'points': 111.5, 'over': 2.06, 'under': 1.826, 'max': 2000.0},
      '112.0': {'points': 112.0, 'over': 2.16, 'under': 1.757, 'max': 2000.0},
      '112.5': {'points': 112.5, 'over': 2.23, 'under': 1.704, 'max': 2000.0},
      '113.0': {'points': 113.0, 'over': 2.34, 'under': 1.645, 'max': 2000.0}},
     'team_total': {'home': {'points': 57.0, 'over': 1.925, 'under': 1.925},
      'away': {'points': 53.5, 'over': 1.869, 'under': 1.98}},
     'meta': {'number': 1,
      'max_spread': 5000.0,
      'max_money_line': 2000.0,
      'max_total': 2000.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2067372965,
     'number': 3,
     'cutoff': '2023-04-15T22:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.625, 'draw': None, 'away': 2.41},
     'spreads': {'-2.0': {'hdp': -2.0,
       'home': 1.952,
       'away': 1.934,
       'max': 3000.0},
      '0.5': {'hdp': 0.5, 'home': 1.558, 'away': 2.52, 'max': 3000.0},
      '-0.5': {'hdp': -0.5, 'home': 1.694, 'away': 2.24, 'max': 3000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.763, 'away': 2.14, 'max': 3000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.854, 'away': 2.02, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 2.04, 'away': 1.833, 'max': 3000.0},
      '-3.0': {'hdp': -3.0, 'home': 2.17, 'away': 1.746, 'max': 3000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.27, 'away': 1.675, 'max': 3000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.43, 'away': 1.595, 'max': 3000.0}},
     'totals': {'56.0': {'points': 56.0,
       'over': 2.01,
       'under': 1.884,
       'max': 1000.0},
      '54.0': {'points': 54.0, 'over': 1.704, 'under': 2.24, 'max': 1000.0},
      '54.5': {'points': 54.5, 'over': 1.775, 'under': 2.13, 'max': 1000.0},
      '55.0': {'points': 55.0, 'over': 1.84, 'under': 2.05, 'max': 1000.0},
      '55.5': {'points': 55.5, 'over': 1.917, 'under': 1.961, 'max': 1000.0},
      '56.5': {'points': 56.5, 'over': 2.1, 'under': 1.8, 'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 2.21, 'under': 1.729, 'max': 1000.0},
      '57.5': {'points': 57.5, 'over': 2.29, 'under': 1.671, 'max': 1000.0},
      '58.0': {'points': 58.0, 'over': 2.43, 'under': 1.602, 'max': 1000.0}},
     'team_total': {'home': {'points': 29.0, 'over': 1.98, 'under': 1.877},
      'away': {'points': 26.5, 'over': 1.854, 'under': 2.0}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2067398089,
     'number': 4,
     'cutoff': '2023-04-15T22:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.694, 'draw': None, 'away': 2.27},
     'spreads': {'-1.0': {'hdp': -1.0,
       'home': 1.862,
       'away': 2.03,
       'max': 500.0},
      '1.5': {'hdp': 1.5, 'home': 1.51, 'away': 2.65, 'max': 500.0},
      '1.0': {'hdp': 1.0, 'home': 1.552, 'away': 2.53, 'max': 500.0},
      '0.5': {'hdp': 0.5, 'home': 1.632, 'away': 2.37, 'max': 500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.775, 'away': 2.13, 'max': 500.0},
      '-1.5': {'hdp': -1.5, 'home': 1.943, 'away': 1.925, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 2.05, 'away': 1.833, 'max': 500.0},
      '-2.5': {'hdp': -2.5, 'home': 2.15, 'away': 1.751, 'max': 500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.28, 'away': 1.671, 'max': 500.0}},
     'totals': {'55.5': {'points': 55.5,
       'over': 1.99,
       'under': 1.9,
       'max': 500.0},
      '53.5': {'points': 53.5, 'over': 1.671, 'under': 2.29, 'max': 500.0},
      '54.0': {'points': 54.0, 'over': 1.724, 'under': 2.2, 'max': 500.0},
      '54.5': {'points': 54.5, 'over': 1.806, 'under': 2.09, 'max': 500.0},
      '55.0': {'points': 55.0, 'over': 1.884, 'under': 1.99, 'max': 500.0},
      '56.0': {'points': 56.0, 'over': 2.09, 'under': 1.806, 'max': 500.0},
      '56.5': {'points': 56.5, 'over': 2.19, 'under': 1.74, 'max': 500.0},
      '57.0': {'points': 57.0, 'over': 2.32, 'under': 1.657, 'max': 500.0},
      '57.5': {'points': 57.5, 'over': 2.43, 'under': 1.606, 'max': 500.0}},
     'team_total': {'home': {'points': 28.5, 'over': 1.97, 'under': 1.884},
      'away': {'points': 27.0, 'over': 1.952, 'under': 1.9}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1570794181,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-15T19:40:00',
   'last': 1681570462,
   'home': 'Boston Celtics',
   'away': 'Atlanta Hawks',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2067326363,
     'number': 0,
     'cutoff': '2023-04-15T19:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.247, 'draw': None, 'away': 4.36},
     'spreads': {'-9.5': {'hdp': -9.5,
       'home': 1.97,
       'away': 1.934,
       'max': 25000.0},
      '-7.0': {'hdp': -7.0, 'home': 1.632, 'away': 2.38, 'max': 25000.0},
      '-7.5': {'hdp': -7.5, 'home': 1.68, 'away': 2.28, 'max': 25000.0},
      '-8.0': {'hdp': -8.0, 'home': 1.735, 'away': 2.2, 'max': 25000.0},
      '-8.5': {'hdp': -8.5, 'home': 1.8, 'away': 2.11, 'max': 25000.0},
      '-9.0': {'hdp': -9.0, 'home': 1.877, 'away': 2.02, 'max': 25000.0},
      '-10.0': {'hdp': -10.0, 'home': 2.06, 'away': 1.847, 'max': 25000.0},
      '-10.5': {'hdp': -10.5, 'home': 2.15, 'away': 1.769, 'max': 25000.0},
      '-11.0': {'hdp': -11.0, 'home': 2.24, 'away': 1.709, 'max': 25000.0},
      '-11.5': {'hdp': -11.5, 'home': 2.33, 'away': 1.657, 'max': 25000.0},
      '-12.0': {'hdp': -12.0, 'home': 2.44, 'away': 1.606, 'max': 25000.0}},
     'totals': {'231.0': {'points': 231.0,
       'over': 1.98,
       'under': 1.909,
       'max': 5000.0},
      '228.5': {'points': 228.5, 'over': 1.74, 'under': 2.16, 'max': 5000.0},
      '229.0': {'points': 229.0, 'over': 1.781, 'under': 2.11, 'max': 5000.0},
      '229.5': {'points': 229.5, 'over': 1.826, 'under': 2.06, 'max': 5000.0},
      '230.0': {'points': 230.0, 'over': 1.877, 'under': 2.01, 'max': 5000.0},
      '230.5': {'points': 230.5, 'over': 1.917, 'under': 1.952, 'max': 5000.0},
      '231.5': {'points': 231.5, 'over': 2.03, 'under': 1.854, 'max': 5000.0},
      '232.0': {'points': 232.0, 'over': 2.09, 'under': 1.806, 'max': 5000.0},
      '232.5': {'points': 232.5, 'over': 2.14, 'under': 1.769, 'max': 5000.0},
      '233.0': {'points': 233.0, 'over': 2.21, 'under': 1.719, 'max': 5000.0},
      '233.5': {'points': 233.5, 'over': 2.26, 'under': 1.684, 'max': 5000.0}},
     'team_total': {'home': {'points': 119.5, 'over': 1.854, 'under': 2.0},
      'away': {'points': 110.5, 'over': 1.925, 'under': 1.925}},
     'meta': {'number': 0,
      'max_spread': 25000.0,
      'max_money_line': 15000.0,
      'max_total': 5000.0,
      'max_team_total': 2000.0}},
    'num_1': {'line_id': 2067339777,
     'number': 1,
     'cutoff': '2023-04-15T19:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.369, 'draw': None, 'away': 3.29},
     'spreads': {'-5.0': {'hdp': -5.0,
       'home': 1.917,
       'away': 1.97,
       'max': 6500.0},
      '-3.0': {'hdp': -3.0, 'home': 1.649, 'away': 2.32, 'max': 6500.0},
      '-3.5': {'hdp': -3.5, 'home': 1.704, 'away': 2.22, 'max': 6500.0},
      '-4.0': {'hdp': -4.0, 'home': 1.769, 'away': 2.14, 'max': 6500.0},
      '-4.5': {'hdp': -4.5, 'home': 1.833, 'away': 2.05, 'max': 6500.0},
      '-5.5': {'hdp': -5.5, 'home': 1.99, 'away': 1.884, 'max': 6500.0},
      '-6.0': {'hdp': -6.0, 'home': 2.07, 'away': 1.813, 'max': 6500.0},
      '-6.5': {'hdp': -6.5, 'home': 2.15, 'away': 1.746, 'max': 6500.0},
      '-7.0': {'hdp': -7.0, 'home': 2.24, 'away': 1.694, 'max': 6500.0}},
     'totals': {'118.0': {'points': 118.0,
       'over': 1.943,
       'under': 1.943,
       'max': 2000.0},
      '116.0': {'points': 116.0, 'over': 1.714, 'under': 2.22, 'max': 2000.0},
      '116.5': {'points': 116.5, 'over': 1.763, 'under': 2.14, 'max': 2000.0},
      '117.0': {'points': 117.0, 'over': 1.813, 'under': 2.08, 'max': 2000.0},
      '117.5': {'points': 117.5, 'over': 1.869, 'under': 2.01, 'max': 2000.0},
      '118.5': {'points': 118.5, 'over': 2.01, 'under': 1.869, 'max': 2000.0},
      '119.0': {'points': 119.0, 'over': 2.1, 'under': 1.8, 'max': 2000.0},
      '119.5': {'points': 119.5, 'over': 2.17, 'under': 1.746, 'max': 2000.0},
      '120.0': {'points': 120.0, 'over': 2.27, 'under': 1.68, 'max': 2000.0}},
     'team_total': {'home': {'points': 61.5, 'over': 1.877, 'under': 1.98},
      'away': {'points': 56.5, 'over': 1.961, 'under': 1.892}},
     'meta': {'number': 1,
      'max_spread': 6500.0,
      'max_money_line': 3500.0,
      'max_total': 2000.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2067247663,
     'number': 3,
     'cutoff': '2023-04-15T19:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.478, 'draw': None, 'away': 2.81},
     'spreads': {'-3.0': {'hdp': -3.0,
       'home': 1.934,
       'away': 1.952,
       'max': 3000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.598, 'away': 2.43, 'max': 3000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.68, 'away': 2.26, 'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.751, 'away': 2.16, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.84, 'away': 2.04, 'max': 3000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.02, 'away': 1.854, 'max': 3000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.14, 'away': 1.763, 'max': 3000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.24, 'away': 1.694, 'max': 3000.0},
      '-5.0': {'hdp': -5.0, 'home': 2.39, 'away': 1.613, 'max': 3000.0}},
     'totals': {'59.0': {'points': 59.0,
       'over': 1.9,
       'under': 1.98,
       'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 1.645, 'under': 2.34, 'max': 1000.0},
      '57.5': {'points': 57.5, 'over': 1.709, 'under': 2.22, 'max': 1000.0},
      '58.0': {'points': 58.0, 'over': 1.763, 'under': 2.15, 'max': 1000.0},
      '58.5': {'points': 58.5, 'over': 1.833, 'under': 2.06, 'max': 1000.0},
      '59.5': {'points': 59.5, 'over': 1.98, 'under': 1.9, 'max': 1000.0},
      '60.0': {'points': 60.0, 'over': 2.06, 'under': 1.826, 'max': 1000.0},
      '60.5': {'points': 60.5, 'over': 2.14, 'under': 1.763, 'max': 1000.0},
      '61.0': {'points': 61.0, 'over': 2.25, 'under': 1.694, 'max': 1000.0}},
     'team_total': {'home': {'points': 31.0, 'over': 1.9, 'under': 1.952},
      'away': {'points': 28.0, 'over': 1.892, 'under': 1.961}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2067247692,
     'number': 4,
     'cutoff': '2023-04-15T19:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.546, 'draw': None, 'away': 2.6},
     'spreads': {'-2.5': {'hdp': -2.5,
       'home': 1.934,
       'away': 1.952,
       'max': 500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.613, 'away': 2.39, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.666, 'away': 2.28, 'max': 500.0},
      '-1.5': {'hdp': -1.5, 'home': 1.751, 'away': 2.15, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 1.833, 'away': 2.05, 'max': 500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.02, 'away': 1.854, 'max': 500.0},
      '-3.5': {'hdp': -3.5, 'home': 2.13, 'away': 1.775, 'max': 500.0},
      '-4.0': {'hdp': -4.0, 'home': 2.25, 'away': 1.684, 'max': 500.0},
      '-4.5': {'hdp': -4.5, 'home': 2.36, 'away': 1.628, 'max': 500.0}},
     'totals': {'58.5': {'points': 58.5,
       'over': 1.884,
       'under': 2.0,
       'max': 500.0},
      '56.5': {'points': 56.5, 'over': 1.625, 'under': 2.39, 'max': 500.0},
      '57.0': {'points': 57.0, 'over': 1.671, 'under': 2.29, 'max': 500.0},
      '57.5': {'points': 57.5, 'over': 1.746, 'under': 2.18, 'max': 500.0},
      '58.0': {'points': 58.0, 'over': 1.806, 'under': 2.09, 'max': 500.0},
      '59.0': {'points': 59.0, 'over': 1.97, 'under': 1.909, 'max': 500.0},
      '59.5': {'points': 59.5, 'over': 2.06, 'under': 1.826, 'max': 500.0},
      '60.0': {'points': 60.0, 'over': 2.17, 'under': 1.746, 'max': 500.0},
      '60.5': {'points': 60.5, 'over': 2.27, 'under': 1.684, 'max': 500.0}},
     'team_total': {'home': {'points': 30.5, 'over': 1.884, 'under': 1.97},
      'away': {'points': 28.5, 'over': 2.02, 'under': 1.84}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1570800108,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-16T19:10:00',
   'last': 1681567037,
   'home': 'Memphis Grizzlies',
   'away': 'Los Angeles Lakers',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2067039020,
     'number': 0,
     'cutoff': '2023-04-16T19:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.613, 'draw': None, 'away': 2.46},
     'spreads': {'-3.5': {'hdp': -3.5,
       'home': 1.9,
       'away': 2.01,
       'max': 20000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.609, 'away': 2.42, 'max': 20000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.641, 'away': 2.37, 'max': 20000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.684, 'away': 2.28, 'max': 20000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.74, 'away': 2.2, 'max': 20000.0},
      '-3.0': {'hdp': -3.0, 'home': 1.813, 'away': 2.1, 'max': 20000.0},
      '-4.0': {'hdp': -4.0, 'home': 1.98, 'away': 1.909, 'max': 20000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.07, 'away': 1.833, 'max': 20000.0},
      '-5.0': {'hdp': -5.0, 'home': 2.15, 'away': 1.763, 'max': 20000.0},
      '-5.5': {'hdp': -5.5, 'home': 2.24, 'away': 1.709, 'max': 20000.0},
      '-6.0': {'hdp': -6.0, 'home': 2.33, 'away': 1.657, 'max': 20000.0}},
     'totals': {'227.5': {'points': 227.5,
       'over': 1.9,
       'under': 1.99,
       'max': 5000.0},
      '225.0': {'points': 225.0, 'over': 1.675, 'under': 2.27, 'max': 5000.0},
      '225.5': {'points': 225.5, 'over': 1.719, 'under': 2.2, 'max': 5000.0},
      '226.0': {'points': 226.0, 'over': 1.757, 'under': 2.15, 'max': 5000.0},
      '226.5': {'points': 226.5, 'over': 1.806, 'under': 2.09, 'max': 5000.0},
      '227.0': {'points': 227.0, 'over': 1.847, 'under': 2.04, 'max': 5000.0},
      '228.0': {'points': 228.0, 'over': 1.943, 'under': 1.934, 'max': 5000.0},
      '228.5': {'points': 228.5, 'over': 1.99, 'under': 1.884, 'max': 5000.0},
      '229.0': {'points': 229.0, 'over': 2.04, 'under': 1.84, 'max': 5000.0},
      '229.5': {'points': 229.5, 'over': 2.09, 'under': 1.8, 'max': 5000.0},
      '230.0': {'points': 230.0, 'over': 2.15, 'under': 1.751, 'max': 5000.0}},
     'team_total': {'home': {'points': 115.5, 'over': 1.884, 'under': 1.97},
      'away': {'points': 112.5, 'over': 1.952, 'under': 1.9}},
     'meta': {'number': 0,
      'max_spread': 20000.0,
      'max_money_line': 12000.0,
      'max_total': 5000.0,
      'max_team_total': 2000.0}},
    'num_1': {'line_id': 2067039017,
     'number': 1,
     'cutoff': '2023-04-16T19:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.645, 'draw': None, 'away': 2.37},
     'spreads': {'-2.0': {'hdp': -2.0,
       'home': 1.909,
       'away': 1.98,
       'max': 5000.0},
      '0.5': {'hdp': 0.5, 'home': 1.602, 'away': 2.42, 'max': 5000.0},
      '-0.5': {'hdp': -0.5, 'home': 1.699, 'away': 2.23, 'max': 5000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.763, 'away': 2.14, 'max': 5000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.833, 'away': 2.06, 'max': 5000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.99, 'away': 1.892, 'max': 5000.0},
      '-3.0': {'hdp': -3.0, 'home': 2.06, 'away': 1.819, 'max': 5000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.15, 'away': 1.751, 'max': 5000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.23, 'away': 1.699, 'max': 5000.0}},
     'totals': {'117.0': {'points': 117.0,
       'over': 1.952,
       'under': 1.934,
       'max': 2000.0},
      '115.0': {'points': 115.0, 'over': 1.729, 'under': 2.19, 'max': 2000.0},
      '115.5': {'points': 115.5, 'over': 1.781, 'under': 2.11, 'max': 2000.0},
      '116.0': {'points': 116.0, 'over': 1.833, 'under': 2.06, 'max': 2000.0},
      '116.5': {'points': 116.5, 'over': 1.884, 'under': 1.99, 'max': 2000.0},
      '117.5': {'points': 117.5, 'over': 2.01, 'under': 1.869, 'max': 2000.0},
      '118.0': {'points': 118.0, 'over': 2.1, 'under': 1.8, 'max': 2000.0},
      '118.5': {'points': 118.5, 'over': 2.17, 'under': 1.74, 'max': 2000.0},
      '119.0': {'points': 119.0, 'over': 2.28, 'under': 1.68, 'max': 2000.0}},
     'team_total': {'home': {'points': 59.0, 'over': 1.9, 'under': 1.952},
      'away': {'points': 57.0, 'over': 1.934, 'under': 1.917}},
     'meta': {'number': 1,
      'max_spread': 5000.0,
      'max_money_line': 2000.0,
      'max_total': 2000.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2067039018,
     'number': 3,
     'cutoff': '2023-04-16T19:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.68, 'draw': None, 'away': 2.3},
     'spreads': {'-1.5': {'hdp': -1.5,
       'home': 1.934,
       'away': 1.952,
       'max': 3000.0},
      '1.0': {'hdp': 1.0, 'home': 1.531, 'away': 2.59, 'max': 3000.0},
      '0.5': {'hdp': 0.5, 'home': 1.613, 'away': 2.4, 'max': 3000.0},
      '-0.5': {'hdp': -0.5, 'home': 1.757, 'away': 2.15, 'max': 3000.0},
      '-1.0': {'hdp': -1.0, 'home': 1.833, 'away': 2.05, 'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 2.03, 'away': 1.847, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 2.13, 'away': 1.775, 'max': 3000.0},
      '-3.0': {'hdp': -3.0, 'home': 2.26, 'away': 1.684, 'max': 3000.0},
      '-3.5': {'hdp': -3.5, 'home': 2.37, 'away': 1.625, 'max': 3000.0}},
     'totals': {'58.5': {'points': 58.5,
       'over': 1.9,
       'under': 1.99,
       'max': 1000.0},
      '56.5': {'points': 56.5, 'over': 1.649, 'under': 2.33, 'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 1.699, 'under': 2.24, 'max': 1000.0},
      '57.5': {'points': 57.5, 'over': 1.769, 'under': 2.14, 'max': 1000.0},
      '58.0': {'points': 58.0, 'over': 1.826, 'under': 2.06, 'max': 1000.0},
      '59.0': {'points': 59.0, 'over': 1.98, 'under': 1.9, 'max': 1000.0},
      '59.5': {'points': 59.5, 'over': 2.06, 'under': 1.833, 'max': 1000.0},
      '60.0': {'points': 60.0, 'over': 2.15, 'under': 1.757, 'max': 1000.0},
      '60.5': {'points': 60.5, 'over': 2.23, 'under': 1.704, 'max': 1000.0}},
     'team_total': {'home': {'points': 30.0, 'over': 1.9, 'under': 1.952},
      'away': {'points': 28.5, 'over': 1.892, 'under': 1.961}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2067039019,
     'number': 4,
     'cutoff': '2023-04-16T19:10:00Z',
     'period_status': 1,
     'money_line': {'home': 1.793, 'draw': None, 'away': 2.12},
     'spreads': {'-0.5': {'hdp': -0.5,
       'home': 1.877,
       'away': 2.01,
       'max': 500.0},
      '2.0': {'hdp': 2.0, 'home': 1.512, 'away': 2.65, 'max': 500.0},
      '1.5': {'hdp': 1.5, 'home': 1.581, 'away': 2.46, 'max': 500.0},
      '1.0': {'hdp': 1.0, 'home': 1.636, 'away': 2.36, 'max': 500.0},
      '0.5': {'hdp': 0.5, 'home': 1.714, 'away': 2.21, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.97, 'away': 1.9, 'max': 500.0},
      '-1.5': {'hdp': -1.5, 'home': 2.07, 'away': 1.819, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 2.19, 'away': 1.724, 'max': 500.0},
      '-2.5': {'hdp': -2.5, 'home': 2.3, 'away': 1.662, 'max': 500.0}},
     'totals': {'58.5': {'points': 58.5,
       'over': 1.99,
       'under': 1.9,
       'max': 500.0},
      '56.5': {'points': 56.5, 'over': 1.694, 'under': 2.25, 'max': 500.0},
      '57.0': {'points': 57.0, 'over': 1.751, 'under': 2.16, 'max': 500.0},
      '57.5': {'points': 57.5, 'over': 1.833, 'under': 2.06, 'max': 500.0},
      '58.0': {'points': 58.0, 'over': 1.9, 'under': 1.97, 'max': 500.0},
      '59.0': {'points': 59.0, 'over': 2.09, 'under': 1.813, 'max': 500.0},
      '59.5': {'points': 59.5, 'over': 2.18, 'under': 1.74, 'max': 500.0},
      '60.0': {'points': 60.0, 'over': 2.31, 'under': 1.662, 'max': 500.0},
      '60.5': {'points': 60.5, 'over': 2.41, 'under': 1.613, 'max': 500.0}},
     'team_total': {'home': {'points': 29.5, 'over': 1.909, 'under': 1.943},
      'away': {'points': 29.0, 'over': 2.03, 'under': 1.833}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1571130758,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-16T21:40:00',
   'last': 1681565359,
   'home': 'Milwaukee Bucks',
   'away': 'Miami Heat',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2066966502,
     'number': 0,
     'cutoff': '2023-04-16T21:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.256, 'draw': None, 'away': 4.26},
     'spreads': {'-9.0': {'hdp': -9.0,
       'home': 1.917,
       'away': 1.99,
       'max': 15000.0},
      '-6.5': {'hdp': -6.5, 'home': 1.595, 'away': 2.46, 'max': 15000.0},
      '-7.0': {'hdp': -7.0, 'home': 1.641, 'away': 2.36, 'max': 15000.0},
      '-7.5': {'hdp': -7.5, 'home': 1.694, 'away': 2.26, 'max': 15000.0},
      '-8.0': {'hdp': -8.0, 'home': 1.757, 'away': 2.17, 'max': 15000.0},
      '-8.5': {'hdp': -8.5, 'home': 1.826, 'away': 2.08, 'max': 15000.0},
      '-9.5': {'hdp': -9.5, 'home': 2.0, 'away': 1.892, 'max': 15000.0},
      '-10.0': {'hdp': -10.0, 'home': 2.09, 'away': 1.813, 'max': 15000.0},
      '-10.5': {'hdp': -10.5, 'home': 2.17, 'away': 1.751, 'max': 15000.0},
      '-11.0': {'hdp': -11.0, 'home': 2.26, 'away': 1.694, 'max': 15000.0},
      '-11.5': {'hdp': -11.5, 'home': 2.36, 'away': 1.645, 'max': 15000.0}},
     'totals': {'219.0': {'points': 219.0,
       'over': 1.952,
       'under': 1.934,
       'max': 3000.0},
      '216.5': {'points': 216.5, 'over': 1.719, 'under': 2.2, 'max': 3000.0},
      '217.0': {'points': 217.0, 'over': 1.757, 'under': 2.15, 'max': 3000.0},
      '217.5': {'points': 217.5, 'over': 1.806, 'under': 2.08, 'max': 3000.0},
      '218.0': {'points': 218.0, 'over': 1.847, 'under': 2.04, 'max': 3000.0},
      '218.5': {'points': 218.5, 'over': 1.892, 'under': 1.98, 'max': 3000.0},
      '219.5': {'points': 219.5, 'over': 2.0, 'under': 1.877, 'max': 3000.0},
      '220.0': {'points': 220.0, 'over': 2.06, 'under': 1.833, 'max': 3000.0},
      '220.5': {'points': 220.5, 'over': 2.11, 'under': 1.787, 'max': 3000.0},
      '221.0': {'points': 221.0, 'over': 2.17, 'under': 1.74, 'max': 3000.0},
      '221.5': {'points': 221.5, 'over': 2.22, 'under': 1.704, 'max': 3000.0}},
     'team_total': {'home': {'points': 113.5, 'over': 1.877, 'under': 1.97},
      'away': {'points': 104.5, 'over': 1.869, 'under': 1.99}},
     'meta': {'number': 0,
      'max_spread': 15000.0,
      'max_total': 3000.0,
      'max_money_line': 7500.0,
      'max_team_total': 1500.0}},
    'num_1': {'line_id': 2066966507,
     'number': 1,
     'cutoff': '2023-04-16T21:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.366, 'draw': None, 'away': 3.31},
     'spreads': {'-5.5': {'hdp': -5.5,
       'home': 1.952,
       'away': 1.934,
       'max': 5000.0},
      '-3.5': {'hdp': -3.5, 'home': 1.666, 'away': 2.29, 'max': 5000.0},
      '-4.0': {'hdp': -4.0, 'home': 1.719, 'away': 2.2, 'max': 5000.0},
      '-4.5': {'hdp': -4.5, 'home': 1.781, 'away': 2.11, 'max': 5000.0},
      '-5.0': {'hdp': -5.0, 'home': 1.854, 'away': 2.03, 'max': 5000.0},
      '-6.0': {'hdp': -6.0, 'home': 2.04, 'away': 1.847, 'max': 5000.0},
      '-6.5': {'hdp': -6.5, 'home': 2.13, 'away': 1.775, 'max': 5000.0},
      '-7.0': {'hdp': -7.0, 'home': 2.21, 'away': 1.709, 'max': 5000.0},
      '-7.5': {'hdp': -7.5, 'home': 2.3, 'away': 1.657, 'max': 5000.0}},
     'totals': {'112.5': {'points': 112.5,
       'over': 1.917,
       'under': 1.97,
       'max': 1500.0},
      '110.5': {'points': 110.5, 'over': 1.714, 'under': 2.22, 'max': 1500.0},
      '111.0': {'points': 111.0, 'over': 1.751, 'under': 2.16, 'max': 1500.0},
      '111.5': {'points': 111.5, 'over': 1.813, 'under': 2.09, 'max': 1500.0},
      '112.0': {'points': 112.0, 'over': 1.862, 'under': 2.02, 'max': 1500.0},
      '113.0': {'points': 113.0, 'over': 1.99, 'under': 1.884, 'max': 1500.0},
      '113.5': {'points': 113.5, 'over': 2.07, 'under': 1.819, 'max': 1500.0},
      '114.0': {'points': 114.0, 'over': 2.16, 'under': 1.746, 'max': 1500.0},
      '114.5': {'points': 114.5, 'over': 2.25, 'under': 1.694, 'max': 1500.0}},
     'team_total': {'home': {'points': 59.0, 'over': 1.98, 'under': 1.877},
      'away': {'points': 53.5, 'over': 1.952, 'under': 1.892}},
     'meta': {'number': 1,
      'max_spread': 5000.0,
      'max_money_line': 2500.0,
      'max_total': 1500.0,
      'max_team_total': 1000.0}},
    'num_3': {'line_id': 2066955419,
     'number': 3,
     'cutoff': '2023-04-16T21:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.446, 'draw': None, 'away': 2.93},
     'spreads': {'-3.5': {'hdp': -3.5,
       'home': 1.97,
       'away': 1.917,
       'max': 3000.0},
      '-1.5': {'hdp': -1.5, 'home': 1.636, 'away': 2.35, 'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.694, 'away': 2.24, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.787, 'away': 2.11, 'max': 3000.0},
      '-3.0': {'hdp': -3.0, 'home': 1.862, 'away': 2.01, 'max': 3000.0},
      '-4.0': {'hdp': -4.0, 'home': 2.07, 'away': 1.819, 'max': 3000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.17, 'away': 1.746, 'max': 3000.0},
      '-5.0': {'hdp': -5.0, 'home': 2.31, 'away': 1.657, 'max': 3000.0},
      '-5.5': {'hdp': -5.5, 'home': 2.42, 'away': 1.602, 'max': 3000.0}},
     'totals': {'56.5': {'points': 56.5,
       'over': 1.917,
       'under': 1.97,
       'max': 1000.0},
      '54.5': {'points': 54.5, 'over': 1.662, 'under': 2.31, 'max': 1000.0},
      '55.0': {'points': 55.0, 'over': 1.709, 'under': 2.22, 'max': 1000.0},
      '55.5': {'points': 55.5, 'over': 1.781, 'under': 2.12, 'max': 1000.0},
      '56.0': {'points': 56.0, 'over': 1.847, 'under': 2.04, 'max': 1000.0},
      '57.0': {'points': 57.0, 'over': 2.0, 'under': 1.884, 'max': 1000.0},
      '57.5': {'points': 57.5, 'over': 2.09, 'under': 1.813, 'max': 1000.0},
      '58.0': {'points': 58.0, 'over': 2.18, 'under': 1.735, 'max': 1000.0},
      '58.5': {'points': 58.5, 'over': 2.27, 'under': 1.684, 'max': 1000.0}},
     'team_total': {'home': {'points': 30.0, 'over': 1.934, 'under': 1.917},
      'away': {'points': 26.5, 'over': 1.884, 'under': 1.97}},
     'meta': {'number': 3,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 1000.0}},
    'num_4': {'line_id': 2066966510,
     'number': 4,
     'cutoff': '2023-04-16T21:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.571, 'draw': None, 'away': 2.53},
     'spreads': {'-2.5': {'hdp': -2.5,
       'home': 1.97,
       'away': 1.917,
       'max': 500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.641, 'away': 2.34, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.699, 'away': 2.23, 'max': 500.0},
      '-1.5': {'hdp': -1.5, 'home': 1.787, 'away': 2.11, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 1.869, 'away': 2.0, 'max': 500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.07, 'away': 1.813, 'max': 500.0},
      '-3.5': {'hdp': -3.5, 'home': 2.17, 'away': 1.74, 'max': 500.0},
      '-4.0': {'hdp': -4.0, 'home': 2.31, 'away': 1.657, 'max': 500.0},
      '-4.5': {'hdp': -4.5, 'home': 2.42, 'away': 1.602, 'max': 500.0}},
     'totals': {'56.0': {'points': 56.0,
       'over': 1.934,
       'under': 1.952,
       'max': 500.0},
      '54.0': {'points': 54.0, 'over': 1.636, 'under': 2.36, 'max': 500.0},
      '54.5': {'points': 54.5, 'over': 1.709, 'under': 2.23, 'max': 500.0},
      '55.0': {'points': 55.0, 'over': 1.769, 'under': 2.14, 'max': 500.0},
      '55.5': {'points': 55.5, 'over': 1.847, 'under': 2.04, 'max': 500.0},
      '56.5': {'points': 56.5, 'over': 2.01, 'under': 1.869, 'max': 500.0},
      '57.0': {'points': 57.0, 'over': 2.12, 'under': 1.781, 'max': 500.0},
      '57.5': {'points': 57.5, 'over': 2.22, 'under': 1.714, 'max': 500.0},
      '58.0': {'points': 58.0, 'over': 2.36, 'under': 1.636, 'max': 500.0}},
     'team_total': {'home': {'points': 29.0, 'over': 1.9, 'under': 1.952},
      'away': {'points': 26.5, 'over': 1.833, 'under': 2.03}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}},
  {'event_id': 1571135863,
   'sport_id': 3,
   'league_id': 487,
   'league_name': 'NBA',
   'starts': '2023-04-17T02:40:00',
   'last': 1681571641,
   'home': 'Denver Nuggets',
   'away': 'Minnesota Timberwolves',
   'event_type': 'prematch',
   'parent_id': None,
   'resulting_unit': 'Regular',
   'is_have_odds': True,
   'periods': {'num_0': {'line_id': 2067398680,
     'number': 0,
     'cutoff': '2023-04-17T02:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.353, 'draw': None, 'away': 3.45},
     'spreads': {'-7.5': {'hdp': -7.5,
       'home': 1.961,
       'away': 1.943,
       'max': 6500.0},
      '-5.0': {'hdp': -5.0, 'home': 1.621, 'away': 2.4, 'max': 6500.0},
      '-5.5': {'hdp': -5.5, 'home': 1.671, 'away': 2.3, 'max': 6500.0},
      '-6.0': {'hdp': -6.0, 'home': 1.724, 'away': 2.21, 'max': 6500.0},
      '-6.5': {'hdp': -6.5, 'home': 1.787, 'away': 2.12, 'max': 6500.0},
      '-7.0': {'hdp': -7.0, 'home': 1.869, 'away': 2.04, 'max': 6500.0},
      '-8.0': {'hdp': -8.0, 'home': 2.05, 'away': 1.854, 'max': 6500.0},
      '-8.5': {'hdp': -8.5, 'home': 2.14, 'away': 1.781, 'max': 6500.0},
      '-9.0': {'hdp': -9.0, 'home': 2.22, 'away': 1.714, 'max': 6500.0},
      '-9.5': {'hdp': -9.5, 'home': 2.32, 'away': 1.666, 'max': 6500.0},
      '-10.0': {'hdp': -10.0, 'home': 2.42, 'away': 1.613, 'max': 6500.0}},
     'totals': {'224.5': {'points': 224.5,
       'over': 1.943,
       'under': 1.943,
       'max': 2000.0},
      '222.0': {'points': 222.0, 'over': 1.714, 'under': 2.21, 'max': 2000.0},
      '222.5': {'points': 222.5, 'over': 1.757, 'under': 2.15, 'max': 2000.0},
      '223.0': {'points': 223.0, 'over': 1.8, 'under': 2.09, 'max': 2000.0},
      '223.5': {'points': 223.5, 'over': 1.847, 'under': 2.04, 'max': 2000.0},
      '224.0': {'points': 224.0, 'over': 1.892, 'under': 1.99, 'max': 2000.0},
      '225.0': {'points': 225.0, 'over': 1.99, 'under': 1.884, 'max': 2000.0},
      '225.5': {'points': 225.5, 'over': 2.04, 'under': 1.84, 'max': 2000.0},
      '226.0': {'points': 226.0, 'over': 2.1, 'under': 1.793, 'max': 2000.0},
      '226.5': {'points': 226.5, 'over': 2.15, 'under': 1.757, 'max': 2000.0},
      '227.0': {'points': 227.0, 'over': 2.21, 'under': 1.709, 'max': 2000.0}},
     'team_total': {'home': {'points': 115.5, 'over': 1.877, 'under': 1.98},
      'away': {'points': 108.5, 'over': 1.917, 'under': 1.934}},
     'meta': {'number': 0,
      'max_spread': 6500.0,
      'max_money_line': 3500.0,
      'max_total': 2000.0,
      'max_team_total': 1000.0}},
    'num_1': {'line_id': 2067398688,
     'number': 1,
     'cutoff': '2023-04-17T02:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.467, 'draw': None, 'away': 2.85},
     'spreads': {'-4.0': {'hdp': -4.0,
       'home': 1.917,
       'away': 1.97,
       'max': 3000.0},
      '-2.0': {'hdp': -2.0, 'home': 1.645, 'away': 2.33, 'max': 3000.0},
      '-2.5': {'hdp': -2.5, 'home': 1.694, 'away': 2.24, 'max': 3000.0},
      '-3.0': {'hdp': -3.0, 'home': 1.757, 'away': 2.15, 'max': 3000.0},
      '-3.5': {'hdp': -3.5, 'home': 1.833, 'away': 2.06, 'max': 3000.0},
      '-4.5': {'hdp': -4.5, 'home': 2.01, 'away': 1.877, 'max': 3000.0},
      '-5.0': {'hdp': -5.0, 'home': 2.09, 'away': 1.8, 'max': 3000.0},
      '-5.5': {'hdp': -5.5, 'home': 2.18, 'away': 1.729, 'max': 3000.0},
      '-6.0': {'hdp': -6.0, 'home': 2.26, 'away': 1.68, 'max': 3000.0}},
     'totals': {'115.0': {'points': 115.0,
       'over': 1.952,
       'under': 1.934,
       'max': 1000.0},
      '113.0': {'points': 113.0, 'over': 1.724, 'under': 2.2, 'max': 1000.0},
      '113.5': {'points': 113.5, 'over': 1.775, 'under': 2.12, 'max': 1000.0},
      '114.0': {'points': 114.0, 'over': 1.826, 'under': 2.06, 'max': 1000.0},
      '114.5': {'points': 114.5, 'over': 1.884, 'under': 2.0, 'max': 1000.0},
      '115.5': {'points': 115.5, 'over': 2.01, 'under': 1.869, 'max': 1000.0},
      '116.0': {'points': 116.0, 'over': 2.1, 'under': 1.8, 'max': 1000.0},
      '116.5': {'points': 116.5, 'over': 2.17, 'under': 1.74, 'max': 1000.0},
      '117.0': {'points': 117.0, 'over': 2.28, 'under': 1.68, 'max': 1000.0}},
     'team_total': {'home': {'points': 59.5, 'over': 1.917, 'under': 1.934},
      'away': {'points': 55.5, 'over': 1.943, 'under': 1.909}},
     'meta': {'number': 1,
      'max_spread': 3000.0,
      'max_money_line': 1500.0,
      'max_total': 1000.0,
      'max_team_total': 500.0}},
    'num_3': {'line_id': 2067398001,
     'number': 3,
     'cutoff': '2023-04-17T02:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.54, 'draw': None, 'away': 2.62},
     'spreads': {'-2.5': {'hdp': -2.5,
       'home': 1.934,
       'away': 1.952,
       'max': 1500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.609, 'away': 2.4, 'max': 1500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.666, 'away': 2.29, 'max': 1500.0},
      '-1.5': {'hdp': -1.5, 'home': 1.757, 'away': 2.15, 'max': 1500.0},
      '-2.0': {'hdp': -2.0, 'home': 1.833, 'away': 2.05, 'max': 1500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.03, 'away': 1.847, 'max': 1500.0},
      '-3.5': {'hdp': -3.5, 'home': 2.13, 'away': 1.775, 'max': 1500.0},
      '-4.0': {'hdp': -4.0, 'home': 2.26, 'away': 1.684, 'max': 1500.0},
      '-4.5': {'hdp': -4.5, 'home': 2.37, 'away': 1.625, 'max': 1500.0}},
     'totals': {'57.5': {'points': 57.5,
       'over': 1.9,
       'under': 1.99,
       'max': 750.0},
      '55.5': {'points': 55.5, 'over': 1.645, 'under': 2.34, 'max': 750.0},
      '56.0': {'points': 56.0, 'over': 1.694, 'under': 2.25, 'max': 750.0},
      '56.5': {'points': 56.5, 'over': 1.769, 'under': 2.14, 'max': 750.0},
      '57.0': {'points': 57.0, 'over': 1.826, 'under': 2.07, 'max': 750.0},
      '58.0': {'points': 58.0, 'over': 1.98, 'under': 1.9, 'max': 750.0},
      '58.5': {'points': 58.5, 'over': 2.06, 'under': 1.826, 'max': 750.0},
      '59.0': {'points': 59.0, 'over': 2.15, 'under': 1.757, 'max': 750.0},
      '59.5': {'points': 59.5, 'over': 2.24, 'under': 1.704, 'max': 750.0}},
     'team_total': {'home': {'points': 30.0, 'over': 1.884, 'under': 1.961},
      'away': {'points': 27.5, 'over': 1.9, 'under': 1.952}},
     'meta': {'number': 3,
      'max_spread': 1500.0,
      'max_money_line': 750.0,
      'max_total': 750.0,
      'max_team_total': 500.0}},
    'num_4': {'line_id': 2067398697,
     'number': 4,
     'cutoff': '2023-04-17T02:40:00Z',
     'period_status': 1,
     'money_line': {'home': 1.68, 'draw': None, 'away': 2.3},
     'spreads': {'-1.5': {'hdp': -1.5,
       'home': 1.934,
       'away': 1.952,
       'max': 500.0},
      '1.0': {'hdp': 1.0, 'home': 1.54, 'away': 2.56, 'max': 500.0},
      '0.5': {'hdp': 0.5, 'home': 1.617, 'away': 2.39, 'max': 500.0},
      '-0.5': {'hdp': -0.5, 'home': 1.757, 'away': 2.15, 'max': 500.0},
      '-1.0': {'hdp': -1.0, 'home': 1.833, 'away': 2.05, 'max': 500.0},
      '-2.0': {'hdp': -2.0, 'home': 2.03, 'away': 1.847, 'max': 500.0},
      '-2.5': {'hdp': -2.5, 'home': 2.13, 'away': 1.775, 'max': 500.0},
      '-3.0': {'hdp': -3.0, 'home': 2.26, 'away': 1.684, 'max': 500.0},
      '-3.5': {'hdp': -3.5, 'home': 2.36, 'away': 1.625, 'max': 500.0}},
     'totals': {'57.0': {'points': 57.0,
       'over': 1.97,
       'under': 1.917,
       'max': 500.0},
      '55.0': {'points': 55.0, 'over': 1.671, 'under': 2.29, 'max': 500.0},
      '55.5': {'points': 55.5, 'over': 1.746, 'under': 2.17, 'max': 500.0},
      '56.0': {'points': 56.0, 'over': 1.813, 'under': 2.09, 'max': 500.0},
      '56.5': {'points': 56.5, 'over': 1.892, 'under': 1.99, 'max': 500.0},
      '57.5': {'points': 57.5, 'over': 2.05, 'under': 1.84, 'max': 500.0},
      '58.0': {'points': 58.0, 'over': 2.16, 'under': 1.757, 'max': 500.0},
      '58.5': {'points': 58.5, 'over': 2.25, 'under': 1.694, 'max': 500.0},
      '59.0': {'points': 59.0, 'over': 2.39, 'under': 1.621, 'max': 500.0}},
     'team_total': {'home': {'points': 29.5, 'over': 2.0, 'under': 1.854},
      'away': {'points': 28.0, 'over': 2.02, 'under': 1.84}},
     'meta': {'number': 4,
      'max_spread': 500.0,
      'max_money_line': 500.0,
      'max_total': 500.0,
      'max_team_total': 500.0}}}}]}

Wow, that’s a lot of stuff. OK, now this is the tricky part. How do we get this thing into a pandas DataFrame? This is where we really have to think carefully. What do we actually want? Remember, a DataFrame, at its simplest, looks like a spreadsheet, with rows and columns. How could this thing possibly look like that?

current_df = pd.json_normalize(data = current_json)
current_df
sport_id sport_name last last_call events
0 3 Basketball 1681571705 1681571706 [{'event_id': 1570671674, 'sport_id': 3, 'leag...

We need to flatten this file. JSON files are nested. That’s what all those brackets are doing. Let’s think a little more about that.

../_images/07-json.png

Fig. 7.7 JSON structure. Source: https://towardsdatascience.com/all-pandas-json-normalize-you-should-know-for-flattening-json-13eae1dfb7dd#

JSON files are like dictionaries, as you can see in the picture above. There’s a key and a value. However, they can get complicated where there’s a list of dictionaries embedded in the same data structure. You can think of navigating them like working through the branches of a tree. Which branch do you want?

To do this, we’ll use the pd.json_normalize method. We’ve just used it, but that was with a simple JSON file. It didn’t really work with the current odds data, unless we add more arguments.

You can read more here.

Everything is packed into that events column. Let’s flatten it. This will take every item in it and convert it into a new column. Keys will be combined together to create compound names that combine different levels.

current_df_events = pd.json_normalize(data = current_json, record_path=['events'])
current_df_events
event_id sport_id league_id league_name starts last home away event_type parent_id ... periods.num_0.totals.222.0.under periods.num_0.totals.222.0.max periods.num_0.totals.222.5.points periods.num_0.totals.222.5.over periods.num_0.totals.222.5.under periods.num_0.totals.222.5.max periods.num_0.totals.223.0.points periods.num_0.totals.223.0.over periods.num_0.totals.223.0.under periods.num_0.totals.223.0.max
0 1570671674 3 487 NBA 2023-04-15T17:10:00 1681571077 Philadelphia 76ers Brooklyn Nets prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 1570671683 3 487 NBA 2023-04-16T00:40:00 1681570378 Sacramento Kings Golden State Warriors prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 1570671684 3 487 NBA 2023-04-17T00:10:00 1681568411 Phoenix Suns Los Angeles Clippers prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 1570671685 3 487 NBA 2023-04-15T22:10:00 1681571621 Cleveland Cavaliers New York Knicks prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 1570794181 3 487 NBA 2023-04-15T19:40:00 1681570462 Boston Celtics Atlanta Hawks prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 1570800108 3 487 NBA 2023-04-16T19:10:00 1681567037 Memphis Grizzlies Los Angeles Lakers prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 1571130758 3 487 NBA 2023-04-16T21:40:00 1681565359 Milwaukee Bucks Miami Heat prematch None ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 1571135863 3 487 NBA 2023-04-17T02:40:00 1681571641 Denver Nuggets Minnesota Timberwolves prematch None ... 2.21 2000.0 222.5 1.757 2.15 2000.0 223.0 1.8 2.09 2000.0

8 rows × 856 columns

list(current_df_events)
['event_id',
 'sport_id',
 'league_id',
 'league_name',
 'starts',
 'last',
 'home',
 'away',
 'event_type',
 'parent_id',
 'resulting_unit',
 'is_have_odds',
 'periods.num_0.line_id',
 'periods.num_0.number',
 'periods.num_0.cutoff',
 'periods.num_0.period_status',
 'periods.num_0.money_line.home',
 'periods.num_0.money_line.draw',
 'periods.num_0.money_line.away',
 'periods.num_0.spreads.-8.5.hdp',
 'periods.num_0.spreads.-8.5.home',
 'periods.num_0.spreads.-8.5.away',
 'periods.num_0.spreads.-8.5.max',
 'periods.num_0.spreads.-6.0.hdp',
 'periods.num_0.spreads.-6.0.home',
 'periods.num_0.spreads.-6.0.away',
 'periods.num_0.spreads.-6.0.max',
 'periods.num_0.spreads.-6.5.hdp',
 'periods.num_0.spreads.-6.5.home',
 'periods.num_0.spreads.-6.5.away',
 'periods.num_0.spreads.-6.5.max',
 'periods.num_0.spreads.-7.0.hdp',
 'periods.num_0.spreads.-7.0.home',
 'periods.num_0.spreads.-7.0.away',
 'periods.num_0.spreads.-7.0.max',
 'periods.num_0.spreads.-7.5.hdp',
 'periods.num_0.spreads.-7.5.home',
 'periods.num_0.spreads.-7.5.away',
 'periods.num_0.spreads.-7.5.max',
 'periods.num_0.spreads.-8.0.hdp',
 'periods.num_0.spreads.-8.0.home',
 'periods.num_0.spreads.-8.0.away',
 'periods.num_0.spreads.-8.0.max',
 'periods.num_0.spreads.-9.0.hdp',
 'periods.num_0.spreads.-9.0.home',
 'periods.num_0.spreads.-9.0.away',
 'periods.num_0.spreads.-9.0.max',
 'periods.num_0.spreads.-9.5.hdp',
 'periods.num_0.spreads.-9.5.home',
 'periods.num_0.spreads.-9.5.away',
 'periods.num_0.spreads.-9.5.max',
 'periods.num_0.spreads.-10.0.hdp',
 'periods.num_0.spreads.-10.0.home',
 'periods.num_0.spreads.-10.0.away',
 'periods.num_0.spreads.-10.0.max',
 'periods.num_0.spreads.-10.5.hdp',
 'periods.num_0.spreads.-10.5.home',
 'periods.num_0.spreads.-10.5.away',
 'periods.num_0.spreads.-10.5.max',
 'periods.num_0.spreads.-11.0.hdp',
 'periods.num_0.spreads.-11.0.home',
 'periods.num_0.spreads.-11.0.away',
 'periods.num_0.spreads.-11.0.max',
 'periods.num_0.totals.213.5.points',
 'periods.num_0.totals.213.5.over',
 'periods.num_0.totals.213.5.under',
 'periods.num_0.totals.213.5.max',
 'periods.num_0.totals.211.0.points',
 'periods.num_0.totals.211.0.over',
 'periods.num_0.totals.211.0.under',
 'periods.num_0.totals.211.0.max',
 'periods.num_0.totals.211.5.points',
 'periods.num_0.totals.211.5.over',
 'periods.num_0.totals.211.5.under',
 'periods.num_0.totals.211.5.max',
 'periods.num_0.totals.212.0.points',
 'periods.num_0.totals.212.0.over',
 'periods.num_0.totals.212.0.under',
 'periods.num_0.totals.212.0.max',
 'periods.num_0.totals.212.5.points',
 'periods.num_0.totals.212.5.over',
 'periods.num_0.totals.212.5.under',
 'periods.num_0.totals.212.5.max',
 'periods.num_0.totals.213.0.points',
 'periods.num_0.totals.213.0.over',
 'periods.num_0.totals.213.0.under',
 'periods.num_0.totals.213.0.max',
 'periods.num_0.totals.214.0.points',
 'periods.num_0.totals.214.0.over',
 'periods.num_0.totals.214.0.under',
 'periods.num_0.totals.214.0.max',
 'periods.num_0.totals.214.5.points',
 'periods.num_0.totals.214.5.over',
 'periods.num_0.totals.214.5.under',
 'periods.num_0.totals.214.5.max',
 'periods.num_0.totals.215.0.points',
 'periods.num_0.totals.215.0.over',
 'periods.num_0.totals.215.0.under',
 'periods.num_0.totals.215.0.max',
 'periods.num_0.totals.215.5.points',
 'periods.num_0.totals.215.5.over',
 'periods.num_0.totals.215.5.under',
 'periods.num_0.totals.215.5.max',
 'periods.num_0.totals.216.0.points',
 'periods.num_0.totals.216.0.over',
 'periods.num_0.totals.216.0.under',
 'periods.num_0.totals.216.0.max',
 'periods.num_0.team_total.home.points',
 'periods.num_0.team_total.home.over',
 'periods.num_0.team_total.home.under',
 'periods.num_0.team_total.away.points',
 'periods.num_0.team_total.away.over',
 'periods.num_0.team_total.away.under',
 'periods.num_0.meta.number',
 'periods.num_0.meta.max_spread',
 'periods.num_0.meta.max_money_line',
 'periods.num_0.meta.max_total',
 'periods.num_0.meta.max_team_total',
 'periods.num_1.line_id',
 'periods.num_1.number',
 'periods.num_1.cutoff',
 'periods.num_1.period_status',
 'periods.num_1.money_line.home',
 'periods.num_1.money_line.draw',
 'periods.num_1.money_line.away',
 'periods.num_1.spreads.-5.0.hdp',
 'periods.num_1.spreads.-5.0.home',
 'periods.num_1.spreads.-5.0.away',
 'periods.num_1.spreads.-5.0.max',
 'periods.num_1.spreads.-3.0.hdp',
 'periods.num_1.spreads.-3.0.home',
 'periods.num_1.spreads.-3.0.away',
 'periods.num_1.spreads.-3.0.max',
 'periods.num_1.spreads.-3.5.hdp',
 'periods.num_1.spreads.-3.5.home',
 'periods.num_1.spreads.-3.5.away',
 'periods.num_1.spreads.-3.5.max',
 'periods.num_1.spreads.-4.0.hdp',
 'periods.num_1.spreads.-4.0.home',
 'periods.num_1.spreads.-4.0.away',
 'periods.num_1.spreads.-4.0.max',
 'periods.num_1.spreads.-4.5.hdp',
 'periods.num_1.spreads.-4.5.home',
 'periods.num_1.spreads.-4.5.away',
 'periods.num_1.spreads.-4.5.max',
 'periods.num_1.spreads.-5.5.hdp',
 'periods.num_1.spreads.-5.5.home',
 'periods.num_1.spreads.-5.5.away',
 'periods.num_1.spreads.-5.5.max',
 'periods.num_1.spreads.-6.0.hdp',
 'periods.num_1.spreads.-6.0.home',
 'periods.num_1.spreads.-6.0.away',
 'periods.num_1.spreads.-6.0.max',
 'periods.num_1.spreads.-6.5.hdp',
 'periods.num_1.spreads.-6.5.home',
 'periods.num_1.spreads.-6.5.away',
 'periods.num_1.spreads.-6.5.max',
 'periods.num_1.spreads.-7.0.hdp',
 'periods.num_1.spreads.-7.0.home',
 'periods.num_1.spreads.-7.0.away',
 'periods.num_1.spreads.-7.0.max',
 'periods.num_1.totals.109.0.points',
 'periods.num_1.totals.109.0.over',
 'periods.num_1.totals.109.0.under',
 'periods.num_1.totals.109.0.max',
 'periods.num_1.totals.107.0.points',
 'periods.num_1.totals.107.0.over',
 'periods.num_1.totals.107.0.under',
 'periods.num_1.totals.107.0.max',
 'periods.num_1.totals.107.5.points',
 'periods.num_1.totals.107.5.over',
 'periods.num_1.totals.107.5.under',
 'periods.num_1.totals.107.5.max',
 'periods.num_1.totals.108.0.points',
 'periods.num_1.totals.108.0.over',
 'periods.num_1.totals.108.0.under',
 'periods.num_1.totals.108.0.max',
 'periods.num_1.totals.108.5.points',
 'periods.num_1.totals.108.5.over',
 'periods.num_1.totals.108.5.under',
 'periods.num_1.totals.108.5.max',
 'periods.num_1.totals.109.5.points',
 'periods.num_1.totals.109.5.over',
 'periods.num_1.totals.109.5.under',
 'periods.num_1.totals.109.5.max',
 'periods.num_1.totals.110.0.points',
 'periods.num_1.totals.110.0.over',
 'periods.num_1.totals.110.0.under',
 'periods.num_1.totals.110.0.max',
 'periods.num_1.totals.110.5.points',
 'periods.num_1.totals.110.5.over',
 'periods.num_1.totals.110.5.under',
 'periods.num_1.totals.110.5.max',
 'periods.num_1.totals.111.0.points',
 'periods.num_1.totals.111.0.over',
 'periods.num_1.totals.111.0.under',
 'periods.num_1.totals.111.0.max',
 'periods.num_1.team_total.home.points',
 'periods.num_1.team_total.home.over',
 'periods.num_1.team_total.home.under',
 'periods.num_1.team_total.away.points',
 'periods.num_1.team_total.away.over',
 'periods.num_1.team_total.away.under',
 'periods.num_1.meta.number',
 'periods.num_1.meta.max_spread',
 'periods.num_1.meta.max_money_line',
 'periods.num_1.meta.max_total',
 'periods.num_1.meta.max_team_total',
 'periods.num_3.line_id',
 'periods.num_3.number',
 'periods.num_3.cutoff',
 'periods.num_3.period_status',
 'periods.num_3.money_line.home',
 'periods.num_3.money_line.draw',
 'periods.num_3.money_line.away',
 'periods.num_3.spreads.-3.0.hdp',
 'periods.num_3.spreads.-3.0.home',
 'periods.num_3.spreads.-3.0.away',
 'periods.num_3.spreads.-3.0.max',
 'periods.num_3.spreads.-1.0.hdp',
 'periods.num_3.spreads.-1.0.home',
 'periods.num_3.spreads.-1.0.away',
 'periods.num_3.spreads.-1.0.max',
 'periods.num_3.spreads.-1.5.hdp',
 'periods.num_3.spreads.-1.5.home',
 'periods.num_3.spreads.-1.5.away',
 'periods.num_3.spreads.-1.5.max',
 'periods.num_3.spreads.-2.0.hdp',
 'periods.num_3.spreads.-2.0.home',
 'periods.num_3.spreads.-2.0.away',
 'periods.num_3.spreads.-2.0.max',
 'periods.num_3.spreads.-2.5.hdp',
 'periods.num_3.spreads.-2.5.home',
 'periods.num_3.spreads.-2.5.away',
 'periods.num_3.spreads.-2.5.max',
 'periods.num_3.spreads.-3.5.hdp',
 'periods.num_3.spreads.-3.5.home',
 'periods.num_3.spreads.-3.5.away',
 'periods.num_3.spreads.-3.5.max',
 'periods.num_3.spreads.-4.0.hdp',
 'periods.num_3.spreads.-4.0.home',
 'periods.num_3.spreads.-4.0.away',
 'periods.num_3.spreads.-4.0.max',
 'periods.num_3.spreads.-4.5.hdp',
 'periods.num_3.spreads.-4.5.home',
 'periods.num_3.spreads.-4.5.away',
 'periods.num_3.spreads.-4.5.max',
 'periods.num_3.spreads.-5.0.hdp',
 'periods.num_3.spreads.-5.0.home',
 'periods.num_3.spreads.-5.0.away',
 'periods.num_3.spreads.-5.0.max',
 'periods.num_3.totals.55.0.points',
 'periods.num_3.totals.55.0.over',
 'periods.num_3.totals.55.0.under',
 'periods.num_3.totals.55.0.max',
 'periods.num_3.totals.53.0.points',
 'periods.num_3.totals.53.0.over',
 'periods.num_3.totals.53.0.under',
 'periods.num_3.totals.53.0.max',
 'periods.num_3.totals.53.5.points',
 'periods.num_3.totals.53.5.over',
 'periods.num_3.totals.53.5.under',
 'periods.num_3.totals.53.5.max',
 'periods.num_3.totals.54.0.points',
 'periods.num_3.totals.54.0.over',
 'periods.num_3.totals.54.0.under',
 'periods.num_3.totals.54.0.max',
 'periods.num_3.totals.54.5.points',
 'periods.num_3.totals.54.5.over',
 'periods.num_3.totals.54.5.under',
 'periods.num_3.totals.54.5.max',
 'periods.num_3.totals.55.5.points',
 'periods.num_3.totals.55.5.over',
 'periods.num_3.totals.55.5.under',
 'periods.num_3.totals.55.5.max',
 'periods.num_3.totals.56.0.points',
 'periods.num_3.totals.56.0.over',
 'periods.num_3.totals.56.0.under',
 'periods.num_3.totals.56.0.max',
 'periods.num_3.totals.56.5.points',
 'periods.num_3.totals.56.5.over',
 'periods.num_3.totals.56.5.under',
 'periods.num_3.totals.56.5.max',
 'periods.num_3.totals.57.0.points',
 'periods.num_3.totals.57.0.over',
 'periods.num_3.totals.57.0.under',
 'periods.num_3.totals.57.0.max',
 'periods.num_3.team_total.home.points',
 'periods.num_3.team_total.home.over',
 'periods.num_3.team_total.home.under',
 'periods.num_3.team_total.away.points',
 'periods.num_3.team_total.away.over',
 'periods.num_3.team_total.away.under',
 'periods.num_3.meta.number',
 'periods.num_3.meta.max_spread',
 'periods.num_3.meta.max_money_line',
 'periods.num_3.meta.max_total',
 'periods.num_3.meta.max_team_total',
 'periods.num_4.line_id',
 'periods.num_4.number',
 'periods.num_4.cutoff',
 'periods.num_4.period_status',
 'periods.num_4.money_line.home',
 'periods.num_4.money_line.draw',
 'periods.num_4.money_line.away',
 'periods.num_4.spreads.-2.5.hdp',
 'periods.num_4.spreads.-2.5.home',
 'periods.num_4.spreads.-2.5.away',
 'periods.num_4.spreads.-2.5.max',
 'periods.num_4.spreads.-0.5.hdp',
 'periods.num_4.spreads.-0.5.home',
 'periods.num_4.spreads.-0.5.away',
 'periods.num_4.spreads.-0.5.max',
 'periods.num_4.spreads.-1.0.hdp',
 'periods.num_4.spreads.-1.0.home',
 'periods.num_4.spreads.-1.0.away',
 'periods.num_4.spreads.-1.0.max',
 'periods.num_4.spreads.-1.5.hdp',
 'periods.num_4.spreads.-1.5.home',
 'periods.num_4.spreads.-1.5.away',
 'periods.num_4.spreads.-1.5.max',
 'periods.num_4.spreads.-2.0.hdp',
 'periods.num_4.spreads.-2.0.home',
 'periods.num_4.spreads.-2.0.away',
 'periods.num_4.spreads.-2.0.max',
 'periods.num_4.spreads.-3.0.hdp',
 'periods.num_4.spreads.-3.0.home',
 'periods.num_4.spreads.-3.0.away',
 'periods.num_4.spreads.-3.0.max',
 'periods.num_4.spreads.-3.5.hdp',
 'periods.num_4.spreads.-3.5.home',
 'periods.num_4.spreads.-3.5.away',
 'periods.num_4.spreads.-3.5.max',
 'periods.num_4.spreads.-4.0.hdp',
 'periods.num_4.spreads.-4.0.home',
 'periods.num_4.spreads.-4.0.away',
 'periods.num_4.spreads.-4.0.max',
 'periods.num_4.spreads.-4.5.hdp',
 'periods.num_4.spreads.-4.5.home',
 'periods.num_4.spreads.-4.5.away',
 'periods.num_4.spreads.-4.5.max',
 'periods.num_4.totals.54.5.points',
 'periods.num_4.totals.54.5.over',
 'periods.num_4.totals.54.5.under',
 'periods.num_4.totals.54.5.max',
 'periods.num_4.totals.52.5.points',
 'periods.num_4.totals.52.5.over',
 'periods.num_4.totals.52.5.under',
 'periods.num_4.totals.52.5.max',
 'periods.num_4.totals.53.0.points',
 'periods.num_4.totals.53.0.over',
 'periods.num_4.totals.53.0.under',
 'periods.num_4.totals.53.0.max',
 'periods.num_4.totals.53.5.points',
 'periods.num_4.totals.53.5.over',
 'periods.num_4.totals.53.5.under',
 'periods.num_4.totals.53.5.max',
 'periods.num_4.totals.54.0.points',
 'periods.num_4.totals.54.0.over',
 'periods.num_4.totals.54.0.under',
 'periods.num_4.totals.54.0.max',
 'periods.num_4.totals.55.0.points',
 'periods.num_4.totals.55.0.over',
 'periods.num_4.totals.55.0.under',
 'periods.num_4.totals.55.0.max',
 'periods.num_4.totals.55.5.points',
 'periods.num_4.totals.55.5.over',
 'periods.num_4.totals.55.5.under',
 'periods.num_4.totals.55.5.max',
 'periods.num_4.totals.56.0.points',
 'periods.num_4.totals.56.0.over',
 'periods.num_4.totals.56.0.under',
 'periods.num_4.totals.56.0.max',
 'periods.num_4.totals.56.5.points',
 'periods.num_4.totals.56.5.over',
 'periods.num_4.totals.56.5.under',
 'periods.num_4.totals.56.5.max',
 'periods.num_4.team_total.home.points',
 'periods.num_4.team_total.home.over',
 'periods.num_4.team_total.home.under',
 'periods.num_4.team_total.away.points',
 'periods.num_4.team_total.away.over',
 'periods.num_4.team_total.away.under',
 'periods.num_4.meta.number',
 'periods.num_4.meta.max_spread',
 'periods.num_4.meta.max_money_line',
 'periods.num_4.meta.max_total',
 'periods.num_4.meta.max_team_total',
 'periods.num_0.spreads.-1.0.hdp',
 'periods.num_0.spreads.-1.0.home',
 'periods.num_0.spreads.-1.0.away',
 'periods.num_0.spreads.-1.0.max',
 'periods.num_0.spreads.3.0.hdp',
 'periods.num_0.spreads.3.0.home',
 'periods.num_0.spreads.3.0.away',
 'periods.num_0.spreads.3.0.max',
 'periods.num_0.spreads.2.5.hdp',
 'periods.num_0.spreads.2.5.home',
 'periods.num_0.spreads.2.5.away',
 'periods.num_0.spreads.2.5.max',
 'periods.num_0.spreads.2.0.hdp',
 'periods.num_0.spreads.2.0.home',
 'periods.num_0.spreads.2.0.away',
 'periods.num_0.spreads.2.0.max',
 'periods.num_0.spreads.1.5.hdp',
 'periods.num_0.spreads.1.5.home',
 'periods.num_0.spreads.1.5.away',
 'periods.num_0.spreads.1.5.max',
 'periods.num_0.spreads.1.0.hdp',
 'periods.num_0.spreads.1.0.home',
 'periods.num_0.spreads.1.0.away',
 'periods.num_0.spreads.1.0.max',
 'periods.num_0.spreads.-1.5.hdp',
 'periods.num_0.spreads.-1.5.home',
 'periods.num_0.spreads.-1.5.away',
 'periods.num_0.spreads.-1.5.max',
 'periods.num_0.spreads.-2.0.hdp',
 'periods.num_0.spreads.-2.0.home',
 'periods.num_0.spreads.-2.0.away',
 'periods.num_0.spreads.-2.0.max',
 'periods.num_0.spreads.-2.5.hdp',
 'periods.num_0.spreads.-2.5.home',
 'periods.num_0.spreads.-2.5.away',
 'periods.num_0.spreads.-2.5.max',
 'periods.num_0.spreads.-3.0.hdp',
 'periods.num_0.spreads.-3.0.home',
 'periods.num_0.spreads.-3.0.away',
 'periods.num_0.spreads.-3.0.max',
 'periods.num_0.spreads.-3.5.hdp',
 'periods.num_0.spreads.-3.5.home',
 'periods.num_0.spreads.-3.5.away',
 'periods.num_0.spreads.-3.5.max',
 'periods.num_0.totals.237.5.points',
 'periods.num_0.totals.237.5.over',
 'periods.num_0.totals.237.5.under',
 'periods.num_0.totals.237.5.max',
 'periods.num_0.totals.235.0.points',
 'periods.num_0.totals.235.0.over',
 'periods.num_0.totals.235.0.under',
 'periods.num_0.totals.235.0.max',
 'periods.num_0.totals.235.5.points',
 'periods.num_0.totals.235.5.over',
 'periods.num_0.totals.235.5.under',
 'periods.num_0.totals.235.5.max',
 'periods.num_0.totals.236.0.points',
 'periods.num_0.totals.236.0.over',
 'periods.num_0.totals.236.0.under',
 'periods.num_0.totals.236.0.max',
 'periods.num_0.totals.236.5.points',
 'periods.num_0.totals.236.5.over',
 'periods.num_0.totals.236.5.under',
 'periods.num_0.totals.236.5.max',
 'periods.num_0.totals.237.0.points',
 'periods.num_0.totals.237.0.over',
 'periods.num_0.totals.237.0.under',
 'periods.num_0.totals.237.0.max',
 'periods.num_0.totals.238.0.points',
 'periods.num_0.totals.238.0.over',
 'periods.num_0.totals.238.0.under',
 'periods.num_0.totals.238.0.max',
 'periods.num_0.totals.238.5.points',
 'periods.num_0.totals.238.5.over',
 'periods.num_0.totals.238.5.under',
 'periods.num_0.totals.238.5.max',
 'periods.num_0.totals.239.0.points',
 'periods.num_0.totals.239.0.over',
 'periods.num_0.totals.239.0.under',
 'periods.num_0.totals.239.0.max',
 'periods.num_0.totals.239.5.points',
 'periods.num_0.totals.239.5.over',
 'periods.num_0.totals.239.5.under',
 'periods.num_0.totals.239.5.max',
 'periods.num_0.totals.240.0.points',
 'periods.num_0.totals.240.0.over',
 'periods.num_0.totals.240.0.under',
 'periods.num_0.totals.240.0.max',
 'periods.num_1.spreads.-0.5.hdp',
 'periods.num_1.spreads.-0.5.home',
 'periods.num_1.spreads.-0.5.away',
 'periods.num_1.spreads.-0.5.max',
 'periods.num_1.spreads.2.0.hdp',
 'periods.num_1.spreads.2.0.home',
 'periods.num_1.spreads.2.0.away',
 'periods.num_1.spreads.2.0.max',
 'periods.num_1.spreads.1.5.hdp',
 'periods.num_1.spreads.1.5.home',
 'periods.num_1.spreads.1.5.away',
 'periods.num_1.spreads.1.5.max',
 'periods.num_1.spreads.1.0.hdp',
 'periods.num_1.spreads.1.0.home',
 'periods.num_1.spreads.1.0.away',
 'periods.num_1.spreads.1.0.max',
 'periods.num_1.spreads.0.5.hdp',
 'periods.num_1.spreads.0.5.home',
 'periods.num_1.spreads.0.5.away',
 'periods.num_1.spreads.0.5.max',
 'periods.num_1.spreads.-1.0.hdp',
 'periods.num_1.spreads.-1.0.home',
 'periods.num_1.spreads.-1.0.away',
 'periods.num_1.spreads.-1.0.max',
 'periods.num_1.spreads.-1.5.hdp',
 'periods.num_1.spreads.-1.5.home',
 'periods.num_1.spreads.-1.5.away',
 'periods.num_1.spreads.-1.5.max',
 'periods.num_1.spreads.-2.0.hdp',
 'periods.num_1.spreads.-2.0.home',
 'periods.num_1.spreads.-2.0.away',
 'periods.num_1.spreads.-2.0.max',
 'periods.num_1.spreads.-2.5.hdp',
 'periods.num_1.spreads.-2.5.home',
 'periods.num_1.spreads.-2.5.away',
 'periods.num_1.spreads.-2.5.max',
 'periods.num_1.totals.117.5.points',
 'periods.num_1.totals.117.5.over',
 'periods.num_1.totals.117.5.under',
 'periods.num_1.totals.117.5.max',
 'periods.num_1.totals.115.5.points',
 'periods.num_1.totals.115.5.over',
 'periods.num_1.totals.115.5.under',
 'periods.num_1.totals.115.5.max',
 'periods.num_1.totals.116.0.points',
 'periods.num_1.totals.116.0.over',
 'periods.num_1.totals.116.0.under',
 'periods.num_1.totals.116.0.max',
 'periods.num_1.totals.116.5.points',
 'periods.num_1.totals.116.5.over',
 'periods.num_1.totals.116.5.under',
 'periods.num_1.totals.116.5.max',
 'periods.num_1.totals.117.0.points',
 'periods.num_1.totals.117.0.over',
 'periods.num_1.totals.117.0.under',
 'periods.num_1.totals.117.0.max',
 'periods.num_1.totals.118.0.points',
 'periods.num_1.totals.118.0.over',
 'periods.num_1.totals.118.0.under',
 'periods.num_1.totals.118.0.max',
 'periods.num_1.totals.118.5.points',
 'periods.num_1.totals.118.5.over',
 'periods.num_1.totals.118.5.under',
 'periods.num_1.totals.118.5.max',
 'periods.num_1.totals.119.0.points',
 'periods.num_1.totals.119.0.over',
 'periods.num_1.totals.119.0.under',
 'periods.num_1.totals.119.0.max',
 'periods.num_1.totals.119.5.points',
 'periods.num_1.totals.119.5.over',
 'periods.num_1.totals.119.5.under',
 'periods.num_1.totals.119.5.max',
 'periods.num_3.spreads.-0.5.hdp',
 'periods.num_3.spreads.-0.5.home',
 'periods.num_3.spreads.-0.5.away',
 'periods.num_3.spreads.-0.5.max',
 'periods.num_3.spreads.2.0.hdp',
 'periods.num_3.spreads.2.0.home',
 'periods.num_3.spreads.2.0.away',
 'periods.num_3.spreads.2.0.max',
 'periods.num_3.spreads.1.5.hdp',
 'periods.num_3.spreads.1.5.home',
 'periods.num_3.spreads.1.5.away',
 'periods.num_3.spreads.1.5.max',
 'periods.num_3.spreads.1.0.hdp',
 'periods.num_3.spreads.1.0.home',
 'periods.num_3.spreads.1.0.away',
 'periods.num_3.spreads.1.0.max',
 'periods.num_3.spreads.0.5.hdp',
 'periods.num_3.spreads.0.5.home',
 'periods.num_3.spreads.0.5.away',
 'periods.num_3.spreads.0.5.max',
 'periods.num_3.totals.58.5.points',
 'periods.num_3.totals.58.5.over',
 'periods.num_3.totals.58.5.under',
 'periods.num_3.totals.58.5.max',
 'periods.num_3.totals.57.5.points',
 'periods.num_3.totals.57.5.over',
 'periods.num_3.totals.57.5.under',
 'periods.num_3.totals.57.5.max',
 'periods.num_3.totals.58.0.points',
 'periods.num_3.totals.58.0.over',
 'periods.num_3.totals.58.0.under',
 'periods.num_3.totals.58.0.max',
 'periods.num_3.totals.59.0.points',
 'periods.num_3.totals.59.0.over',
 'periods.num_3.totals.59.0.under',
 'periods.num_3.totals.59.0.max',
 'periods.num_3.totals.59.5.points',
 'periods.num_3.totals.59.5.over',
 'periods.num_3.totals.59.5.under',
 'periods.num_3.totals.59.5.max',
 'periods.num_3.totals.60.0.points',
 'periods.num_3.totals.60.0.over',
 'periods.num_3.totals.60.0.under',
 'periods.num_3.totals.60.0.max',
 'periods.num_3.totals.60.5.points',
 'periods.num_3.totals.60.5.over',
 'periods.num_3.totals.60.5.under',
 'periods.num_3.totals.60.5.max',
 'periods.num_4.spreads.2.0.hdp',
 'periods.num_4.spreads.2.0.home',
 'periods.num_4.spreads.2.0.away',
 'periods.num_4.spreads.2.0.max',
 'periods.num_4.spreads.1.5.hdp',
 'periods.num_4.spreads.1.5.home',
 'periods.num_4.spreads.1.5.away',
 'periods.num_4.spreads.1.5.max',
 'periods.num_4.spreads.1.0.hdp',
 'periods.num_4.spreads.1.0.home',
 'periods.num_4.spreads.1.0.away',
 'periods.num_4.spreads.1.0.max',
 'periods.num_4.spreads.0.5.hdp',
 'periods.num_4.spreads.0.5.home',
 'periods.num_4.spreads.0.5.away',
 'periods.num_4.spreads.0.5.max',
 'periods.num_4.totals.58.5.points',
 'periods.num_4.totals.58.5.over',
 'periods.num_4.totals.58.5.under',
 'periods.num_4.totals.58.5.max',
 'periods.num_4.totals.57.0.points',
 'periods.num_4.totals.57.0.over',
 'periods.num_4.totals.57.0.under',
 'periods.num_4.totals.57.0.max',
 'periods.num_4.totals.57.5.points',
 'periods.num_4.totals.57.5.over',
 'periods.num_4.totals.57.5.under',
 'periods.num_4.totals.57.5.max',
 'periods.num_4.totals.58.0.points',
 'periods.num_4.totals.58.0.over',
 'periods.num_4.totals.58.0.under',
 'periods.num_4.totals.58.0.max',
 'periods.num_4.totals.59.0.points',
 'periods.num_4.totals.59.0.over',
 'periods.num_4.totals.59.0.under',
 'periods.num_4.totals.59.0.max',
 'periods.num_4.totals.59.5.points',
 'periods.num_4.totals.59.5.over',
 'periods.num_4.totals.59.5.under',
 'periods.num_4.totals.59.5.max',
 'periods.num_4.totals.60.0.points',
 'periods.num_4.totals.60.0.over',
 'periods.num_4.totals.60.0.under',
 'periods.num_4.totals.60.0.max',
 'periods.num_4.totals.60.5.points',
 'periods.num_4.totals.60.5.over',
 'periods.num_4.totals.60.5.under',
 'periods.num_4.totals.60.5.max',
 'periods.num_0.spreads.-5.0.hdp',
 'periods.num_0.spreads.-5.0.home',
 'periods.num_0.spreads.-5.0.away',
 'periods.num_0.spreads.-5.0.max',
 'periods.num_0.spreads.-5.5.hdp',
 'periods.num_0.spreads.-5.5.home',
 'periods.num_0.spreads.-5.5.away',
 'periods.num_0.spreads.-5.5.max',
 'periods.num_0.totals.226.0.points',
 'periods.num_0.totals.226.0.over',
 'periods.num_0.totals.226.0.under',
 'periods.num_0.totals.226.0.max',
 'periods.num_0.totals.223.5.points',
 'periods.num_0.totals.223.5.over',
 'periods.num_0.totals.223.5.under',
 'periods.num_0.totals.223.5.max',
 'periods.num_0.totals.224.0.points',
 'periods.num_0.totals.224.0.over',
 'periods.num_0.totals.224.0.under',
 'periods.num_0.totals.224.0.max',
 'periods.num_0.totals.224.5.points',
 'periods.num_0.totals.224.5.over',
 'periods.num_0.totals.224.5.under',
 'periods.num_0.totals.224.5.max',
 'periods.num_0.totals.225.0.points',
 'periods.num_0.totals.225.0.over',
 'periods.num_0.totals.225.0.under',
 'periods.num_0.totals.225.0.max',
 'periods.num_0.totals.225.5.points',
 'periods.num_0.totals.225.5.over',
 'periods.num_0.totals.225.5.under',
 'periods.num_0.totals.225.5.max',
 'periods.num_0.totals.226.5.points',
 'periods.num_0.totals.226.5.over',
 'periods.num_0.totals.226.5.under',
 'periods.num_0.totals.226.5.max',
 'periods.num_0.totals.227.0.points',
 'periods.num_0.totals.227.0.over',
 'periods.num_0.totals.227.0.under',
 'periods.num_0.totals.227.0.max',
 'periods.num_0.totals.227.5.points',
 'periods.num_0.totals.227.5.over',
 'periods.num_0.totals.227.5.under',
 'periods.num_0.totals.227.5.max',
 'periods.num_0.totals.228.0.points',
 'periods.num_0.totals.228.0.over',
 'periods.num_0.totals.228.0.under',
 'periods.num_0.totals.228.0.max',
 'periods.num_0.totals.228.5.points',
 'periods.num_0.totals.228.5.over',
 'periods.num_0.totals.228.5.under',
 'periods.num_0.totals.228.5.max',
 'periods.num_1.totals.111.5.points',
 'periods.num_1.totals.111.5.over',
 'periods.num_1.totals.111.5.under',
 'periods.num_1.totals.111.5.max',
 'periods.num_1.totals.112.0.points',
 'periods.num_1.totals.112.0.over',
 'periods.num_1.totals.112.0.under',
 'periods.num_1.totals.112.0.max',
 'periods.num_1.totals.112.5.points',
 'periods.num_1.totals.112.5.over',
 'periods.num_1.totals.112.5.under',
 'periods.num_1.totals.112.5.max',
 'periods.num_0.spreads.-4.0.hdp',
 'periods.num_0.spreads.-4.0.home',
 'periods.num_0.spreads.-4.0.away',
 'periods.num_0.spreads.-4.0.max',
 'periods.num_0.spreads.-4.5.hdp',
 'periods.num_0.spreads.-4.5.home',
 'periods.num_0.spreads.-4.5.away',
 'periods.num_0.spreads.-4.5.max',
 'periods.num_0.totals.217.0.points',
 'periods.num_0.totals.217.0.over',
 'periods.num_0.totals.217.0.under',
 'periods.num_0.totals.217.0.max',
 'periods.num_0.totals.216.5.points',
 'periods.num_0.totals.216.5.over',
 'periods.num_0.totals.216.5.under',
 'periods.num_0.totals.216.5.max',
 'periods.num_0.totals.217.5.points',
 'periods.num_0.totals.217.5.over',
 'periods.num_0.totals.217.5.under',
 'periods.num_0.totals.217.5.max',
 'periods.num_0.totals.218.0.points',
 'periods.num_0.totals.218.0.over',
 'periods.num_0.totals.218.0.under',
 'periods.num_0.totals.218.0.max',
 'periods.num_0.totals.218.5.points',
 'periods.num_0.totals.218.5.over',
 'periods.num_0.totals.218.5.under',
 'periods.num_0.totals.218.5.max',
 'periods.num_0.totals.219.0.points',
 'periods.num_0.totals.219.0.over',
 'periods.num_0.totals.219.0.under',
 'periods.num_0.totals.219.0.max',
 'periods.num_0.totals.219.5.points',
 'periods.num_0.totals.219.5.over',
 'periods.num_0.totals.219.5.under',
 'periods.num_0.totals.219.5.max',
 'periods.num_1.totals.113.0.points',
 'periods.num_1.totals.113.0.over',
 'periods.num_1.totals.113.0.under',
 'periods.num_1.totals.113.0.max',
 'periods.num_0.spreads.-11.5.hdp',
 'periods.num_0.spreads.-11.5.home',
 'periods.num_0.spreads.-11.5.away',
 'periods.num_0.spreads.-11.5.max',
 'periods.num_0.spreads.-12.0.hdp',
 'periods.num_0.spreads.-12.0.home',
 'periods.num_0.spreads.-12.0.away',
 'periods.num_0.spreads.-12.0.max',
 'periods.num_0.totals.231.0.points',
 'periods.num_0.totals.231.0.over',
 'periods.num_0.totals.231.0.under',
 'periods.num_0.totals.231.0.max',
 'periods.num_0.totals.229.0.points',
 'periods.num_0.totals.229.0.over',
 'periods.num_0.totals.229.0.under',
 'periods.num_0.totals.229.0.max',
 'periods.num_0.totals.229.5.points',
 'periods.num_0.totals.229.5.over',
 'periods.num_0.totals.229.5.under',
 'periods.num_0.totals.229.5.max',
 'periods.num_0.totals.230.0.points',
 'periods.num_0.totals.230.0.over',
 'periods.num_0.totals.230.0.under',
 'periods.num_0.totals.230.0.max',
 'periods.num_0.totals.230.5.points',
 'periods.num_0.totals.230.5.over',
 'periods.num_0.totals.230.5.under',
 'periods.num_0.totals.230.5.max',
 'periods.num_0.totals.231.5.points',
 'periods.num_0.totals.231.5.over',
 'periods.num_0.totals.231.5.under',
 'periods.num_0.totals.231.5.max',
 'periods.num_0.totals.232.0.points',
 'periods.num_0.totals.232.0.over',
 'periods.num_0.totals.232.0.under',
 'periods.num_0.totals.232.0.max',
 'periods.num_0.totals.232.5.points',
 'periods.num_0.totals.232.5.over',
 'periods.num_0.totals.232.5.under',
 'periods.num_0.totals.232.5.max',
 'periods.num_0.totals.233.0.points',
 'periods.num_0.totals.233.0.over',
 'periods.num_0.totals.233.0.under',
 'periods.num_0.totals.233.0.max',
 'periods.num_0.totals.233.5.points',
 'periods.num_0.totals.233.5.over',
 'periods.num_0.totals.233.5.under',
 'periods.num_0.totals.233.5.max',
 'periods.num_1.totals.120.0.points',
 'periods.num_1.totals.120.0.over',
 'periods.num_1.totals.120.0.under',
 'periods.num_1.totals.120.0.max',
 'periods.num_3.totals.61.0.points',
 'periods.num_3.totals.61.0.over',
 'periods.num_3.totals.61.0.under',
 'periods.num_3.totals.61.0.max',
 'periods.num_1.totals.115.0.points',
 'periods.num_1.totals.115.0.over',
 'periods.num_1.totals.115.0.under',
 'periods.num_1.totals.115.0.max',
 'periods.num_0.totals.220.0.points',
 'periods.num_0.totals.220.0.over',
 'periods.num_0.totals.220.0.under',
 'periods.num_0.totals.220.0.max',
 'periods.num_0.totals.220.5.points',
 'periods.num_0.totals.220.5.over',
 'periods.num_0.totals.220.5.under',
 'periods.num_0.totals.220.5.max',
 'periods.num_0.totals.221.0.points',
 'periods.num_0.totals.221.0.over',
 'periods.num_0.totals.221.0.under',
 'periods.num_0.totals.221.0.max',
 'periods.num_0.totals.221.5.points',
 'periods.num_0.totals.221.5.over',
 'periods.num_0.totals.221.5.under',
 'periods.num_0.totals.221.5.max',
 'periods.num_1.spreads.-7.5.hdp',
 'periods.num_1.spreads.-7.5.home',
 'periods.num_1.spreads.-7.5.away',
 'periods.num_1.spreads.-7.5.max',
 'periods.num_1.totals.113.5.points',
 'periods.num_1.totals.113.5.over',
 'periods.num_1.totals.113.5.under',
 'periods.num_1.totals.113.5.max',
 'periods.num_1.totals.114.0.points',
 'periods.num_1.totals.114.0.over',
 'periods.num_1.totals.114.0.under',
 'periods.num_1.totals.114.0.max',
 'periods.num_1.totals.114.5.points',
 'periods.num_1.totals.114.5.over',
 'periods.num_1.totals.114.5.under',
 'periods.num_1.totals.114.5.max',
 'periods.num_3.spreads.-5.5.hdp',
 'periods.num_3.spreads.-5.5.home',
 'periods.num_3.spreads.-5.5.away',
 'periods.num_3.spreads.-5.5.max',
 'periods.num_0.totals.222.0.points',
 'periods.num_0.totals.222.0.over',
 'periods.num_0.totals.222.0.under',
 'periods.num_0.totals.222.0.max',
 'periods.num_0.totals.222.5.points',
 'periods.num_0.totals.222.5.over',
 'periods.num_0.totals.222.5.under',
 'periods.num_0.totals.222.5.max',
 'periods.num_0.totals.223.0.points',
 'periods.num_0.totals.223.0.over',
 'periods.num_0.totals.223.0.under',
 'periods.num_0.totals.223.0.max']

That’s a lot of columns! Do you see what it did? When I flattened the file, it worked its way through the dictionary and key values. So, periods to num_0 to totals to the various over/under values, etc. It then combined those permutations to create new columns, where each value is separated by a period. Then value at the end of the chain is what goes into the DataFrame.

That’s a quick introduction to Rapid API and dealing with its JSON output. Every API is different - you’ll have to play around.

7.2.3. Data on Kaggle#

Kaggle is also a great source for data. You can search their data sets here.

Searching for finance, I see one on consumer finance complaints that looks interesting. The Kaggle page describes the data, gives you a data dictionary, and some examples.

The data for Kaggle contests is usually pretty clean already. That said, you’ll usually have to do at least some work to get it ready to look at.