Skip to Content
API ReferenceMiddles Summary

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/summary

AuthenticationPermalink for this section

Requires API key. Pro tier or higher required.

Query ParametersPermalink for this section

ParameterTypeDefaultDescription
sportstringallFilter by sport (e.g., basketball, football)
leaguestringallFilter by league (e.g., nba, nfl, nhl)

Example RequestsPermalink for this section

curl -X GET "https://api.sharpapi.io/api/v1/opportunities/middles/summary?league=nfl" \ -H "X-API-Key: YOUR_API_KEY"

ResponsePermalink for this section

Success (200)Permalink for this section

{ "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 HeadersPermalink for this section

X-RateLimit-Limit: 300 X-RateLimit-Remaining: 296 X-RateLimit-Reset: 1707401000 X-Data-Delay: 0 X-Request-Id: req_msum789def

Error ResponsesPermalink for this section

401 Unauthorized

{ "error": { "code": "unauthorized", "message": "Invalid or missing API key", "docs": "https://docs.sharpapi.io/en/authentication" } }

403 Tier Required

{ "error": { "code": "tier_restricted", "message": "Middles detection requires Pro tier or higher", "docs": "https://docs.sharpapi.io/en/pricing" } }

Response FieldsPermalink for this section

FieldTypeDescription
totalintegerTotal number of current middles
positive_ev_countintegerMiddles with positive expected value
guaranteed_profit_countintegerMiddles that are also arbitrage opportunities
player_prop_countintegerMiddles on player prop markets
by_sportobjectCount of middles per sport
by_marketobjectCount of middles per market type
by_sportsbookobjectCount of middles per sportsbook (each book in a middle is counted)
avg_middle_sizenumberAverage middle gap size in points
avg_probabilitynumberAverage probability of middles hitting
avg_evnumberAverage expected value per $100 wagered
best_evobject|nullHighest EV opportunity summary
best_ev.evnumberEV in dollars per $100 wagered
best_ev.sportstringSport of the best EV middle
best_ev.marketstringMarket type of the best EV middle
has_key_numbers_countintegerMiddles containing sport-specific key numbers

Use CasesPermalink for this section

Dashboard OverviewPermalink for this section

Use the summary endpoint to power dashboard widgets showing middle opportunity counts, breakdowns, and averages without fetching the full list.

Polling vs Full FetchPermalink for this section

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.

Last updated on