The sports industry is one of the most attractive and sturdy in entertainment. The level of attention to the top sports events is impressively high. That’s why sports betting is an exciting way to earn money. A simple spectator, who is familiar with the current team situation, can easily “invest” in them. Plus, gambling can make sports more interesting personally for you. So today, we will be talking about sports betting and some useful APIs for its implementation.
What are Sports Betting APIs?
In short, the bookmaker is an organization that proposes some coefficients for sports events before or directly during the event. For example, matches, fights, tournaments, etc. If the potential consumer finds those coefficients adequate, there is a possibility to bet. Betting is a game where you need to weigh the odds and probabilities for making the most proficient gamble.
But what is the coefficient? Let’s imagine it as a multiplier of success. If, for example, some specific action during a football match will have a coefficient of 1.7, then successful betting on it will multiply your winning money. However, in case of failure, the money will go the bookmaker — dangerous, random, but a beautiful game.
Popular Bet Types
Before we dive in, let’s go over a few key sports betting terms:
Moneyline
The moneyline is the amount of money at stake.
Practical example:
A basketball game between Bulldogs and Snakes. You can make your bet on either one of them, but there will always be outsiders and favorites. For example, the probability of the stronger team (favorite) winning is higher, so if you bet on them, you won’t win as much money.
This is where a moneyline becomes useful. If you look at the money lines for this game and see this picture:
Bulldogs +150, Snakes -170.
What does it mean?
Well, Snakes are the favorites to win the game, so the earnings will be lower. According to this, you will need to bet $170 for a standard $100 profit.
Bulldogs are weaker, so the bet is riskier, but the jackpot will be more. In this case, you will win a pure $150 from $100 bet. Pure means that the final amount of transactions will be $250 (income plus basic bet). The principle is simple, remember that the potential loser always has a plus (+) sign, while the expected winner has a minus (-).
Point Spread Line
The point spread is the difference between the final game results. According to the previous example, Bulldogs may have +10 and Snakes -10.
Logic is pure – the worse team probably will lose with some gap to the better team. In this case, by 10 points.
So here you can try to predict two possible scenarios:
- Snakes will win ten or more point difference,
- or Bulldogs lose with nine or less.
In the case where there’s an equally 10 point difference, you will get your bet money back.
Total Line
The total line is the entire points count. Here is a prediction for a summary of the final point results. Usually, it’s like a threshold — certain bounds are over or under it.
For example, Bulldogs and Snakes could score a total of 180 points together. And you can predict if the real result will be in the upper or lower bound against it.
Now let’s talk about APIs. Application programming interfaces, or APIs, are a way to build useful and straightforward software interactions. It’s a predefined set of rules (i.e., questions) that can control user actions within the program. APIs make program-user interaction more comfortable and more productive.
Communication is based on a request-response procedure. The first one is a question from the user (what are the available bets for the Bulldogs game). The second is an answer for this task (wagers, coefficients, etc.) that is returned in a standard way.
Usually, there are four popular request types:
- GET – when the user asks something from the program
- POST – adding some new information to the application directly from the client
- PUT / PATCH – modification of the previously added data
- DELETE – removing some information from the server
With knowledge about gambling and API structure, we can move further. Right now, the critical task will be in the real sports betting API implementation.
For our project, we’ll be using TheRundown‘s sports betting API.
How to use TheRundown’s Sports Betting API on RapidAPI
Prerequisites
Of course, different implementations require some technical stack. In our case, we will use Python. But we won’t just run the necessary Python files, we will also focus on the web application. So for this purpose, we will be using Flask — lightweight, swift, and very powerful micro-framework.
Also, there is a need to make requests with responsive handling. Python has many high-quality solutions and requests are one of them. Both libraries should be installed in your Python version (whatever it will be — local or virtual). The most obvious way is via pip command.
pip install flask pip install requests
After that, you can go to the project directory and create file main.py. For now, let’s add the following content:
from flask import Flask app = Flask(__name__) @app.route("/") def home(): return "Hello world!" if __name__ == "__main__": app.run(debug=True)
You can test this app by running the file and visit your localhost in the browser. If all is good, the language prerequisites are done, so let’s talk about APIs.
RapidAPI
If you don’t want to waste your time on searching API hub process, you should take a look at the RapidAPI. Here you can find everything possible for APIs. One account will give you access to over 10,ooo APIs, including TheRundown, the API we will be using in this tutorial.
A user account on RapidAPI gives private and non-limited access to all the existing endpoints here. One can create multiple applications for projects separately, make some direct interaction, and not be afraid about security and storage.
Making an API Call
Finally, it’s time to do some practice test calls. One of the most interesting sports betting APIs is TheRundown. You can find it just by search on the main RapidAPI page.
This is a compelling and informative betting system. Here you can find detailed information about various sports and leagues per many different affiliates. Also, this API allows getting more advanced bets during real-time moments of game, e.g., 1st Quarter / Period situation.
The main window of the concrete API can be subdivided into a few sections. Let’s talk about them briefly.
The upper part of the page is delegated to the description tabs. There are four of them:
- endpoints – this is the mainframe or API console where we can explore the existing requests, test them and even find some useful snippets for various languages
- API details – information from the API authors, it can be in the docs format or just a link to some other pages
- discussions – discussion threads for questions about using the API
- pricing – tiered subscription plans based on API usage. hint: there’s a freemium plan that gives you 25 free API calls/day. However, it’s likely you’ll need to subscribe to a heavier usage plan if you plan on having a lot of queries.
Let’s test some endpoints of TheRundown. First of all, it can be helpful to find out all the supportable sports. Pick the Sports dropdown object on the left side and choose the GET Sports request.
As you may see, it doesn’t require any parameters for the request, so we can immediately execute it. Press the Test Endpoint button and you should see the response on the right side of the window.
TheRundown supports data for multiple sports and we can interact with any of them. Let’s choose basketball, for example.
Take note that the unique sport_id of the basketball is 4.
Also, on the screen above, you can find a snippet on Python with an endpoint using. It looks like a signal to return to our Flask application, doesn’t it?
Process the response
All that we want right now is the same response from our code as in the browser test. Modify main.py with the following lines:
from flask import Flask import requests app = Flask(__name__) url = "https://therundown-therundown-v1.p.rapidapi.com/" headers = { 'x-rapidapi-host': "therundown-therundown-v1.p.rapidapi.com", 'x-rapidapi-key': "<YOUR_RAPIDAPI_KEY>" } # Endpoints sports = "sports" @app.route("/") def home(): response = requests.request("GET", url + sports, headers=headers) return response.json() if __name__ == "__main__": app.run(debug=True)
As you may notice, the code is modified by adding a few objects for headers (valuable data for HTTP communication) and URL. In the home method, we call the request and return all response in the JSON format. Right now, if you run this file, the output should look something like this:
Now that we’ve successfully connected to the API, let’s explore some practice applications.
Example: Create a Dynamic Bidding Guide
It is evident that right now our app is not very functional. To demonstrate what you can do with the TheRundown API, we will continue expanding the application.
The idea of the app is that it will be the guide for the actual basketball games in the NBA. Users will have not only short information about teams and locations but also an overview of all the opened betting lines.
The main endpoint of this application — events by sport. Here we need to point the sports_id (4 for the basketball, remember?). The response should be similar to this:
At this moment, there are three games and we would like to make some cards with each of them. Each card will contain the place of the game, time, and both participating teams. In the lower part, we will add three dropdown lists for moneylines, spread lines, and totals with all available affiliates.
Let’s prepare all the necessary data on the server-side. Open main.py and paste this code:
from flask import Flask, render_template import requests app = Flask(__name__) url = "https://therundown-therundown-v1.p.rapidapi.com/" headers = { 'x-rapidapi-host': "therundown-therundown-v1.p.rapidapi.com", 'x-rapidapi-key': "<YOUR_RAPIDAPI_KEY>" } # Endpoints nba_events = "sports/4/events" def get_lines(line_periods): bets = {} bets["moneylines"] = [] bets["spreads"] = [] bets["totals"] = [] for line_index in line_periods: line = line_periods[line_index]['period_full_game'] affiliate = line['affiliate']['affiliate_name'] bets["moneylines"].append("{0} : {1} {2}".format(line['moneyline']['moneyline_home'], line['moneyline']['moneyline_away'], affiliate)) bets["spreads"].append("{0} : {1} {2}".format(line['spread']['point_spread_home'], line['spread']['point_spread_away'], affiliate)) bets["totals"].append("over {0}; under {1} {2}".format(line['total']['total_over'], line['total']['total_under'], affiliate)) return bets @app.route("/") def get_events(): querystring = {"include":["all_periods","scores"]} response = requests.request("GET", url + nba_events, headers=headers, params=querystring).json() events = [] for event in response['events']: event_data = {} event_data['time'] = event['event_date'] event_data['place'] = "{0}, {1}".format(event['score']['venue_name'], event['score']['venue_location']) event_data['teams'] = "{0} - {1}".format(event['teams'][1]['name'], event['teams'][0]['name']) event_data['bets'] = get_lines(event['line_periods']) events.append(event_data) return render_template('index.html', events = events) if __name__ == "__main__": app.run(debug=True)
Don’t worry, a significant part of the code is just a response parsing.
After the request is sent, the received JSON data needs to be prepared. Our task is to make the data structure that will store all events with selected information. A brief description of the game is taken from the primary event node. Pay attention, that the final object with data is a dictionary.
However, with odds, we need to be more delicate. As they are stored in the deeper layer (event->line_periods->period_full_time), there is a separate method for getting this data.
Finally, the code returns the template of the HTML-page with the event information. Now it’s part of prettifying the visualization, and this will be released via Flask templates.
As we don’t want to dive deep into web development today, let’s use some Bootstrap styles. They are free-to-use, cover many use cases, and have detailed documentation. Today we will use two components: dropdowns and cards.
First of all, create folder static inside of the project directory. This folder usually responds to static resources. In our case, there will be only one custom stylesheets file. Create a style.css file here and paste the next lines:
.grid-container { display: grid; grid-template-columns: auto auto auto; padding: 10px; grid-row-gap: 50px; grid-column-gap: 50px; } .grid-item { padding: 20px; width: auto; }
These two classes will help display our game cards in the adaptive and helpful grid. Now return to the root directory of the project and create a templates folder. Here, Flask will be looking for HTML templates. We will need two of them.
Create a file base.html and add this code:
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Custom style file --> <link rel="stylesheet" href="{{ url_for ('static', filename='style.css')}}"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> <title>{% block title %} Base page {% endblock %}</title> </head> <body> {% block body %} Body block {% endblock %} </body> </html>
Here we add the required files: static styles and Bootstrap scripts.
Also, pay attention to the {% %} blocks. It’s called Jinja2 and allows us to make more advanced HTML templates. For example, Jinja connects sent Python objects with templates, extends layouts, etc.
Now we can finally create the main template of the project – index.html:
{% extends 'base.html' %} {% block title %} NBA booking {% endblock %} {% block body %} <h1 class="display-4" style="text-align: center;">NBA events betting lines</h1> <div class="grid-container"> {%for event in events%} <div class="card grid-item" > <div class="card-body"> <center><h6 class="card-subtitle mb-2 text-muted">{{ event['place'] }}</h6></center> <center><h5 class="card-title">{{ event['teams'] }}</h5></center> <center><h6 class="card-subtitle mb-2 text-muted">{{ event['time'] }}</h6></center> <center> <div class="btn-group"> <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Moneylines </button> <div class="dropdown-menu"> {% for bet in event['bets']['moneylines'] %} <a class="dropdown-item" href="#">{{ bet }}</a> {% endfor %} </div> </div> <div class="btn-group"> <button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Spread lines </button> <div class="dropdown-menu"> {% for bet in event['bets']['spreads'] %} <a class="dropdown-item" href="#">{{ bet }}</a> {% endfor %} </div> </div> <div class="btn-group"> <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Total lines </button> <div class="dropdown-menu"> {% for bet in event['bets']['totals'] %} <a class="dropdown-item" href="#">{{ bet }}</a> {% endfor %} </div> </div> </center> </div> </div> {% endfor %} </div> {% endblock %}
We’ve now implemented the dropdown and card objects in loops based on the event data.
Now save all your files and test out your project:
From our example, there are only three available games. Each of them is shown in the separate card with dropdowns for possible odds. Each odd category has a list of possible scores from different affiliates. With this app, you can now see whenever the hot NBA games are coming.
Conclusion
Today we have introduced a powerful sports betting API known as TheRundown. It supports dozens of sources in different sports that can be tracked and used. Also, we discovered the importance of the API use and tried to receive the request handly from the RapidAPI hub. Finally, we have created a useful bidding guide on the next stack: RapidAPI + TheRundown + Flask + Bootstrap. The project is informative and shows all the advantages of the betting APIs for real sports fans. Especially, if they are also passionate programmers.
I just landed up in your blog and I really appreciate your blog. Your blog is very informative and easy to understand. you are sharing good information for Sports Betting software development
That’s awesome to hear kirti! Thanks for dropping by.
Hi,
This is amazing, all the major scripts are here. Thank you for sharing the codes.
Hello,
Thank you for this blog it’s very helpful. For some reason why I try running the code I get an error for the website that says:
json.decoder.JSONDecodeError: Extra data: line 1 column 5 (char 4)
and it says there’s an error in this line of code:
response = requests.request(“GET”, url + nba_events, headers=headers, params=querystring).json()
I was wondering if you have any idea why this could be the case? I copy and pasted the code from the blog, followed the directions and I have a valid key to pull info from the API.
Thanks!
I am having the same issue.
Any help would be much appreciated!