Middles Summary
Get aggregate statistics for current middle opportunities without the full list. Uses the same underlying data as the Middles endpoint.
GET /api/v1/opportunities/middles/summaryAuthentication
Requires API key. Pro tier or higher required.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sport | string | all | Filter by sport (e.g., basketball, football) |
league | string | all | Filter by league (e.g., nba, nfl, nhl) |
Example Requests
cURL
curl -X GET "https://api.sharpapi.io/api/v1/opportunities/middles/summary?league=nfl" \
-H "X-API-Key: YOUR_API_KEY"Response
Success (200)
{
"success": true,
"data": {
"total": 47,
"positive_ev_count": 38,
"guaranteed_profit_count": 2,
"player_prop_count": 12,
"by_sport": {
"football": 18,
"basketball": 15,
"hockey": 8,
"baseball": 6
},
"by_market": {
"point_spread": 22,
"total_points": 13,
"player_points": 7,
"player_rebounds": 5
},
"by_sportsbook": {
"draftkings": 34,
"fanduel": 31,
"betmgm": 22,
"caesars": 18,
"bet365": 15
},
"avg_middle_size": 1.8,
"avg_probability": 0.1245,
"avg_ev": 4.72,
"best_ev": {
"ev": 31.52,
"sport": "football",
"market": "point_spread"
},
"has_key_numbers_count": 14
},
"meta": {
"source": "cache",
"filters": {
"sport": null,
"league": ["nfl"]
},
"updated_at": "2026-02-17T19:45:30Z"
}
}Response Headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 296
X-RateLimit-Reset: 1707401000
X-Data-Delay: 0
X-Request-Id: req_msum789defError Responses
401 Unauthorized
{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key",
"docs": "https://sharpapi.io/docs/authentication"
}
}403 Tier Required
{
"error": {
"code": "tier_restricted",
"message": "Middles detection requires Pro tier or higher",
"docs": "https://sharpapi.io/docs/pricing"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
total | integer | Total number of current middles |
positive_ev_count | integer | Middles with positive expected value |
guaranteed_profit_count | integer | Middles that are also arbitrage opportunities |
player_prop_count | integer | Middles on player prop markets |
by_sport | object | Count of middles per sport |
by_market | object | Count of middles per market type |
by_sportsbook | object | Count of middles per sportsbook (each book in a middle is counted) |
avg_middle_size | number | Average middle gap size in points |
avg_probability | number | Average probability of middles hitting |
avg_ev | number | Average expected value per $100 wagered |
best_ev | object|null | Highest EV opportunity summary |
best_ev.ev | number | EV in dollars per $100 wagered |
best_ev.sport | string | Sport of the best EV middle |
best_ev.market | string | Market type of the best EV middle |
has_key_numbers_count | integer | Middles containing sport-specific key numbers |
Use Cases
Dashboard Overview
Use the summary endpoint to power dashboard widgets showing middle opportunity counts, breakdowns, and averages without fetching the full list.
Polling vs Full Fetch
Poll the summary endpoint at shorter intervals to detect when new opportunities appear, then fetch the full Middles endpoint only when the count changes.
// Poll summary every 10 seconds
let lastCount = 0;
setInterval(async () => {
const summary = await fetchMiddlesSummary();
if (summary.data.total !== lastCount) {
lastCount = summary.data.total;
const middles = await fetchMiddles(); // Full fetch
updateUI(middles);
}
}, 10000);The summary endpoint is cached for 10 seconds and counts toward your rate limit the same as the full middles endpoint.
Related Endpoints
- Middles — Full list of middle opportunities
- +EV Opportunities — Positive expected value bets
- Arbitrage Opportunities — Guaranteed profit opportunities
- SSE Stream — Real-time
middles:detectedandmiddles:expiredevents
Last updated on