Skip to Content
API ReferenceClosing Line Value (CLV)

Closing Line Value (CLV)

Analyze how well a sportsbook’s closing odds compare to Pinnacle’s devigged (no-vig) probability. Positive CLV means the book closed looser than Pinnacle — a historical proxy for edge.

GET /api/v1/historical/clv

Sharp tier or higher required. Pro and lower tiers receive a 403 tier_restricted error. This endpoint is gated by the closing_lines feature.

Phase 1 data window: Closing lines are captured in real-time as games go live. The Valkey store retains data for 30 days. Historical data beyond 30 days is not yet available.

How Closing Lines Are Captured

When a game transitions from pre-match to live, the server captures each book’s last pre-match odds as that event’s closing line. The closing price is devigged using the Power method (same as EV calculation) to produce a no-vig probability per selection.

CLV is then computed as:

CLV% = (pin_no_vig_prob - book_no_vig_prob) / book_no_vig_prob × 100

Where pin_no_vig_prob is Pinnacle’s devigged probability (the sharp reference) and book_no_vig_prob is the soft book’s devigged probability. A positive CLV% means the soft book closed at a price more favorable than the Pinnacle fair line.

Authentication

Requires API key. Sharp tier or higher required (closing_lines feature).

Query Parameters

ParameterTypeDefaultDescription
fromstring7 days agoStart date (YYYY-MM-DD or ISO 8601). Clamped to 30-day window.
tostringtodayEnd date (YYYY-MM-DD or ISO 8601).
group_bystringsportsbookAggregation dimension. One of: sportsbook, sport, league, market, day.
sportstringallFilter by sport(s), comma-separated (e.g. basketball,football).
leaguestringallFilter by league(s), comma-separated (e.g. nba,nfl).
sportsbookstringallFilter by sportsbook(s), comma-separated.

Date Window

Sharp tier allows up to 30 days of history (the current retention window for closing line data). Requesting dates outside this window is clamped silently to the earliest available date.

Example Requests

# CLV by sportsbook for the past 7 days curl -X GET "https://api.sharpapi.io/api/v1/historical/clv?from=2026-04-10&to=2026-04-17&group_by=sportsbook" \ -H "X-API-Key: YOUR_API_KEY" # CLV grouped by sport, NBA only curl -X GET "https://api.sharpapi.io/api/v1/historical/clv?league=nba&group_by=sport" \ -H "X-API-Key: YOUR_API_KEY" # CLV grouped by day for DraftKings curl -X GET "https://api.sharpapi.io/api/v1/historical/clv?sportsbook=draftkings&group_by=day" \ -H "X-API-Key: YOUR_API_KEY"

Response

Success (200)

{ "success": true, "data": { "group_by": "sportsbook", "groups": [ { "group_key": "draftkings", "samples": 312, "avg_clv_percent": 1.42, "avg_abs_clv_percent": 2.18, "distinct_books": 1, "distinct_sports": 4 }, { "group_key": "fanduel", "samples": 289, "avg_clv_percent": 0.87, "avg_abs_clv_percent": 1.95, "distinct_books": 1, "distinct_sports": 4 }, { "group_key": "betmgm", "samples": 201, "avg_clv_percent": -0.21, "avg_abs_clv_percent": 1.74, "distinct_books": 1, "distinct_sports": 3 } ], "date_range": { "from": "2026-04-10T00:00:00.000", "to": "2026-04-17T00:00:00.000" }, "total_events": 58, "comparable_events": 51, "sharp_reference": "pinnacle" }, "meta": { "source": "valkey:closing_line", "tier_window_days": 30, "phase": "1", "filters": { "sport": null, "league": null, "sportsbook": null, "group_by": "sportsbook" }, "updated_at": "2026-04-17T20:00:00.000000000Z" } }

Empty result (no closing line data yet):

{ "success": true, "data": { "group_by": "sportsbook", "groups": [], "date_range": { "from": "...", "to": "..." }, "total_events": 0, "comparable_events": 0, "sharp_reference": "pinnacle" }, "meta": { "source": "valkey:closing_line", "phase": "1", ... } }

An empty groups array is a valid response when no closing line data has been captured for the requested date range — not an error.

Error Responses

403 Tier Restricted

{ "error": { "code": "tier_restricted", "message": "The 'closing_lines' feature requires Sharp or higher.", "required_tier": "sharp", "docs": "https://docs.sharpapi.io/en/pricing" } }

400 Validation Error

{ "error": { "code": "validation_error", "message": "Invalid group_by. Must be one of: day, league, market, sport, sportsbook" } }

Response Fields

data object

FieldTypeDescription
group_bystringThe dimension used for aggregation
groupsarrayArray of group rows, sorted by samples descending
date_rangeobjectActual from/to used after tier clamping
total_eventsintegerTotal events found in the date range (before Pinnacle filter)
comparable_eventsintegerEvents with a Pinnacle closing line available for comparison
sharp_referencestringSharp book used as the fair-odds reference ("pinnacle")

Group row fields

FieldTypeDescription
group_keystringThe group identifier (sportsbook name, sport, league, market type, or YYYY-MM-DD date)
samplesintegerNumber of closing line comparisons in this group
avg_clv_percentnumberAverage CLV% across all samples. Positive = book closed looser than Pinnacle.
avg_abs_clv_percentnumberAverage absolute CLV% (direction-agnostic market efficiency measure)
distinct_booksintegerNumber of distinct books in this group
distinct_sportsintegerNumber of distinct sports in this group

meta object

FieldTypeDescription
sourcestringAlways "valkey:closing_line" (Phase 1 backend)
tier_window_daysintegerMaximum lookback days for your tier (Sharp = 30)
phasestring"1" — real-time capture from live transitions. ClickHouse backfill planned for Phase 2.
updated_atstringISO 8601 response timestamp

Interpreting CLV

CLV%Interpretation
> +2%Book consistently closed significantly looser than sharp lines — high value captured
+0.5% to +2%Book closed slightly loose — typical for recreational books
-0.5% to +0.5%Near-market close — efficient or mixed
< -0.5%Book tightened into close — may indicate steam chasing or sharp-side action

A positive average CLV on your bets is the strongest indicator that you’re betting into inefficient prices. Over a large sample, positive CLV strongly predicts positive ROI.

Last updated on