+EV Opportunities
Find positive expected value betting opportunities across all sportsbooks.
GET /api/v1/opportunities/evThis endpoint replaces the former /positive-ev and /value-bets endpoints. All scoring fields (confidence_score, kelly_percent, fair_probability) are now included in every response.
Multi-book results: When multiple sportsbooks are +EV on the same selection, the API returns a separate opportunity for each book. For example, if DraftKings is +105, FanDuel is +103, and BetMGM is +101 on the same moneyline, you’ll see three entries — each with its own sportsbook, odds_american, ev_percentage, kelly_percent, and confidence_score. Results are sorted by EV% descending by default, so the best-odds book appears first. Use the sportsbook filter to narrow to specific books.
Authentication
Requires API key. Pro tier or higher required. Your account must have the ev feature enabled.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sport | string | all | Filter by sport(s), comma-separated (e.g. basketball, football, ice_hockey) |
league | string | all | Filter by league(s), comma-separated (e.g. nba, nfl, nhl) |
sportsbook | string | tier-allowed | Filter by sportsbook(s), comma-separated. Tier limits enforced. |
market | string | all | Filter by market type(s), comma-separated. Supports category aliases (main, spread, total, props) or exact types (point_spread, player_points). |
event | string | all | Filter by game/event ID(s), comma-separated |
min_ev | number | 0 | Minimum EV percentage threshold |
max_ev | number | — | Maximum EV percentage threshold |
live | boolean | — | true = live only, false = prematch only, omit = both |
min_odds | number | — | Minimum American odds (e.g., -200) |
max_odds | number | — | Maximum American odds (e.g., +500) |
min_market_width | number | — | Minimum market width (vig indicator). Lower width = sharper market. |
max_market_width | number | — | Maximum market width |
max_odds_age | number | — | Maximum odds age in seconds. Filters out stale opportunities where the underlying odds are older than this threshold. |
date_range | string | — | Filter by event date: today, tomorrow, or week. Dates are evaluated in US Eastern Time (ET). |
sort | string | -ev | Sort field. Options: ev, confidence/confidence_score, kelly/kelly_percent, time/start_time, book_count/books. Prefix with - for descending. |
limit | integer | 50 | Results per page (max 200) |
offset | integer | 0 | Pagination offset (max 5000) |
Filtering Multiple Values
Use comma-separated values for multi-select filters:
?sportsbook=draftkings,fanduel&league=nba,nflExample Requests
cURL
# Basic EV opportunities for NBA
curl -X GET "https://api.sharpapi.io/api/v1/opportunities/ev?league=nba&min_ev=2" \
-H "X-API-Key: YOUR_API_KEY"Response
Success (200)
{
"success": true,
"data": [
{
"id": "ev_dk_nba_33483153_ml_PHO",
"game_id": "evt_nba_phi_pho_20260208",
"ev_percentage": 4.2,
"odds_american": -105,
"odds_decimal": 1.952,
"no_vig_odds": -118,
"fair_probability": 0.541,
"market_width": 3.2,
"devig_method": "power",
"sharp_book": "pinnacle",
"selection": "PHO Suns",
"market": "moneyline",
"line": null,
"sportsbook": "draftkings",
"game": "PHI 76ers vs PHO Suns",
"sport": "basketball",
"league": "nba",
"home_team": "PHI 76ers",
"away_team": "PHO Suns",
"start_time": "2026-02-08T19:00:00Z",
"is_live": false,
"confidence_score": 87,
"kelly_percent": 0.021,
"book_count": 5,
"arb_available": false,
"arb_profit": null,
"is_player_prop": false,
"player_name": null,
"stat_category": null,
"possibly_stale": false,
"oldest_odds_age_seconds": null,
"warnings": [],
"detected_at": "2026-02-08T14:22:10.456Z"
},
{
"id": "ev_fd_nba_33483153_ml_PHO",
"game_id": "evt_nba_phi_pho_20260208",
"ev_percentage": 2.8,
"odds_american": -108,
"odds_decimal": 1.926,
"no_vig_odds": -118,
"fair_probability": 0.541,
"market_width": 3.2,
"devig_method": "power",
"sharp_book": "pinnacle",
"selection": "PHO Suns",
"market": "moneyline",
"line": null,
"sportsbook": "fanduel",
"game": "PHI 76ers vs PHO Suns",
"sport": "basketball",
"league": "nba",
"home_team": "PHI 76ers",
"away_team": "PHO Suns",
"start_time": "2026-02-08T19:00:00Z",
"is_live": false,
"confidence_score": 82,
"kelly_percent": 0.015,
"book_count": 5,
"arb_available": false,
"arb_profit": null,
"is_player_prop": false,
"player_name": null,
"stat_category": null,
"possibly_stale": false,
"oldest_odds_age_seconds": null,
"warnings": [],
"detected_at": "2026-02-08T14:22:10.456Z"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"has_more": false,
"next_offset": null
},
"meta": {
"source": "redis",
"last_update": "2026-02-08T14:22:10.456Z",
"summary": {
"count": 24,
"avg_ev": 3.8,
"max_ev": 7.1,
"by_sportsbook": {
"draftkings": 9,
"fanduel": 8,
"betmgm": 7
},
"by_sport": {
"basketball": 12
},
"by_market": {
"moneyline": 5,
"point_spread": 4,
"player_points": 3
}
},
"filters": {
"sport": null,
"league": ["nba"],
"sportsbook": null,
"market": null,
"min_ev": 2.0,
"max_ev": null,
"live": null,
"sort": "-ev",
"include": null
}
}
}Response Headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 298
X-RateLimit-Reset: 1707401000
X-Data-Delay: 0
X-Request-Id: req_abc123def456Error Responses
401 Unauthorized
{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key",
"docs": "https://docs.sharpapi.io/en/authentication"
}
}403 Feature Required
{
"error": {
"code": "feature_required",
"message": "The 'ev' feature is required. Upgrade to Pro or higher.",
"docs": "https://docs.sharpapi.io/en/pricing"
}
}429 Rate Limited
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded",
"docs": "https://docs.sharpapi.io/en/api-reference/overview"
}
}Response Fields
Core Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique opportunity identifier (hash) |
game_id | string|null | Associated game/event identifier |
external_event_id | string|null | Sportsbook’s native event ID |
selection_id | string|null | Sportsbook’s native outcome/selection ID (for deep linking to the bet slip) |
ev_percentage | number | Expected value as a percentage (e.g., 4.2 = 4.2% EV). Deprecated alias: ev_percent. |
odds_american | number | Current American odds at the sportsbook |
odds_decimal | number | Decimal odds (e.g., 1.952) |
no_vig_odds | number|null | Fair (no-vig) American odds derived from the sharp line |
fair_probability | number|null | No-vig (devigged) fair probability (0.0 to 1.0) |
market_width | number|null | Width of the market (vig indicator) |
devig_method | string | De-vig method used (e.g., power) |
sharp_book | string | Sharp book used as reference (e.g., pinnacle). Deprecated alias: devig_book. |
selection | string | The selection (team name, Over/Under, player, etc.) |
market | string | Market type (moneyline, point_spread, total_points, etc.) |
line | number|null | Spread/total line (e.g., -3.5, 220.5) |
sportsbook | string | Sportsbook offering these odds. Multiple entries may exist for the same selection if several books are +EV. |
game | string | Human-readable game name |
sport | string | Sport identifier (lowercase) |
league | string | League identifier |
home_team | string|null | Home team name |
away_team | string|null | Away team name |
start_time | string|null | ISO 8601 event start time |
is_live | boolean | Whether the event is currently live |
confidence_score | number | Multi-factor confidence score (0-100) |
kelly_percent | number|null | Kelly criterion optimal bet fraction (0.0 to 1.0) |
book_count | number | Number of sportsbooks offering this market |
arb_available | boolean | Whether an arbitrage exists on this market |
arb_profit | number|null | Arbitrage profit percentage if available |
is_player_prop | boolean | Whether this is a player prop market |
player_name | string|null | Player name (if player prop) |
stat_category | string|null | Stat type (if player prop, e.g., points, rebounds) |
possibly_stale | boolean | true if underlying odds may have moved since detection |
oldest_odds_age_seconds | number|null | Age of the stalest odds used in the EV calculation (seconds) |
warnings | string[] | Data quality warnings (e.g., POTENTIALLY_STALE_ODDS, LIVE_STALE_ODDS) |
detected_at | string | ISO 8601 timestamp when the +EV was first detected |
Meta Summary Fields
| Field | Type | Description |
|---|---|---|
summary.count | number | Total opportunities matching filters |
summary.avg_ev | number | Average EV across all results |
summary.max_ev | number | Highest EV found |
summary.by_sportsbook | object | Opportunity count per sportsbook |
summary.by_sport | object | Opportunity count per sport |
summary.by_market | object | Opportunity count per market type |
Understanding Expected Value
Expected Value (EV) measures the average profit or loss per bet over time. A positive EV (+EV) bet means you have a mathematical edge over the sportsbook.
EV% = (fair_probability x decimal_odds - 1) x 100Where:
fair_probability= No-vig probability derived from the sharp book (Pinnacle)decimal_odds= The decimal odds offered by the soft book
How SharpAPI Calculates EV
SharpAPI uses Pinnacle (a sharp book with efficient odds) as the source of truth for fair probability.
Step 1: Get the sharp book odds
Pinnacle: Team A -115 / Team B +105Step 2: Remove the vig to find fair probability (Power method)
// Implied probabilities (with vig)
probA = 1 / 1.87 = 0.535 // -115 in decimal = 1.87
probB = 1 / 2.05 = 0.488 // +105 in decimal = 2.05
total = 1.023 // 2.3% vig
// Power devig: solve for k where probA^k + probB^k = 1
// k ≈ 1.036 for this market
fairProbA = 0.535^1.036 = 0.522 (52.2%)
fairProbB = 0.488^1.036 = 0.478 (47.8%)Step 3: Compare to a soft book
DraftKings: Team A -105 (decimal 1.952)
Fair probability: 52.3%
EV% = (0.523 x 1.952 - 1) x 100
EV% = +2.1%A +2.1% EV means you expect to profit $2.10 for every $100 wagered on this bet over time.
Why This Works
| Book Type | Characteristics |
|---|---|
| Sharp (Pinnacle) | Low vig, efficient odds, accurate probabilities |
| Soft (DraftKings, FanDuel, BetMGM) | Higher vig, slower to adjust, exploitable |
When soft books are slow to update their odds after a market move, their implied probability deviates from reality, creating a +EV opportunity.
EV Thresholds
| EV % | Quality | Suggested Action |
|---|---|---|
| < 0% | Negative EV | Avoid |
| 0 - 2% | Marginal | Only viable at high volume |
| 2 - 5% | Good | Standard profitable threshold |
| 5%+ | Excellent | High confidence opportunities |
We recommend setting min_ev=2 for most use cases. Marginal EV (below 2%) can be eroded by line movement before you place the bet.
Kelly Criterion
The kelly_percent field tells you the optimal fraction of your bankroll to wager according to the Kelly criterion (0.0 to 1.0, e.g. 0.021 = 2.1%):
Kelly% = (edge / odds_to_1) = (fair_prob x decimal_odds - 1) / (decimal_odds - 1)Kelly Sizing Guide
| Kelly % | Risk Level | Recommendation |
|---|---|---|
| < 1% | Low | Small edge, consider skipping |
| 1 - 3% | Moderate | Standard bet size |
| 3 - 5% | Aggressive | Strong edge, but size carefully |
| 5%+ | Very aggressive | Excellent edge; consider fractional Kelly (half or quarter) |
Variance Warning: +EV does not guarantee profit on every bet. Over 100 bets at 5% EV, actual results can range widely. The edge only materializes over hundreds or thousands of bets. Never bet more than you can afford to lose.
Best Practices
- Set a minimum EV threshold - Use
min_ev=2or higher to focus on meaningful edges - Use Kelly sizing - Use
kelly_percentto determine bet size (multiply by bankroll) - Filter by confidence - Use
confidence_scoreto prioritize high-confidence opportunities - Monitor
market_width- Narrow markets (low width) indicate more efficient pricing and more reliable EV calculations - Act quickly - +EV opportunities are fleeting; lines move fast
- Track your results - Log every bet and compare actual ROI to expected EV over time
- Use fractional Kelly - Most professionals use quarter or half Kelly to reduce variance
Related Endpoints
- Arbitrage Opportunities - Guaranteed profit across books
- Low Hold Opportunities - Tightest lines across books
- Middles - Line discrepancy opportunities
- Best Odds - Find the best price across all books
- EV Calculation Concepts - Deep dive into the math