Skip to content

Commit 0c562fe

Browse files
Mlaz-codeclaude
andauthored
docs(odds): document offset cap, removed_truncated, since_clamped (#192)
Companion to sharp-api-go PR #44. Documents the three new safety bounds on /odds and /odds/delta: - offset > 500 now returns 400 offset_too_large on both endpoints. /odds clients are directed to cursor= for deeper pagination; /odds/delta clients are directed to advance `since` to the previous response's `updated_at`. - /odds/delta responses may include removed_truncated: true when the `removed` array hits the 1000-entry cap, and since_clamped: true when the client's `since` was older than the 10-minute removal retention window. Both flags are optional — healthy polling clients (rolling `since` forward each call) never see them, which is called out in a new Polling note on the delta reference page. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 783a4df commit 0c562fe

2 files changed

Lines changed: 39 additions & 5 deletions

File tree

content/en/api-reference/odds-delta.mdx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,17 @@ Use the `server_time` from each response as the `since` value for your next requ
3636
| `min_odds` | number | - | Minimum American odds filter (e.g., `-110`) |
3737
| `max_odds` | number | - | Maximum American odds filter (e.g., `+200`) |
3838
| `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. |
39-
| `limit` | integer | 50 | Max results per page (max 200) |
40-
| `offset` | integer | 0 | Pagination offset |
39+
| `limit` | integer | 50 | Max results per page (max 500) |
40+
| `offset` | integer | 0 | Pagination offset. **Must be ≤ 500.** For older changes, advance `since` to the previous response's `server_time` rather than using offset. |
4141

4242
<Callout type="warning">
4343
The `since` parameter is **required**. Omitting it returns a `400 validation_error` error.
4444
</Callout>
4545

46+
<Callout type="info">
47+
**`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.
48+
</Callout>
49+
4650
## Example Requests
4751

4852
<Tabs items={['cURL', 'JavaScript', 'Python']}>
@@ -171,6 +175,17 @@ X-Request-Id: req_delta_abc123
171175
}
172176
```
173177

178+
***400 Offset too large***
179+
```json
180+
{
181+
"error": {
182+
"code": "offset_too_large",
183+
"message": "offset must be <= 500; advance `since` to the previous response's `updated_at` to retrieve older changes",
184+
"max_offset": 500
185+
}
186+
}
187+
```
188+
174189
***401 Unauthorized***
175190
```json
176191
{
@@ -193,6 +208,15 @@ The `meta` object includes two additional fields:
193208
| `meta.server_time` | string | ISO 8601 server timestamp. Use as the `since` value for your next request |
194209
| `meta.books_changed` | array | List of sportsbook IDs that had updates in this delta |
195210

211+
### Truncation and Clamping Flags
212+
213+
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.
214+
215+
| Field | Type | Description |
216+
|-------|------|-------------|
217+
| `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. |
218+
| `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. |
219+
196220
## Polling Pattern
197221

198222
The recommended polling pattern uses `server_time` to chain requests:

content/en/api-reference/odds.mdx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ The sportsbooks returned in your results depend on your subscription tier. Free
3737
| `group_by` | string || Group results by field (e.g., `event`) |
3838
| `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. Only affects books with state-dependent URLs (BetMGM, Caesars, BetRivers). |
3939
| `limit` | integer | 50 | Max results per page (max 200) |
40-
| `offset` | integer | 0 | Pagination offset. May produce duplicate rows when live data updates between requests — use `cursor` for multi-page scans. |
41-
| `cursor` | string || Opaque cursor from `next_cursor` in a previous response. **Recommended for multi-page scans** — stable against live data changes. Takes precedence over `offset` when both are provided. |
40+
| `offset` | integer | 0 | Pagination offset. **Must be ≤ 500.** Values above 500 return `400 offset_too_large` — use `cursor` for deeper pagination. May produce duplicate rows when live data updates between requests. |
41+
| `cursor` | string || Opaque cursor from `next_cursor` in a previous response. **Required for deep pagination (past offset 500)** and recommended for any multi-page scan — stable against live data changes. Takes precedence over `offset` when both are provided. |
4242

4343
<Callout type="info">
4444
Use comma-separated values to filter by multiple sportsbooks: `sportsbook=draftkings,fanduel,betmgm`
@@ -159,7 +159,17 @@ curl "https://api.sharpapi.io/api/v1/odds?league=nfl&limit=200&cursor=eyJlIjoiMz
159159

160160
Cursors are opaque — do not parse or construct them. They encode the sort position of the last item on the current page and are only valid for the same filter parameters.
161161

162-
`?offset=N` continues to work and is appropriate for single-page requests or direct position access. It is not recommended for iterating through live data.
162+
`?offset=N` continues to work for shallow pagination (up to offset 500) and is appropriate for single-page requests or direct position access. Beyond 500, the API returns `400 offset_too_large` — the server would otherwise have to sort the full filtered result set on every page, which is much cheaper to avoid than to optimize per-request. Use `cursor` for anything deeper.
163+
164+
```json
165+
{
166+
"error": {
167+
"code": "offset_too_large",
168+
"message": "offset must be <= 500; use `cursor=` from the previous response for deeper pagination",
169+
"max_offset": 500
170+
}
171+
}
172+
```
163173

164174
## Response
165175

0 commit comments

Comments
 (0)