About the project
Free odds APIs only give you the current price. History is paywalled. So LineDrift builds its own dataset — snapshotting bookmaker odds every four hours — and turns that time series into no-vig consensus probabilities and value flags. It is a data pipeline built under a real constraint, not a CRUD demo.
Why it exists
The Odds API's free tier gives 500 credits a month, and its historical endpoints cost 10× the live ones. Rather than pay for history, LineDrift manufactures it: a scheduled job records the match-winner (1X2) market for the Premier League, Danish Superliga, and — while it is on — the FIFA World Cup in decimal odds across EU bookmakers, and stores every reading in Postgres.
The whole project is designed around that ceiling — which is exactly the story worth telling. Every architectural choice below falls out of it.
Architecture
Ingest · every 4 hours
Serve · per request
The only endpoint that writes is the snapshot route, guarded by a bearer secret and safe to retry. Every other page reads Postgres directly in a React Server Component. Raw API JSON is validated by Zod at a single boundary, so the rest of the app never sees an untrusted shape.
The value engine
A bookmaker's odds bake in their margin. The value engine strips that out, builds a consensus fair price from the market, and flags any bookmaker paying meaningfully more than consensus. Here is the whole chain on a sample match — the numbers below are computed live by the same functions the app runs.
p = 1 / oddsPinnacle's 2.10 home price implies 47.6%, the draw 29.4%, the away 27.8%.
Σ implied − 1Those three add up to more than 100%. The excess — 4.8%here — is the bookmaker's margin, shown per book on every match.
implied / Σ impliedDividing each implied probability by their sum removes the margin, leaving a fair line that totals 100%: home 45.4%, draw 28.1%, away 26.5%.
mean no-vig, ≥ 3 booksAveraging the no-vig probabilities across all bookmakers quoting a full line gives the market's consensus. With fewer than 3 books there is no consensus and nothing is flagged. For this sample: .
The budget
One snapshot costs regions × markets credits per league — two credits a run for the domestic leagues, three while the World Cup has fixtures (its key bills nothing between tournaments). Running every four hours keeps even a World Cup month inside the free tier.
Off-season a run is two credits, so usage sits near ~360 a month; a World Cup month rises to ~486 — still under 500. Development and tests never touch the live API; a single saved response fixture powers all of it, and the schedule is the only knob if credits run low.
Operations
The numbers below are read live from the pipeline's own run log: every snapshot run — including failed ones — records what it saw and what the API said was left of the monthly budget.
Educational analytics project. Not betting advice.
odds × consensus − 1The best home price is 2.36 at Betfair. Against consensus that is an edge of +4.3% — at or above the 3% threshold, so it is flagged as value.
open / close − 1Once a match kicks off, every earlier price is graded against the closing line — each bookmaker's last pre-kickoff quote, the market's most informed estimate. An opener of 2.36 against a 2.21 close works out to +6.8%: beating the close consistently is the classic test of whether "value" was real. Finished matches get a closing-line report on their detail page.
Sample match · no-vig home %
| Book | Home | Draw | Away | No-vig home |
|---|---|---|---|---|
| Pinnacle | 2.10 | 3.40 | 3.60 | 45.4% |
| Bet365 | 2.08 | 3.35 | 3.65 | 45.6% |
| Betfair | 2.36 | 3.30 | 3.40 | 41.5% |