Sports modelling guide
How to build a sports betting model with an odds API
The formula is easy. The edge lives in correctly matched markets, honest timestamps and prices your model could actually have taken.
Free key. 1,000 requests every month. No credit card.
Most betting models fail before the prediction starts.
They compare different lines, train on prices that arrived later, ignore suspended markets and call the result an edge. Better algorithms cannot rescue dirty evidence.
A useful sports betting model does one job: estimate a probability, compare it with an available price and say no when the evidence is weak. It does not need to begin with machine learning. A market-derived fair-price model is already a real model if its rules are explicit and its test is honest.
Collect clean odds → match the exact market → remove margin → estimate fair probability → compare the offered price → test out of sample.
- 01Observe
event · market · line · price · time - 02Price
fair_probability = remove_vig(odds) - 03Compare
edge = offered_odds / fair_odds - 1 - 04Reject
stale · mismatched · unavailable
No clean evidence. No signal.
Choose what you are modelling
“Sports betting model” covers three different jobs. Pick one before collecting a row of data.
Outcome model
Team, player and game data produce a probability of an outcome. Elo, Poisson, logistic regression and machine learning sit here.
Market model
Bookmaker and exchange prices produce an estimate of fair probability. The market is the input, not merely the benchmark.
Hybrid model
Your forecast starts the price. Market evidence calibrates, challenges or vetoes it before a decision is made.
One sport, one league, one market and one fixed decision time. Complexity can wait. Clean measurement cannot.
Build the data contract first
The maths only works when every price belongs to the same event, market and selection. Home −3.5 is not home −4. A first-half total is not a full-game total. One player’s points line is not another player’s line.
| Evidence | Fields to retain | What it prevents |
|---|---|---|
| Event identity | event_id, league, participants, start time | Joining prices to the wrong fixture |
| Market identity | market, period, metric, player, side and line | Comparing similar-looking but different bets |
| Selection identity | selection_key and complete outcome roster | Removing vig from incomplete markets |
| Price state | bookmaker, decimal odds and availability | Treating suspended or missing prices as tradable |
| Time | source time, receipt time and snapshot time where supplied | Letting future information leak into the past |
The modelling process
Build it in this order. Each step protects the one after it.
- 01
Collect observations causally
Store what the source said and when your system actually received it. The distinction matters in every backtest.
- 02
Create stable identities
Key events, markets, periods, selections, players and lines independently of the current price.
- 03
Preserve availability
A disappeared or suspended line becomes unavailable. Do not silently carry its previous price forward.
- 04
Validate complete markets
Require every mutually exclusive outcome before removing margin. Reject mixed lines, periods or players.
- 05
Remove vig per bookmaker
Convert each complete market to no-vig probabilities before combining sources. Never average raw probabilities carrying different margins.
- 06
Estimate fair probability
Keep multi-book, Pinnacle and exchange-derived estimates separate. Record why each source was available—or why it was rejected.
- 07
Calculate offered edge
Compare the fair probability with the price that is actually available at the target bookmaker.
- 08
Simulate execution
Apply delay, price movement, limits, partial fills, commission, voids and rejections. A theoretical price is not an executed bet.
- 09
Test forward through time
Train on earlier events and evaluate on later ones. Never let the same event cross training and test boundaries.
- 10
Fail closed
Missing identity, freshness or availability should produce no signal. Your model should be excellent at refusing bad evidence.
Turn odds into a fair price
Decimal odds contain an implied probability plus the bookmaker’s margin. Remove that margin before calling anything fair.
raw_probability = 1 / decimal_odds
overround = sum(raw_probabilities) - 1
fair_probability = raw_probability / sum(raw_probabilities)
fair_odds = 1 / fair_probability
The multiplicative method above is a clean baseline. Additive, power and Shin methods can produce different estimates, especially in uneven markets. Pick the method before testing. Do not switch methods because one makes the backtest prettier.
Consensus, Pinnacle or Betfair?
No single source is automatically the truth. Each one answers a different question.
| Source | Best use | Strength | Failure mode |
|---|---|---|---|
| Multi-book consensus | Broad, stable coverage | Reduces dependence on one bookmaker | Correlated feeds, stale inputs and weak source selection |
| Pinnacle no-vig | A sharp-book benchmark | Simple and interpretable | Missing markets, stale prices or different settlement rules |
| Betfair order book | Executable market evidence | Back, lay, size, spread and matched activity | Thin liquidity, wide spreads, commission and partial fills |
Use Pinnacle as a benchmark, not an oracle
Pinnacle can provide a strong no-vig reference when the exact market is present, complete and current. It can still be missing, stale or settled differently from the bookmaker you are comparing. “Sharp-book benchmark” is defensible. “True probability” is not.
Inspect Pinnacle odds API coverage and access.
Use exchange depth, not last traded price
An exchange shows more than a sportsbook quote. Back and lay ladders, available size, spread width, matched volume and market state all matter. Last traded price can be old, tiny or impossible to execute at your stake.
A midpoint is useful only when the book is tight and liquid. Commission changes the break-even probability. Treat the order book as evidence, not decoration.
Calculate the edge
Once the model has a fair price, compare it with the offered price.
Fair odds2.00
Offered odds2.10
Estimated EV5.0%
EV = offered_odds / fair_odds - 1
Five per cent EV means an estimated five cents of profit per unit staked under the probability assumption. It does not mean a 5% chance of winning. It does not promise a 5% return. If the fair price is wrong or the offered price disappears, the edge disappears with it.
Backtest what could have happened
A backtest using tomorrow’s information is fiction with a spreadsheet attached.
At every historical decision time, use only the data already received and the price actually available then.
- Split chronologically. Random train/test splits leak changing team strength and market regimes.
- Keep the same event entirely inside one split.
- Use the price available at the decision time—not a later closing price—as the offered price.
- Model observation delay, decision delay and price movement.
- Track disappeared and suspended prices instead of assuming continuous availability.
- Apply commission, limits, stake constraints, voids, rejections and partial fills.
- Fit probability calibration on past validation data only.
Measure more than profit
Measures squared probability error. Lower is better.
Punishes confident wrong probabilities heavily.
Selections priced at 60% should win roughly 60% over a representative sample.
Compares your taken price with a causally constructed closing reference for the exact selection.
Shows how many model signals remained available after realistic delay.
Shows how often the model had enough evidence to produce a valid estimate.
Then segment everything by sport, league, market, bookmaker, odds band, time to start and liquidity. One aggregate number can hide a model that only works in one narrow pocket.
The mistakes that fake an edge
- Using closing odds as historical inputs. The model sees information it would not have had.
- Comparing different lines or periods. Similar labels do not create equivalent markets.
- Removing vig from an incomplete market. The missing outcome does not vanish from probability space.
- Treating Pinnacle as ground truth. Sharp is useful. Infallible is marketing.
- Treating last traded as executable. A tiny old trade is not a price available for your stake.
- Ignoring missing prices. Carrying stale prices forward manufactures opportunities.
- Tuning thresholds on the test set. That converts the test set into training data.
- Judging the model by a hot month. Short-term profit can be noise. Calibration and execution evidence travel better.
Build the first version for free
The odds-api.net Sandbox includes a free API key and 1,000 requests every month. That is enough to prove authentication, inspect real event and odds responses, validate your market keys and run the fair-price maths locally.
It is not enough for high-frequency collection or a serious historical dataset. That is the point of the first build: prove the contract before paying to scale it.
curl --request GET \
--header "X-API-Key: $ODDS_API_KEY" \
"https://api.odds-api.net/v1/events/{event_id}/odds/snapshot?price_fields=odds,fair&include_unavailable=true"
Each line can include nullable fair_odds. A null value means the response did not contain enough comparable no-vig evidence for that selection.
Scale when the model earns it
1,000 requests per month. Prove the API, schema and calculation.
50,000 base API credits, 60 requests per minute and one concurrent stream.
2 million base API credits and eight concurrent streams for broader collection.
Historical odds are a separate add-on on eligible paid plans. Check the current pricing and retention terms before designing a backtest around them.
Build the boring parts first
Match the market. Keep the timestamps. Reject stale data. Remove the vig. Test through time.
Then earn the right to make the model clever.
Sources and method
The product statements were checked against the current odds-api.net public API contract, coverage tools, pricing and public developer package on 13 September 2026. The formulas are standard industry calculations. Examples are illustrative, not performance claims or betting advice.