Detecting +EV Bets with an API: A Complete Developer Guide
What Is a +EV Bet and Why Should Developers Care?
Positive expected value (+EV) betting is the practice of identifying wagers where the true probability of an outcome is higher than what the bookmaker's odds imply. In plain math: if a sportsbook offers +150 on a team you calculate has a 45% chance of winning, your expected value is positive — over a large sample, you profit. Most casual bettors ignore EV entirely. Developers building betting tools, analytics dashboards, or alert systems can automate the detection of these edges at scale.
The challenge has historically been data: to calculate EV you need both the best available odds across books AND a sharp estimate of the true probability (the 'fair' or 'no-vig' line). Scraping individual sportsbooks, normalizing formats, and computing fair odds yourself is an enormous lift. That's exactly the problem a betting analytics API solves — it delivers pre-computed fair odds, best odds, and EV scores in a single normalized JSON response, so you can focus on building logic rather than wrangling data.
MoneyLine's API exposes +EV detection natively through the /v1/edge endpoint, and also provides the raw ingredients — bestOdds, fairOdds, and avgOdds — throughout the /v1/odds response so you can derive your own EV calculations on any market. This guide walks through both approaches with real field references and code patterns.
Using the /v1/edge Endpoint for Pre-Computed +EV Detection
The fastest path to detecting +EV bets in your application is the /v1/edge endpoint. Rather than pulling raw odds and doing the EV math yourself, this endpoint returns opportunities that have already been identified as having positive expected value, arbitrage potential, or meaningful edge against the market. Authentication uses the x-api-key header — every request must include it.
A typical request targets a specific league. For example, querying edge opportunities for the NFL looks like: GET /v1/edge?leagueId=nfl with header x-api-key: YOUR_KEY. The response returns an array of event-level objects. Each object includes an eventId you can cross-reference with /v1/events, plus market breakdowns organized by marketType (moneyline, spread, total, or a specific player prop market like player_points). Within each market you'll find outcomes identified as +EV, including the bookmaker offering the mispriced line and the magnitude of the edge.
The edge endpoint covers all six supported leagues — NFL, NBA, MLB, NHL, NCAAF, and NCAAB — and updates as odds move, so polling it on a short interval (say, every 60–90 seconds for live markets) gives you a near real-time feed of opportunities. Pair the eventId from the edge response with a call to /v1/events to retrieve the game's schedule details, current score if live, and status, giving users full context around each identified bet.
For developers building alert systems, the recommended pattern is: poll /v1/edge on your chosen interval, diff the response against your last snapshot, and push notifications only for newly appeared opportunities or those where the EV percentage has materially increased. This avoids spamming users with the same opportunity repeatedly while ensuring genuine new edges surface immediately.
Computing EV Yourself with /v1/odds: fairOdds vs bestOdds
If you want full control over EV calculation — perhaps applying your own probability models or adjusting for specific books you have access to — the /v1/odds endpoint gives you everything you need. The response structure is normalized across all supported leagues and markets. At the event summary level, moneyline, spread, and total are each returned as arrays of objects. Each object contains: name (the outcome label, e.g. 'Kansas City Chiefs'), an optional point for spreads and totals, fairOdds (the no-vig consensus probability expressed as an American odds value), bestOdds (the highest price currently available across tracked bookmakers), and avgOdds (the market average).
The EV formula using American odds is straightforward. Convert fairOdds to an implied probability: if fairOdds is -110, implied probability = 110 / (110 + 100) = 52.38%. Convert bestOdds to a decimal multiplier: if bestOdds is +105, decimal = 2.05. EV% = (impliedProbability * decimalOdds) - 1. A positive result means the bet has positive expected value at the best available price. In JavaScript: const fairProb = fairOdds < 0 ? Math.abs(fairOdds) / (Math.abs(fairOdds) + 100) : 100 / (fairOdds + 100); const bestDecimal = bestOdds > 0 ? (bestOdds / 100) + 1 : (100 / Math.abs(bestOdds)) + 1; const ev = (fairProb * bestDecimal) - 1;
The bookmakers array in the /v1/odds response drills down further. Each entry has a bookmakerId, bookmakerName, sourceType (indicating whether it's a sharp book, exchange, or recreational sportsbook), and a markets array. Each market object has a marketType and an outcomes array where each outcome contains name, an optional point, and price (the American odds at that specific book). This lets you filter EV calculations to only books a user has access to, or weight your fair-odds estimate more heavily toward sharp sourceType books like pinnacle-style exchanges.
A practical filtering pattern: iterate the outcomes in the event summary, compute EV for each where bestOdds > fairOdds on a probability basis, then look up which specific bookmaker is offering that bestOdds price by cross-referencing the bookmakers array. Return only opportunities where EV exceeds your threshold (a common starting point is 2%) and where the bookmaker offering the price is one the user has an account with. This produces a personalized, actionable +EV feed rather than a raw data dump.
Detecting +EV Player Props with /v1/player-props
Player props markets are often softer than game lines — books set them with less precision and sharp money moves them more slowly. This makes props one of the highest-yield areas for +EV detection. MoneyLine's /v1/player-props endpoint returns player-level data nested by player, with each player object including teamAbbr and teamName for easy roster context, plus the same fairOdds, bestOdds, and avgOdds structure found in the main odds endpoint.
To target props for a specific game, include the eventId in your query: GET /v1/player-props?eventId=EVENT_ID&leagueId=nba. You can also query by leagueId alone to pull all available prop markets across the league's slate for a given day. The response groups outcomes by market type — for NBA this includes markets like player_points, player_rebounds, player_assists, player_threes; for NFL you'll see player_passing_yards, player_rushing_yards, player_receiving_yards, player_anytime_td, and more.
The EV computation logic is identical to game lines — compare fairOdds to bestOdds for each outcome — but props warrant an additional filter: line movement. If bestOdds on a player's over has moved from -115 to +105 in the last hour while fairOdds has stayed flat, that's a signal the market is moving against the book's opening number, which often amplifies EV. While MoneyLine's API doesn't expose historical snapshots directly, you can implement this yourself by storing each poll's response in a time-series database (Postgres with timestamptz, or a time-series store like TimescaleDB) and querying the delta.
For developers building consumer-facing tools, surfacing +EV props with a player's team context (via teamAbbr and teamName) alongside the specific book offering the best price creates a highly actionable UI. A user sees: 'LeBron James (LAL) — Points Over 25.5 — +EV 3.4% — Best odds: +108 at BookX vs fair odds of +101.' That's a complete picture derived entirely from the /v1/player-props and /v1/edge responses without any additional data sources.
Building a Real-Time +EV Alert System: Architecture Tips
A production-grade +EV alert system built on MoneyLine's API typically follows a polling-and-diff architecture. A backend worker (Node.js, Python, or Go all work well) polls /v1/edge and /v1/odds on a configurable interval. The interval should adapt to context: pre-game lines for tomorrow's slate can be checked every 5 minutes, while live in-game markets warrant 30–60 second polling to catch rapid line movement. MoneyLine's free tier supports meaningful query volume for personal and commercial use, so you have room to build without immediate rate-limit pressure.
Store the latest response snapshot in memory or a fast cache layer like Redis. On each new poll, compute a diff: which eventIds are new, which outcomes have changed their EV status, and which have crossed your EV threshold for the first time in this session. Only events in the diff trigger downstream actions — push notifications, webhook calls to a Discord bot, SMS via Twilio, or entries in an alert database table. This keeps notification volume manageable and ensures users receive timely, non-redundant signals.
For multi-user products where different users have different book access or EV thresholds, store user preferences in your database and apply them as a post-processing filter on the shared API response. Because MoneyLine returns data for all tracked bookmakers in a single normalized response, you pull once and filter many times — avoiding N×users API calls per interval. This is far more efficient than per-user polling and keeps your infrastructure costs low even at scale.
Finally, enrich your stored alert records with context from /v1/events (game time, status, teams) and /v1/ai/chat for natural-language summaries. A query to /v1/ai/chat asking 'Why might this player prop be +EV today given recent performance?' can generate an LLM-powered insight that makes your alerts more engaging and defensible to end users, not just a raw number.
FAQ
What is the difference between the /v1/edge endpoint and computing EV from /v1/odds?
The /v1/edge endpoint returns pre-computed positive expected value, arbitrage, and edge opportunities — it's the fastest way to detect +EV bets without writing your own math. The /v1/odds endpoint gives you the raw ingredients (fairOdds, bestOdds, avgOdds) so you can apply your own EV formula, probability adjustments, or book filters. Most production applications use both: /v1/edge for quick alerting and /v1/odds for custom analytics.
How do I authenticate requests to the MoneyLine API?
All requests require an x-api-key header containing your API key. For example, in a fetch call: fetch('https://api.moneyline.com/v1/edge?leagueId=nfl', { headers: { 'x-api-key': 'YOUR_KEY' } }). The same header applies to every endpoint including /v1/odds, /v1/player-props, /v1/events, /v1/best-bets, and /v1/ai/chat.
Which fields in the odds response do I use to calculate expected value?
Use fairOdds as your estimate of true probability (no-vig consensus) and bestOdds as the price you can actually get in the market. Convert fairOdds to an implied probability, convert bestOdds to a decimal multiplier, and compute EV% = (impliedProbability × decimalMultiplier) - 1. A result above 0 (or your chosen threshold like 0.02 for 2%) indicates a +EV opportunity. These fields appear in the moneyline, spread, and total arrays at the event summary level, and also within /v1/player-props outcomes.
Does the MoneyLine API support live or in-game +EV detection?
Yes. The /v1/edge and /v1/odds endpoints update continuously as odds move, including during live games. For in-game +EV detection, poll on a shorter interval (30–60 seconds) and cross-reference eventId with /v1/events to confirm game status. Live markets tend to move faster, so timely polling is important to capture opportunities before lines correct.
Can I detect +EV player props for all six supported leagues?
Yes. The /v1/player-props endpoint supports NFL, NBA, MLB, NHL, NCAAF, and NCAAB. Each player object includes teamAbbr, teamName, and nested market outcomes with fairOdds and bestOdds. The available prop market types vary by sport — for example, NFL includes passing/rushing/receiving yards and touchdowns, while NBA includes points, rebounds, assists, and three-pointers. Query by leagueId to get all props for a league's current slate, or include an eventId to narrow to a specific game.
Is the MoneyLine API free to use for commercial projects?
MoneyLine offers a free tier that covers both personal and commercial use, making it accessible for developers building production applications without upfront cost. This includes access to the core endpoints — /v1/odds, /v1/edge, /v1/player-props, /v1/events, /v1/best-bets, and /v1/ai/chat — across all six supported leagues.