Build an arbitrage betting scanner in Python
A working arbitrage scanner in under 70 lines of Python. Pull head to head odds from many bookmakers, find prices that beat the margin, and split the stake.
Guide ยท Updated June 2026
An arbitrage bet backs every outcome of a game at different bookmakers so you profit whichever way it lands. It exists when the implied probabilities of the two sides add up to less than 100 percent. This guide builds a scanner in Python: pull head to head odds from many books over the RapidOddsAPI REST endpoint, group each game across books, check every pair of prices for an arb, then split your stake so the return is the same on both sides.
Bookmakers price the same game slightly differently. Now and then they disagree enough that you can back one side at one book and the other side at another and lock in a profit before the result is even known. The maths is short. The real work is watching enough bookmakers to catch the gap while it is open, which is what the odds API does for you. We will build the whole thing step by step, then put it together into one script you can run.
The idea in one line
Each price has an implied probability, which is just 1 / price. Add the implied probability of the two sides together. If they come to less than 100 percent, the two books have left a gap, and that gap is your profit.
For example, 2.10 on one team at one book and 2.10 on the other team at another book gives 0.476 + 0.476 = 0.952, or about 95 percent. That is under 100 percent, so backing both sides returns about 5 percent no matter who wins.
Step 1: pull the odds
Ask the REST endpoint for head to head odds from the bookmakers you want to compare. One thing to know about Australian books: many brands share a single odds feed, so you pass the feed name (for example Sportsbet, TAB, Ladbrokes), not the individual clone brands, since books on the same feed always show the same price.
Step 2: group each game across books
The response returns one entry per game and bookmaker pair, so the same game appears once for every book you asked for. Before you can compare prices you need all of a game's books in one place, so merge the entries that belong to the same game.
Here we match games by team name, which is enough when each matchup happens once. If the same teams can play twice in a day, or different books list slightly different start times, you also need to match on the start time. That is its own topic, covered in the game matching guide.
Step 3: collect every price for each team
For a single game, gather every head to head price on offer for each team, and remember which book is offering it. This gives you two lists, one per team, ready to compare.
Step 4: check every pair of books
Now try each price on one team against each price on the other. Skip pairs from the same book, since an arb needs two different bookmakers. Keep the lowest combined margin you find, because that is the most profitable arb for the game.
It is tempting to just take the single best price on each side, but that can miss an arb where one book happens to top both teams. Checking every pair is a few more lines and never misses one.
Step 5: split the stake
When an arb exists you want the same payout no matter who wins, so you stake more on the shorter price. Each side gets a share of the total stake equal to its implied probability divided by the combined margin.
The profit percentage is (1 / margin - 1) * 100. A margin of 0.952 is a return of about 5 percent on the total stake.
The full scanner
Put the pieces together and you have a complete scanner. It pulls the odds, groups each game, checks every pair of books, and prints any arb it finds with the stake to place on each side.
What you get back
When the scanner finds an arb it prints the game, the profit, and the exact stake for each side. A real arb looks like this:
Stake 48.10 on the Blue Jays at 2.18 and 51.90 on the Red Sox at 2.02. If the Blue Jays win you collect 104.85, and if the Red Sox win you collect 104.85. Either way you are up 4.85 on your 100 stake, whoever wins.
Things to know before betting real money
- Arbs are short lived. Books correct their prices quickly, so an arb can be gone in seconds. To catch them as they appear, stream prices over the WebSocket feed instead of polling on a timer.
- Add a margin buffer. A tiny edge can vanish before both bets are placed. Many tools only act on arbs above a minimum profit, for example 1 percent, rather than anything below 1.0.
- Coverage matters. The more bookmakers you compare, the more arbs you see. See the full bookmaker coverage.
Taking it further
This scanner covers head to head, which is the simplest market because it has two outcomes that always oppose each other. You can point the same approach at more markets and more sports, with small changes to the logic.
- More sports. Change the SPORT value to scan NFL, NBA, AFL, NRL, and the rest. The whole script works as is, since the response shape is the same for every sport.
- Totals and spreads. These have a point field, so only outcomes on the same line can be paired (over 8.5 against under 8.5, not under 9.5). Group prices by their point value first, then run the same arb check within each line.
- Player props. Same as totals and spreads, but you also match on the player_name field, so you only compare the same player on the same line across books.
- Three way markets. Soccer head to head has home, draw and away, so you check three implied probabilities instead of two, and the same under 100 percent rule applies.
See the full list of sports and markets on the coverage page.
Next steps
You have a working 2-way arbitrage scanner. To make it production ready, stream odds over WebSocket so you react the instant a price moves, and handle games properly with the game matching guide. For other tools you can build on the same data, see what you can build with an odds API, or read the full API documentation.
Start building with RapidOddsAPI
Real-time, standardised odds from 100+ bookmakers over REST and WebSocket. Start free with 250 credits, no credit card required.