Arbitrage API for sports betting
Arbitrage API data: the best price on every side at identical lines across sportsbooks and exchanges, plus an MCP tool that finds arbs with stakes.
Arbitrage API data comes from /v1/best-lines, which returns the best price on each side at identical lines across every sportsbook and exchange, so checking for an arb is one sum. The find_arbitrage MCP tool runs the whole scan and works out the stakes for you.
- Best price per side at identical lines
- Exchanges and prediction markets included
- find_arbitrage MCP tool with stakes per leg
- Pre-game on every paid plan, in-play on Syndicate
An arbitrage API has one job: put every book's price on the same market, at the same line, at the same moment, so you can see when the best prices on each side pay the same return whichever side wins. PreciseAPI has no /v1/arbitrage endpoint. It has /v1/best-lines, which compares every sportsbook and exchange quoting a market and returns the best price on each side, and an MCP tool, find_arbitrage, that runs the whole scan and works out the stakes for you. This page covers the math, the requests, the code and the limits you will run into.
The arbitrage condition
Convert each side's best price to decimal odds and add up the reciprocals. Each reciprocal is that side's implied probability, so the sum is the combined implied probability of the market across the books you would use. Inside one book the sum is always above 1, because the margin is built in. When the best prices on each side come from different books, the sum can drop below 1, and that gap is the arb.
For a market whose sides are priced at decimal odds d1, d2 … dn:
- Combined implied probability: S = 1/d1 + 1/d2 + … + 1/dn
- It is an arb when S < 1, and the return on the total stake is 1/S − 1 whichever side wins
- The stake on side i, for a total stake T, is T × (1/di) / S
- Every side then pays the same amount, T / S
A worked example: an NBA total of 224.5 has the Over at +104 (2.04) at one book and the Under at +100 (2.00) at another. S = 0.4902 + 0.5000 = 0.9902, so the return is 1/0.9902 − 1 = 0.99%. With $100 in total, stake $49.50 on the Over and $50.50 on the Under, and either result pays about $100.99. The arbitrage calculator runs the same numbers for two- and three-way markets.
Arbitrage API data: /v1/best-lines
/v1/best-lines does the comparison an arb check starts from. For each market it groups every source quoting the identical line (same market key, period, line, and player or team), picks the best price on each side, and lists every book posting that price in best_books. books_quoting says how many sources were compared, and a market needs at least two to appear. DFS apps, suspended markets and promotional lines are left out, and alternate ladders are not compared.
One call costs 3 credits and covers up to 200 events. It defaults to the full-game moneyline, spread and total; markets, periods and books narrow it, and format=decimal returns prices ready for the sum above. Pass books with the books you hold accounts at, because an arb you can't place is only a number.
curl "https://api.preciseapi.com/v1/best-lines?league=nba&markets=moneyline,spread,total&format=decimal" \
-H "Authorization: Bearer $PRECISEAPI_KEY"
A shortened response, with one market:
{
"data": [
{
"id": "evt_1iazqk4srnb",
"league": "nba",
"status": "scheduled",
"home": { "id": "nba_phx", "name": "Phoenix Suns", "abbr": "PHX" },
"away": { "id": "nba_sas", "name": "San Antonio Spurs", "abbr": "SAS" },
"markets": [
{
"key": "total",
"period": "full_game",
"line": 224.5,
"books_quoting": 19,
"outcomes": [
{ "id": "sel_0v1c8b2k9qa", "name": "Over", "side": "over", "point": 224.5, "best_price": 2.04, "best_books": ["prophetx"] },
{ "id": "sel_2m7d0x4ru1e", "name": "Under", "side": "under", "point": 224.5, "best_price": 2, "best_books": ["betmgm", "caesars"] }
]
}
]
}
],
"meta": { "request_id": "req_…", "count": 1, "credits_used": 3, "credits_remaining": 149412, "generated_at": "2026-11-11T18:02:11.204Z" }
}
Finding arbs in code
This script is the core of an arbitrage API integration: it checks every market in the response and prints the margin and the stake per leg.
const res = await fetch(
'https://api.preciseapi.com/v1/best-lines?league=nba&markets=moneyline,spread,total&format=decimal',
{ headers: { Authorization: `Bearer ${process.env.PRECISEAPI_KEY}` } },
);
const { data } = await res.json();
const TOTAL_STAKE = 100;
for (const event of data) {
for (const m of event.markets) {
// One book can't arb itself: the legs need at least two books between them.
const books = new Set(m.outcomes.flatMap((o) => o.best_books));
if (m.outcomes.length < 2 || books.size < 2) continue;
const s = m.outcomes.reduce((sum, o) => sum + 1 / o.best_price, 0);
if (s >= 1) continue;
console.log(`${event.away.abbr} @ ${event.home.abbr} ${m.key} ${m.line ?? ''}: ${((1 / s - 1) * 100).toFixed(2)}%`);
for (const o of m.outcomes) {
const stake = (TOTAL_STAKE * (1 / o.best_price)) / s;
console.log(` ${o.name} ${o.point ?? ''} @ ${o.best_price} (${o.best_books.join(', ')}): stake ${stake.toFixed(2)}`);
}
}
}
The same loop handles three-way soccer moneylines, since it sums however many outcomes a market has. Decimal prices are rounded to three places; for margins measured in hundredths of a percent, request the default American odds and convert them yourself.
The arbitrage odds API route over MCP
If you work in Claude, ChatGPT, Cursor or another AI client, the PreciseAPI MCP server runs the scan for you. find_arbitrage takes a league and checks every upcoming game, up to 60 per call (25 for player prop boards), for markets where the best prices on each side, at two or more different books, add up to less than 100%. It returns each leg's book, price and stake, the payout and the profit, sorted by margin.
The options: books limits legs to the books you can bet at; markets is main (moneyline, spread and total) or props; period picks a half, quarter or other period; min_margin_pct sets the smallest return to report, 0 by default, and a negative value down to −5 also shows near-arbs; total_stake defaults to 100. Each call costs 3 credits, like the /v1/best-lines call it reads, and a call that ends in an error is not charged.
{
"markets_scanned": 214,
"total_stake": 100,
"arbitrage": [
{
"event_id": "evt_1iazqk4srnb",
"game": "San Antonio Spurs @ Phoenix Suns",
"starts": "Wed, Nov 11, 9:00 PM EST",
"market": "Total",
"margin_pct": 0.99,
"legs": [
{ "bet": "Over 224.5", "book": "ProphetX", "price": "+104", "stake": 49.5 },
{ "bet": "Under 224.5", "book": "BetMGM", "price": "+100", "stake": 50.5 }
],
"payout": 100.99,
"profit": 0.99
}
]
}
Ask "any arbitrage on MLB totals between DraftKings, FanDuel and Novig?" and the client fills in the arguments. The odds API MCP guide shows how to connect each app.
Using it as an odds API for arbitrage bots
An arb lasts only until the slower book moves, so refresh rate matters more than anything else in the loop. On Edge, polling one league's best lines every 30 seconds uses 8,640 credits a day out of 150,000 a month. Sharp and Syndicate have unlimited credits and rate limits of 1,200 and 3,000 requests a minute. Syndicate adds the WebSocket stream, which sends a snapshot and then only the markets that changed, and in-play odds.
Two details keep a scanner honest. max_source_age_ms (1 to 300,000) leaves out quotes whose last read from the source is older than you allow; set it with care, because a price that hasn't changed is re-sent only every few minutes and can be current while it looks old. And exchange or prediction market legs have depth: /v1/odds returns liquidity on each exchange outcome, and venues may charge fees the price doesn't show.
PreciseAPI is a data provider only. It doesn't place bets or connect to sportsbook accounts, and whether automated betting is allowed is set by each book's terms.
Why no arbitrage API can promise a sure thing
The math is exact; the conditions around it are not. Before treating any result as certain, keep these in mind:
- Prices move. An arb is an observation at the time of the call, and by the time you place the second leg the first price may be gone.
- Books limit arbers. Recreational books often cut the stakes of, or close, accounts that bet arbs consistently, and most can void bets placed at an obviously wrong price.
- Rules differ. Books settle overtime, retirements and postponements differently, so two legs on "the same" market can settle on different terms.
- Depth is finite. An exchange price may have only a few dollars behind it.
Verify every price on the book's own site before placing anything. PreciseAPI doesn't give betting advice, and nothing on this page guarantees a profit.
Plans and credit costs
| Edge | Sharp | Syndicate | |
|---|---|---|---|
| Price | $49.99 / month | $199.99 / month | $249.99 / month |
| Credits | 150,000 / month | Unlimited | Unlimited |
/v1/best-lines (3 credits) | Pre-game | Pre-game | Pre-game and in-play |
find_arbitrage over MCP (3 credits) | Pre-game | Pre-game | Pre-game and in-play |
| Player prop markets | Yes | Yes | Yes |
| Rate limit | 300 / minute | 1,200 / minute | 3,000 / minute |
| WebSocket stream | No | No | Yes |
The free Sandbox has 50 credits for the dashboard chat but no API or MCP access, so an arbitrage API setup starts on Edge. See odds API pricing for the full comparison.
Related tools and pages
- The arbitrage calculator checks one opportunity by hand, with stakes per leg.
- How to find arbitrage bets walks through the process end to end.
- The odds comparison API page covers
/v1/best-linesin full. - The positive EV API finds single prices that beat the no-vig fair line.
- The glossary explains line shopping and the betting exchange.
- The live odds API covers in-play prices on Syndicate.
Frequently asked questions
Does PreciseAPI have an arbitrage endpoint?
No. There is no /v1/arbitrage REST endpoint; the arbitrage API workflow is to compute arbs from /v1/best-lines, which returns the best price on each side at identical lines, or call the find_arbitrage MCP tool, which scans a league and returns stakes per leg. Both cost 3 credits.
Is PreciseAPI an arb betting API that places bets?
No. It is a data feed: prices, best lines, line history and scores. It doesn't place bets, hold funds or connect to sportsbook accounts.
Which books can be legs of an arb?
Any sportsbook or exchange in the feed, including prediction markets such as Kalshi and Polymarket. DFS pick'em apps are left out, because their payouts are not cash odds. Books that share a trading platform often post identical prices, so they rarely form an arb with each other.
Can I find arbs on live games?
Only on Syndicate, which includes in-play odds. On Edge and Sharp, /v1/best-lines and find_arbitrage cover games that haven't started, and the MCP tool tells you how many live games it left out.
Is there a free trial?
The Sandbox is free, with 50 credits for the dashboard chat and no card required, but it has no API or MCP access. API keys work from the Edge plan at $49.99 a month.
How an arb check works
For each market, /v1/best-lines compares every sportsbook and exchange quoting the identical line and returns the best price on each side with the books posting it. Convert those prices to decimal and add the reciprocals: a sum below 1 means the best prices, placed at different books, pay the same return, 1/sum − 1, whichever side wins. Stake each side in proportion to its reciprocal. DFS apps, suspended markets and alternate ladders are left out, and one call costs 3 credits for up to 200 events.
Arbs over MCP, and their limits
In Claude, ChatGPT or Cursor, the find_arbitrage tool scans a league’s upcoming games, keeps to the books you can bet at, and returns each leg’s book, price and stake for the total you choose, at 3 credits a call. Every result is an observation at the time of the call: prices move, books limit accounts that bet arbs, and settlement rules differ between books. Verify each price before placing anything; PreciseAPI provides data, not betting advice.
Example request
GET /v1/best-lines?league=nba&markets=moneyline,spread,total&format=decimal
Endpoint
- GET /v1/best-lines: Best lines
What teams build with it
- Odds screens: Build a real-time odds screen: every book’s price side by side, the best line highlighted and updates in under a second, from one normalized odds API.
- Media & affiliates: An odds API for affiliates, media and tipsters: live odds tables, best-price widgets and deep links to each book’s bet slip, from one normalized feed.
Related reading
- Line Shopping API: Finding the Best Prices Across Every Book: How to find the best available price for every outcome across sportsbooks and exchanges in code. Matching outcomes, comparing prices and numbers, /v1/best-lines versus computing it yourself, freshness and credit budgets.
- Implied Probability From Odds Data: Formulas, Overround and Code: Compute implied probability from odds data at scale. Formulas in both directions, the format=probability option and its rounding, overround across a whole response, pushes, probability curves from alternate ladders, consensus across books and probability time series.
- Odds API Node.js Tutorial: Streaming Real-Time Odds with WebSockets: Build a reliable Node.js client for real-time odds with the ws package. Snapshots, deltas, sequence-gap detection, resync and reconnects with backoff.
More products
- Positive EV API: Positive EV API data: every book’s price next to the no-vig fair line from the market consensus or a sharp book like Pinnacle, ranked by edge.
- No-vig odds API: No vig odds API data: implied probabilities from every book with format=probability, so you can remove the margin from any market and get fair odds.
- Sports scores API: Sports scores API with live scores, the game clock and final results on the same event ids as the odds, for scoreboards, live screens and bet grading.
- Line movement API: Line movement API with every price change from the opening line to the close, per book, for line charts, steam alerts and closing line value tracking.
Responses use the same event, market and outcome ids as every other endpoint. Prices are American odds by default, with format=decimal and format=probability for the other two, and a market whose source has stopped reporting is flagged suspended instead of being shown as live.
Every source and league is on the coverage page, and what each request costs is on the pricing page.