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)
Real response for GET /api/v1/opportunities/middles/summary?sport=baseball (captured 2026-07-02):
{
"data": {
"by_league": {
"mexico_-_lmb": {
"avg_expected_value": 3.33,
"avg_quality_score": 1,
"count": 22
},
"mlb": {
"avg_expected_value": 10.47,
"avg_quality_score": 3.2,
"count": 72
}
},
"by_sport": {
"baseball": {
"avg_expected_value": 8.8,
"avg_quality_score": 2.69,
"count": 94
}
},
"total": 94
},
"updated_at": "2026-07-02T18:22:29.38658773Z"
}Response Headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 296
X-RateLimit-Reset: 1707401000
X-Data-Delay: 0
X-Request-Id: 1782526326424224-82519Error Responses
401 Unauthorized
No key supplied returns missing_api_key; a bad key returns invalid_api_key.
{
"error": {
"code": "missing_api_key",
"message": "API key required. Pass via X-API-Key header, api_key query parameter, or Bearer token.",
"docs": "https://sharpapi.io/docs/authentication"
}
}403 Tier Restricted
{
"error": {
"code": "tier_restricted",
"message": "This endpoint requires Pro tier or higher",
"docs": "https://sharpapi.io/pricing",
"tier": "hobby",
"required_tier": "pro"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
total | integer | Total current middles matching the filters |
by_sport | object | Per-sport buckets, keyed by sport slug |
by_sport.<sport>.count | integer | Number of middles in this sport |
by_sport.<sport>.avg_quality_score | number | Average middle quality score for this sport |
by_sport.<sport>.avg_expected_value | number | Average expected value for this sport |
by_league | object | Per-league buckets, keyed by league slug — same {count, avg_quality_score, avg_expected_value} shape |
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 is computed from the same in-process result set as the full Middles endpoint (refreshed each engine cycle) 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