Odds Delta
Get only the odds that have changed since a given timestamp. This endpoint returns the same odds format as /odds but filtered to items updated after your since value, making it ideal for polling clients that want incremental updates without re-fetching the full snapshot.
GET /api/v1/odds/deltaAuthentication
Requires API key. Available to all tiers.
Use the server_time from each response as the since value for your next request. This ensures you never miss updates and never receive duplicates.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
since | string | required | ISO 8601 timestamp. Only return odds updated after this time (e.g., 2026-02-11T12:00:00Z) |
sportsbook | string | all | Comma-separated sportsbook IDs (e.g., draftkings,fanduel) |
sport | string | all | Filter by sport (e.g., basketball, football) |
league | string | all | Filter by league (e.g., nba, nfl) |
market | string | all | Filter by market type (e.g., moneyline, spread, total). Supports category aliases — see Odds: Market Category Aliases. Also accepted as market_type=. |
event_id | string | - | Filter by event ID |
is_live | boolean | false | Return only live/in-play events |
state | string | — | US state code for sportsbook deep links (e.g., nj, ny, il). When set, deep_link URLs include ?state=XX so the redirect targets the correct state-specific sportsbook domain. |
limit | integer | 50 | Max results per page (max 500) |
offset | integer | 0 | Pagination offset. Must be ≤ 500. For older changes, advance since to the previous response’s server_time rather than using offset. |
The since parameter is required. Omitting it returns a 400 validation_error error.
since has a 10-minute retention window for removals. Odds removals older than 10 minutes are pruned from memory. If you send a since older than that, the data array still honors your timestamp, but the removed list can only contain odds removed within the last 10 minutes — and since_clamped: true will be set on the response. Advance since at the cadence in the Polling Pattern section below to avoid this.
Example Requests
cURL
# Get all odds changes in the last 30 seconds
curl -X GET "https://api.sharpapi.io/api/v1/odds/delta?since=2026-02-11T12:00:00Z&league=nba" \
-H "X-API-Key: YOUR_API_KEY"Response
Success (200)
{
"data": [
{
"id": "199954867251468",
"sportsbook": "draftkings",
"event_id": "nba_celtics_lakers_2026-02-08_b3",
"sport": "basketball",
"league": "nba",
"home_team": "Los Angeles Lakers",
"away_team": "Boston Celtics",
"market_type": "moneyline",
"selection": "Boston Celtics",
"selection_type": "away",
"odds_american": -150,
"odds_decimal": 1.667,
"odds_probability": 0.60,
"line": null,
"event_start_time": "2026-02-08T19:00:00Z",
"timestamp": "2026-02-08T12:00:15.125Z",
"is_live": false,
"is_main_line": true
}
],
"removed": [
{ "id": "102044417046441", "sportsbook": "pinnacle", "removed_at": "2026-02-08T12:00:07Z" }
],
"pagination": {
"limit": 50,
"offset": 0,
"count": 1,
"total": 1,
"has_more": false,
"next_offset": null
},
"updated_at": "2026-02-08T12:00:20Z",
"meta": {
"server_time": "2026-02-08T12:00:20Z"
}
}Each data row carries the full odds object documented on Odds Snapshot (trimmed here for brevity). Apply data rows as upserts and removed rows as deletions to your local copy.
Response Headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1737853200
X-Data-Delay: 0
X-Request-Id: 1782526326424224-82519Error Responses
400 Missing since parameter
{
"error": {
"code": "validation_error",
"message": "since query parameter is required (ISO 8601 timestamp)"
}
}400 Offset too large
{
"error": {
"code": "offset_too_large",
"message": "offset must be <= 500; advance `since` to the previous response's `updated_at` to retrieve older changes",
"max_offset": 500
}
}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"
}
}Delta Response Schema
The data array contains the same odds objects as the /odds endpoint. Only odds updated after the since timestamp are included.
The removed Array
The top-level removed array names every odds row that left the board since your since timestamp — markets a book took down (suspension, a handicap/total threshold retired by a line move, event settled). Delete these ids from your local state; this is the explicit close signal, so you never need to diff snapshots yourself. Present only when at least one removal matched your filters. See Market Lifecycle for the full close/suspend signal map.
| Field | Type | Description |
|---|---|---|
removed[].id | string | The odds ID that is no longer on the board |
removed[].sportsbook | string | The book that removed it |
removed[].removed_at | string | ISO 8601 timestamp of when SharpAPI observed the removal |
On top of the standard {data, pagination, updated_at} shape, the delta envelope adds:
| Field | Type | Description |
|---|---|---|
removed | array | Odds removed since since, each {id, sportsbook, removed_at}. Apply as deletions to your local copy. |
meta.server_time | string | ISO 8601 server timestamp. Use as the since value for your next request. |
overflow | boolean | Optional. Present and true when the changed-data set hit the server cap — narrow your filters or poll more often. |
Truncation and Clamping Flags
Two optional top-level boolean flags appear only when the server had to apply a safety limit to the response. Well-behaved clients polling at the recommended cadence never see them.
| Field | Type | Description |
|---|---|---|
removed_truncated | boolean | Present and true when the removed array hit the 1000-entry server cap. There are more removed odds the server didn’t include. Usually means your since is too old or your filters are too broad — narrow the window or filter set and re-poll. |
since_clamped | boolean | Present and true when since was older than the server’s 10-minute removal retention. The data array still honors your original since, but removed is restricted to the last 10 minutes of removals. Advance since to meta.server_time each call to avoid this. |
Polling Pattern
The recommended polling pattern uses server_time to chain requests:
- Make an initial request with
sinceset to a recent timestamp - Read
meta.server_timefrom the response - Use that
server_timeas thesincevalue in your next request - Repeat on your desired interval (e.g., every 5 seconds)
This ensures:
- No gaps -
server_timeis the server’s clock, so you won’t miss updates due to clock drift - No duplicates - each delta window is non-overlapping
- Minimal payload - only changed odds are returned
If no odds have changed since your since timestamp, the response will have an empty data array and count: 0. This is normal and expected during quiet periods.
Related Endpoints
- Odds Snapshot - Get the full current odds snapshot
- SSE Stream - Real-time push updates via Server-Sent Events
- WebSocket Stream - Real-time push updates via WebSocket