Skip to Content
API ReferenceOverview

API Reference Overview

Complete reference for the SharpAPI v1 REST API. All endpoints return JSON and follow consistent conventions for authentication, filtering, pagination, and error handling.

Base URL

https://api.sharpapi.io/api/v1

Always use api.sharpapi.io as the base URL, not sharpapi.io.

OpenAPI Specification

The full OpenAPI 3.1 spec is available for import into tools like Postman, Insomnia, or code generators:

This spec covers all endpoints, request/response schemas, and authentication requirements.

Request Format

  • All requests use HTTPS
  • Authentication via X-API-Key header, Authorization: Bearer header, or api_key query param
  • Request bodies (where applicable) use JSON with Content-Type: application/json
  • All field names are snake_case

Endpoint Summary

SharpAPI exposes 35 routes across 7 namespaces plus reference and health endpoints.

Odds

MethodPathAuthMin Tier
GET/api/v1/oddsYesFree
GET/api/v1/odds/deltaYesFree
GET/api/v1/odds/bestYesFree
GET/api/v1/odds/comparisonYesFree
POST/api/v1/odds/batchYesFree

Events

MethodPathAuthMin Tier
GET/api/v1/eventsYesFree
GET/api/v1/events/:eventIdYesFree
GET/api/v1/events/:eventId/oddsYesFree
GET/api/v1/events/:eventId/marketsYesFree

Opportunities

MethodPathAuthMin Tier
GET/api/v1/opportunities/evYesPro
GET/api/v1/opportunities/arbitrageYesHobby
GET/api/v1/opportunities/middlesYesPro

Splits

MethodPathAuthMin Tier
GET/api/v1/splitsYesPro
GET/api/v1/splits/historyYesPro

Streaming

MethodPathAuthMin Tier
GET/api/v1/streamYesAdd-on

Account

MethodPathAuthMin Tier
GET/api/v1/accountYesFree
GET/api/v1/account/usageYesFree
GET/api/v1/account/keysYesFree
POST/api/v1/account/keysYesFree
DELETE/api/v1/account/keys/:keyIdYesFree
POST/api/v1/account/keys/:keyId/rotateYesFree

Reference Data (Public)

MethodPathAuthMin Tier
GET/api/v1/sportsNo-
GET/api/v1/leaguesNo-
GET/api/v1/sportsbooksNo-
GET/api/v1/marketsNo-
GET/api/v1/teamsNo-

Enterprise

MethodPathAuthMin Tier
GET/api/v1/futuresYesEnterprise
GET/api/v1/futures/oddsYesEnterprise

Health

MethodPathAuthMin Tier
GET/api/v1/healthNo-

Response Format

Success Envelope

All successful responses wrap data in a consistent envelope:

{ "success": true, "data": [ { "id": "draftkings_33483153_moneyline_PHO", "sportsbook": "draftkings", "sport": "basketball", "home_team": "PHI 76ers", "away_team": "PHO Suns", "market_type": "moneyline", "selection": "PHO Suns", "odds_american": -150, "odds_decimal": 1.667, "odds_probability": 0.60, "is_live": false } ], "pagination": { "limit": 50, "offset": 0, "has_more": true, "next_offset": 50, "next_cursor": "eyJlIjoiMzM0ODMxNTMiLCJiIjoiZHJhZnRraW5ncyIsIm0iOiJtb25leWxpbmUiLCJpIjoiZHJhZnRraW5nc18zMzQ4MzE1M19tb25leWxpbmVfUEhJIn0" }, "meta": { "count": 1, "total": 3095, "pagination": { "limit": 50, "offset": 0, "has_more": true, "next_offset": 50, "next_cursor": "eyJlIjoiMzM0ODMxNTMiLCJiIjoiZHJhZnRraW5ncyIsIm0iOiJtb25leWxpbmUiLCJpIjoiZHJhZnRraW5nc18zMzQ4MzE1M19tb25leWxpbmVfUEhJIn0" }, "updated_at": "2026-01-26T02:10:37.846Z", "filters": { "sportsbook": "draftkings", "league": "nba" } } }
FieldDescription
successtrue for all successful responses
dataArray of results (or single object for detail endpoints)
pagination.limitMaximum items per page (default: 50, max: 200)
pagination.offsetCurrent offset into results
pagination.has_moreWhether more results exist beyond this page
pagination.next_offsetOffset value to use for the next page (legacy — use next_cursor for live-data endpoints)
pagination.next_cursorOpaque cursor for the next page. Pass as ?cursor= — stable against live data changes. Recommended for multi-page scans.
meta.countNumber of items returned in this response
meta.totalTotal matching items across all pages
meta.paginationSame as top-level pagination (included for backward compatibility)
meta.updated_atISO 8601 timestamp of when the data was last refreshed
meta.filtersEcho of the filters applied to this request

Single Resource Response

{ "success": true, "data": { "id": "evt_abc123", "sport": "nba", "home_team": "PHI 76ers", "away_team": "PHO Suns", "start_time": "2026-01-26T19:00:00Z" }, "meta": { "updated_at": "2026-01-26T02:10:37.846Z" } }

Error Envelope

All errors follow a consistent format:

{ "error": { "code": "rate_limited", "message": "Rate limit exceeded. Upgrade your plan or wait 45 seconds.", "docs": "https://docs.sharpapi.io/en/authentication#rate-limits" } }
FieldDescription
error.codeMachine-readable error code
error.messageHuman-readable description
error.docsLink to relevant documentation (optional — included on auth, tier, rate limit, and streaming errors)
error.correct_endpointThe correct endpoint to use (optional — included on unknown_endpoint errors when the API recognizes the path as a known wrong route)
error.retry_afterSeconds until retry is allowed (optional — included on rate_limited errors)

Standard Response Headers

Every API response includes these headers:

HeaderExampleDescription
X-RateLimit-Limit300Maximum requests per minute for your tier
X-RateLimit-Remaining299Requests remaining in the current window
X-RateLimit-Reset1705804800Unix timestamp when the rate limit resets
X-Data-Delay0Data delay in seconds (60 for Free, 0 for paid tiers)
X-Request-Idreq_a1b2c3d4Unique request identifier for debugging and support

Include the X-Request-Id value when contacting support about a specific request.

Tier Comparison

FeatureFreeHobbyProSharpEnterprise
Sportsbooks2 (DK, FD)515All 32All 32
Data Delay60s0s0s0s0s
Requests/min121203001,000Custom
PinnacleNoNoYesYesYes
EV / Arb / MiddlesNoNoYesYesYes
StreamingNoAdd-onAdd-onAdd-onIncluded
Batch max events10105050100

Streaming requires the WebSocket add-on ($99/mo) on paid tiers. Enterprise includes streaming at no extra cost.

Filtering

All list endpoints support filtering via query parameters. Filters use singular parameter names and accept comma-separated values for multi-select.

Filter Parameters

ParameterTypeExampleDescription
sportsbookstringdraftkings,fanduelFilter by one or more sportsbooks
sportstringbasketball,footballFilter by sport
leaguestringnba,nflFilter by league
marketstringmoneyline,spreadFilter by market type
eventstringevt_abc123Filter by event ID
livebooleantrueOnly live/in-progress events
sortstring-odds_americanSort field with optional - prefix for descending
fieldsstringid,sportsbook,odds_americanComma-separated fields to include in response
min_oddsnumber-110Minimum American odds filter
max_oddsnumber200Maximum American odds filter
group_bystringeventGroup results by field
limitnumber25Results per page (default: 50, max: 200)
offsetnumber50Pagination offset. May produce duplicate rows on live endpoints when data changes between requests.
cursorstringOpaque cursor from next_cursor. Recommended for multi-page scans over live data — eliminates offset drift.

Examples

# Multiple sportsbooks (comma-separated) curl "https://api.sharpapi.io/api/v1/odds?sportsbook=draftkings,fanduel" \ -H "X-API-Key: YOUR_KEY" # Combine filters curl "https://api.sharpapi.io/api/v1/odds?league=nba,nhl&sportsbook=pinnacle&live=true" \ -H "X-API-Key: YOUR_KEY" # Paginate through results curl "https://api.sharpapi.io/api/v1/odds?limit=25&offset=50" \ -H "X-API-Key: YOUR_KEY"

Parameter names are always singular (sportsbook, not sportsbooks). Use commas to pass multiple values: sportsbook=draftkings,fanduel.

Odds Formats

All odds are returned as flat fields on each odds object:

{ "odds_american": -110, "odds_decimal": 1.909, "odds_probability": 0.5238 }
FieldExampleDescription
odds_american-110, +150Standard US format
odds_decimal1.909, 2.50Multiplier format
odds_probability0.5238Implied probability (0 to 1)

Error Codes

The canonical list of error codes emitted by the API. The string in error.code is the stable contract — check it rather than the prose message.

HTTP error codes

Emitted in REST responses.

CodeHTTP StatusDescription
missing_api_key401No API key supplied via X-API-Key, ?api_key=, or Authorization: Bearer
invalid_api_key401API key was supplied but is not recognized
expired_api_key401API key has expired — generate a new one in the dashboard
disabled_api_key401API key is disabled, usually because the subscription lapsed
unauthorized401Bearer-token auth failed on admin or /api/v1/monitoring/* endpoints (distinct from invalid_api_key)
invalid_token401Clerk session token failed verification (dashboard-only endpoints)
tier_restricted403Endpoint or feature is not available on your tier — response includes tier and required_tier
not_found404Resource not found
method_not_allowed405HTTP method is not supported on this route
gone410Event has ended or expired — use /api/v1/events for current events
unknown_endpoint410Wrong API path — response includes correct_endpoint with the right route (e.g. /api/v1/arbitrage/api/v1/opportunities/arbitrage)
validation_error400Request body or query parameters failed validation
offset_too_large400offset exceeds the per-endpoint maximum (currently 500 on /odds and /odds/delta). Switch to cursor-based pagination or advance since
rate_limited429Per-minute request rate limit exceeded — response includes retry_after
concurrent_request_cap429Too many in-flight requests for your tier — reduce parallelism or upgrade
too_many_streams429Maximum concurrent SSE or WebSocket streams exceeded for this API key
backpressureEmitted as an SSE event: error (not an HTTP status) when the client cannot keep up; server then closes the stream
upstream_error502Temporary issue reaching an upstream sportsbook or auth provider
service_unavailable503A required service (e.g. key management) is not configured or is offline
not_ready503A backing store the endpoint depends on (e.g. ClickHouse, closing-line capture) is not yet ready to serve the request. Retry with backoff
internal_error500Unexpected server error — retry with backoff and contact support with X-Request-Id if it persists

bad_request and invalid_request are deprecated — both were collapsed into validation_error. Clients that match on the old strings should add validation_error to their error map.

WebSocket frame error codes

Emitted only inside {"type": "error", "code": "..."} frames on an open WebSocket connection. They describe client-protocol mistakes and do not correspond to an HTTP status.

CodeMeaning
invalid_messageFrame could not be parsed as JSON or did not match the expected shape
unknown_message_typetype field is not one of the documented values (auth, subscribe, filter, refresh_token, ping)
missing_tokenauth or refresh_token frame did not include a token field
missing_channelssubscribe frame did not include a non-empty channels array
not_authenticatedFrame requires an authenticated session (sent subscribe, filter, or refresh_token before auth)
already_authenticatedClient sent a second auth frame after the first one succeeded
Last updated on