Sports arbitrage scanner with Slack alerts

Scan US and European sportsbooks every 15 minutes for guaranteed-profit arbitrage opportunities and get them pushed to Slack with stake splits ready to place.

Deterministic Code
The Odds APISlackFinancePersonal ProductivityNotifications & AlertsResearch & Monitoring

Build a deterministic sports arbitrage scanner that watches The Odds API for guaranteed-profit opportunities across bookmakers and pushes them into Slack the moment they appear.

Trigger: cron every 15 minutes. Only run inside a configurable active-hours window (default: a wide US window, 9am to 1am US Eastern). Skip the run entirely outside the window.

Inputs (all should be workflow-configurable with sensible defaults):

- Sports list, as The Odds API sport keys. Default: americanfootball_nfl, basketball_nba, baseball_mlb, icehockey_nhl, americanfootball_ncaaf, basketball_ncaab.

- Regions, comma-separated. Default: us,us2,eu.

- Market: h2h (moneyline) only. Odds format: decimal.

- Bankroll size in dollars. Default: 1000.

- Minimum profit margin to alert on. Default: 0.005 (0.5%).

- Slack channel ID (or name) to post alerts to.

On each tick:

1) For each configured sport, call The Odds API "Get Odds" with the configured regions, markets=h2h, oddsFormat=decimal. Be efficient with credits: one call per sport with all regions joined is fine.

2) For each event returned: skip if commence_time is within 10 minutes of now (too late to place both legs). Then for each outcome name across the event (e.g. Team A, Team B, and Draw if present), find the best (highest) decimal price across all returned bookmakers and remember which bookmaker offered it.

3) Compute the arbitrage sum: sum of 1/best_price across all outcomes. If sum < 1.0, this is an arbitrage. Profit margin = 1 - sum. Skip if profit margin is below the configured minimum.

4) Compute the stake split for the configured bankroll: stake_i = bankroll * (1/best_price_i) / sum. Round to two decimals. Guaranteed payout = bankroll / sum.

5) Deduplicate within the run by (event_id, set of bookmakers used) so the same opportunity at the same book pair is not posted twice in one tick.

6) For each surviving arb, use Slack's "Send a Message" operation to post to the configured channel. Format the message clearly:

- Header: sport, matchup (Home vs Away), and commence time in US Eastern.

- Profit line: profit margin as a percentage and the guaranteed payout for the configured bankroll.

- Per-leg lines: outcome name, bookmaker title, decimal price, and stake to place.

- Footer: tick timestamp.

Use Slack mrkdwn formatting (*bold*, not **bold**).

Error handling: if The Odds API returns 429 with OUT_OF_USAGE_CREDITS, log it and exit cleanly (do not post). If a single sport call fails, continue with the others. Log how many credits were consumed using the x-requests-last header so the user can monitor quota drift.

The math is fully deterministic, so this should be implemented as a code workflow (no LLM in the loop).

Additional information

What does this prompt do?
  • Every 15 minutes during your active hours, pulls live moneyline odds across major US and European sportsbooks for the sports you care about.
  • Finds events where the best available prices across books add up to a guaranteed profit (a real arbitrage), no matter which side wins.
  • Posts each opportunity to Slack with the matchup, the two books you'd bet at, the exact stake split for your configured bankroll, and the locked-in profit percentage.
  • Skips opportunities that tip off in under 10 minutes and avoids reposting the same arb twice in a run, so the alert feed stays clean and actionable.
What do I need to use this?
  • A The Odds API account (the free Starter plan gets you 500 monthly credits to try it out).
  • A Slack workspace and the channel you want the alerts to land in.
  • Your bankroll size and the list of sports you want to watch (defaults to NFL, NBA, MLB, NHL, NCAAF, and NCAAB).
How can I customize it?
  • Change how often it scans, or narrow the active hours to your local evening window.
  • Pick which sports, regions, and bookmakers are included so the scanner only watches books you can actually bet at.
  • Set your bankroll and minimum profit threshold so only arbs above a certain edge get pushed to Slack.

Frequently asked questions

What is sports arbitrage and is this finding real opportunities?
Sports arbitrage means betting every outcome of an event at different sportsbooks where the combined prices guarantee a profit no matter who wins. This scanner does the standard math: it adds up the inverse of the best decimal odds at each outcome, and if the total is below 1.0, the gap is your locked-in margin. It is the same approach published in The Odds API's official arbitrage tutorial.
Will the free Starter plan from The Odds API be enough?
It depends on how many sports and regions you scan. The free tier gives you 500 credits per month and each odds request costs credits based on sports and regions selected. Scanning six US sports across three regions every 15 minutes will exceed the free tier, so most serious users move to a paid plan. You can start narrow on the free plan to see how often arbs surface.
How do I change which Slack channel the alerts go to?
When you set up the workflow you pick the channel during configuration. You can swap it later from the workflow settings without rebuilding anything, and you can point it at a private channel or a direct message if you want the alerts to stay personal.
Will it spam me with the same arbitrage over and over?
No. Each run deduplicates by event and bookmaker pair, so a given matchup at a given pair of books is only posted once per scan. The next scan starts fresh, which is what you want because prices change and the arb may have closed.
Why does it skip events that start in under 10 minutes?
Sportsbooks pull lines fast as game time approaches, and you usually cannot place both legs in time. Filtering out anything starting within 10 minutes keeps the feed focused on opportunities you can actually act on.

Stop refreshing odds screens looking for an edge.

Connect The Odds API and Slack once, and Geni will scan the books every 15 minutes and ping you the second a guaranteed-profit opportunity shows up.