Skip to content

Commit d49b8d4

Browse files
Mlaz-codeclaude
andcommitted
docs(deeplinks): update batch endpoint docs to match current implementation
- Batch returns redirect paths (/api/v1/deeplink/{id}), not direct URLs - Accepts both odds IDs and opportunity hash_ids - Max batch size is 500 (was 50/100) - Unresolvable IDs return null instead of being omitted - Updated response schema, code examples, and OpenAPI spec - Updated supported sportsbooks table (21 of 28 supported) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dbb18e7 commit d49b8d4

2 files changed

Lines changed: 92 additions & 106 deletions

File tree

content/en/api-reference/deeplinks.mdx

Lines changed: 67 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import { Callout, Tabs } from 'nextra/components'
66

77
# Deep Links
88

9-
Generate sportsbook deep links from opportunity hash IDs. Deep links take users directly to the relevant bet slip or event page on a sportsbook's website, enabling one-click bet placement from your application.
9+
Generate sportsbook deep links from odds IDs or opportunity hash IDs. Deep links take users directly to the relevant event page on a sportsbook's website, enabling one-click bet placement from your application.
1010

1111
## Endpoints
1212

1313
| Method | Path | Description |
1414
|--------|------|-------------|
1515
| `GET` | `/api/v1/deeplinks` | Get deep links for a single opportunity |
16-
| `POST` | `/api/v1/deeplinks/batch` | Get deep links for up to 100 opportunities |
16+
| `POST` | `/api/v1/deeplinks/batch` | Get deep links for up to 500 IDs |
1717
| `GET` | `/api/v1/deeplink/{id}` | Redirect to a sportsbook (public, no auth) |
1818

1919
## Authentication
@@ -23,7 +23,7 @@ Requires API key for `GET /deeplinks` and `POST /deeplinks/batch`. Available to
2323
The redirect endpoint (`GET /deeplink/{id}`) is **public** and does not require authentication — the opaque ID prevents enumeration.
2424

2525
<Callout type="info">
26-
Deep links are generated from opportunity data. The `id` parameter is the `hash_id` field returned by the [+EV](/en/api-reference/opportunities-ev), [Arbitrage](/en/api-reference/opportunities-arbitrage), [Middles](/en/api-reference/opportunities-middles), and [Low Hold](/en/api-reference/opportunities-low-hold) endpoints.
26+
The `id` parameter accepts both **odds IDs** (from `/odds`, `/odds/best`) and **opportunity hash IDs** (from [+EV](/en/api-reference/opportunities-ev), [Arbitrage](/en/api-reference/opportunities-arbitrage), [Middles](/en/api-reference/opportunities-middles), and [Low Hold](/en/api-reference/opportunities-low-hold) endpoints). Odds IDs resolve to market-specific links; opportunity hash IDs resolve to event-level links.
2727
</Callout>
2828

2929
---
@@ -155,21 +155,21 @@ Cache-Control: public, s-maxage=10, max-age=5
155155
POST /api/v1/deeplinks/batch
156156
```
157157

158-
Returns deep links for multiple opportunities in a single request. IDs that are not found return `null`.
158+
Returns deep link redirect paths for multiple IDs in a single request. Accepts both **odds IDs** and **opportunity hash IDs**. Each ID in the request appears in the response — resolved IDs return a redirect path, unresolvable IDs return `null`.
159159

160160
### Request Body
161161

162162
```json
163163
{
164-
"ids": ["77b0749a1faae425", "abc1234567890def", "def9876543210abc"],
164+
"ids": ["17336125542407", "77b0749a1faae425", "abc1234567890def"],
165165
"state": "nj"
166166
}
167167
```
168168

169169
| Field | Type | Default | Description |
170170
|-------|------|---------|-------------|
171-
| `ids` | string[] | **required** | Array of opportunity hash IDs (1-100 items, each 16-character hex) |
172-
| `state` | string | `pa` | US state code for state-specific sportsbook URLs |
171+
| `ids` | string[] | **required** | Array of odds IDs or opportunity hash IDs (1–500 items) |
172+
| `state` | string | `pa` | US state code for state-specific sportsbook URLs (e.g., `nj`, `ny`, `il`) |
173173

174174
### Example Requests
175175

@@ -179,7 +179,7 @@ Returns deep links for multiple opportunities in a single request. IDs that are
179179
curl -X POST "https://api.sharpapi.io/api/v1/deeplinks/batch" \
180180
-H "X-API-Key: YOUR_API_KEY" \
181181
-H "Content-Type: application/json" \
182-
-d '{"ids": ["77b0749a1faae425", "abc1234567890def"], "state": "nj"}'
182+
-d '{"ids": ["17336125542407", "77b0749a1faae425"], "state": "nj"}'
183183
```
184184
</Tabs.Tab>
185185
<Tabs.Tab>
@@ -193,20 +193,18 @@ const response = await fetch(
193193
'Content-Type': 'application/json'
194194
},
195195
body: JSON.stringify({
196-
ids: ['77b0749a1faae425', 'abc1234567890def'],
196+
ids: ['17336125542407', '77b0749a1faae425'],
197197
state: 'nj'
198198
})
199199
}
200200
);
201-
const { data, meta } = await response.json();
202-
203-
console.log(`Found ${meta.found} of ${meta.count} opportunities`);
201+
const { data } = await response.json();
204202

205-
for (const [id, links] of Object.entries(data)) {
206-
if (links) {
207-
console.log(`${id}:`, Object.keys(links).join(', '));
203+
for (const [id, link] of Object.entries(data)) {
204+
if (link) {
205+
console.log(`${id}: https://api.sharpapi.io${link}`);
208206
} else {
209-
console.log(`${id}: not found`);
207+
console.log(`${id}: not available`);
210208
}
211209
}
212210
```
@@ -222,19 +220,17 @@ response = requests.post(
222220
'Content-Type': 'application/json'
223221
},
224222
json={
225-
'ids': ['77b0749a1faae425', 'abc1234567890def'],
223+
'ids': ['17336125542407', '77b0749a1faae425'],
226224
'state': 'nj'
227225
}
228226
)
229227
result = response.json()
230228

231-
print(f"Found {result['meta']['found']} of {result['meta']['count']} opportunities")
232-
233-
for opp_id, links in result['data'].items():
234-
if links:
235-
print(f"{opp_id}: {', '.join(links.keys())}")
229+
for id, link in result['data'].items():
230+
if link:
231+
print(f"{id}: https://api.sharpapi.io{link}")
236232
else:
237-
print(f"{opp_id}: not found")
233+
print(f"{id}: not available")
238234
```
239235
</Tabs.Tab>
240236
</Tabs>
@@ -243,35 +239,36 @@ for opp_id, links in result['data'].items():
243239

244240
#### Success (200)
245241

242+
The batch endpoint returns **redirect paths**, not direct sportsbook URLs. Prepend your base URL or use the path with the redirect endpoint to reach the sportsbook.
243+
246244
```json
247245
{
248-
"success": true,
249246
"data": {
250-
"77b0749a1faae425": {
251-
"draftkings": "https://sportsbook.draftkings.com/event/12345?outcomes=abc123",
252-
"fanduel": "https://nj.sportsbook.fanduel.com/addToBetslip?marketId=m456&selectionId=s789"
253-
},
254-
"abc1234567890def": null,
255-
"def9876543210abc": {
256-
"betmgm": "https://nj.betmgm.com/en/sports/events/67890?options=opt123&type=Single"
257-
}
247+
"17336125542407": "/api/v1/deeplink/17336125542407",
248+
"77b0749a1faae425": "/api/v1/deeplink/77b0749a1faae425",
249+
"abc1234567890def": null
258250
},
259-
"meta": {
260-
"updated_at": "2026-02-11T12:00:15.000Z",
261-
"count": 3,
262-
"found": 2
263-
}
251+
"updated_at": "2026-02-11T12:00:15.000Z"
264252
}
265253
```
266254

255+
| Value | Meaning |
256+
|-------|---------|
257+
| `"/api/v1/deeplink/{id}"` | Deeplink available — follow the redirect path to reach the sportsbook |
258+
| `null` | No deeplink available for this ID (unsupported sportsbook, expired odds, or invalid ID) |
259+
260+
<Callout type="info">
261+
To get the final sportsbook URL, either follow the redirect (`GET https://api.sharpapi.io/api/v1/deeplink/{id}`) or use the path directly in `<a href>` links — the browser will follow the 302 redirect automatically.
262+
</Callout>
263+
267264
#### Error Responses
268265

269266
***400 Missing IDs***
270267
```json
271268
{
272269
"error": {
273-
"code": "invalid_request",
274-
"message": "Missing or empty \"ids\" array in request body"
270+
"code": "bad_request",
271+
"message": "ids array required"
275272
}
276273
}
277274
```
@@ -280,33 +277,12 @@ for opp_id, links in result['data'].items():
280277
```json
281278
{
282279
"error": {
283-
"code": "invalid_request",
284-
"message": "Maximum batch size is 100 ids"
285-
}
286-
}
287-
```
288-
289-
***400 Invalid ID format***
290-
```json
291-
{
292-
"error": {
293-
"code": "invalid_request",
294-
"message": "Invalid id format. Expected 16-character hex strings. Invalid: xyz123"
280+
"code": "bad_request",
281+
"message": "Maximum 500 IDs per batch"
295282
}
296283
}
297284
```
298285

299-
### Response Headers
300-
301-
```
302-
X-RateLimit-Limit: 120
303-
X-RateLimit-Remaining: 119
304-
X-RateLimit-Reset: 1737853200
305-
X-Data-Delay: 0
306-
X-Request-Id: req_dlb_xyz789
307-
Cache-Control: public, s-maxage=10, max-age=5
308-
```
309-
310286
---
311287

312288
## Deep Link Redirect
@@ -395,31 +371,40 @@ If the `fallback` query parameter is provided and the ID is not found, the endpo
395371

396372
| Field | Type | Description |
397373
|-------|------|-------------|
398-
| `data` | object | Map of hash ID to deep links object (or `null` if not found) |
399-
| `meta.count` | number | Total number of IDs requested |
400-
| `meta.found` | number | Number of IDs with at least one deep link |
401-
| `meta.updated_at` | string | ISO 8601 timestamp |
374+
| `data` | object | Map of ID to redirect path (string) or `null` if unavailable |
375+
| `updated_at` | string | ISO 8601 timestamp of the odds data |
402376

403377
## Supported Sportsbooks
404378

405-
Deep links are generated for sportsbooks that support direct linking. State-specific books (marked with \*) use the `state` parameter to generate the correct regional URL.
379+
Deep links are available for 21 of 28 sportsbooks. State-specific books use the `state` parameter to generate the correct regional URL.
406380

407-
| Sportsbook | Link Type | State-Specific |
381+
| Sportsbook | Deep Link Support | State-Specific |
408382
|-----------|-----------|----------------|
409-
| DraftKings | Outcome/Event | No |
410-
| FanDuel | Outcome/Event | Yes* |
411-
| BetMGM | Outcome/Event | Yes* |
412-
| Caesars | Outcome/Event | Yes* |
413-
| BetRivers | Event | Yes* |
414-
| Pinnacle | Event | No |
415-
| bet365 | Event | No |
416-
| Betway | Event | No |
417-
| Fanatics | Event | No |
418-
| Novig | Event | No |
419-
420-
<Callout type="info">
421-
**Outcome** links open the sportsbook with the specific bet pre-selected in the bet slip. **Event** links open the event page where the user can find the market manually. Outcome links provide a better user experience when available.
422-
</Callout>
383+
| DraftKings | Yes | No |
384+
| FanDuel | Yes | No |
385+
| BetMGM | Yes | No |
386+
| Caesars | Yes | Yes |
387+
| Pinnacle | Yes | No |
388+
| Fanatics | Yes | No |
389+
| BetRivers | Yes | Yes |
390+
| Betway | Yes | No |
391+
| Bovada | Yes | No |
392+
| BetOnline | Yes | No |
393+
| Ladbrokes | Yes | No |
394+
| Stake | Yes | No |
395+
| Hard Rock | Yes | No |
396+
| Novig | Yes | No |
397+
| Kalshi | Yes | No |
398+
| BallyBet | Yes | No |
399+
| Unibet | Yes | No |
400+
| SkyBet | Yes | No |
401+
| theScore Bet | Yes | No |
402+
| Polymarket | Yes | No |
403+
| ProphetX | Yes | No |
404+
405+
The following sportsbooks do not currently support deep links. IDs for these books will return `null` in the batch response:
406+
407+
bet365, bet365 UK, Bet105, Bookmaker, Fliff, Rebet, SABA
423408

424409
## Related Endpoints
425410

public/openapi.json

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,7 +2746,7 @@
27462746
"post": {
27472747
"operationId": "batchDeepLinks",
27482748
"summary": "Batch deep link lookup",
2749-
"description": "Returns deep links for multiple opportunity IDs. Requires **Hobby** tier or higher.",
2749+
"description": "Returns redirect paths for multiple odds IDs or opportunity hash IDs. Resolved IDs return a redirect path, unresolvable IDs return null. Requires **Hobby** tier or higher.",
27502750
"tags": [
27512751
"Deep Links"
27522752
],
@@ -2763,10 +2763,9 @@
27632763
"ids": {
27642764
"type": "array",
27652765
"items": {
2766-
"type": "string",
2767-
"pattern": "^[a-f0-9]{16}$"
2766+
"type": "string"
27682767
},
2769-
"maxItems": 50
2768+
"maxItems": 500
27702769
},
27712770
"state": {
27722771
"type": "string",
@@ -2776,8 +2775,8 @@
27762775
},
27772776
"example": {
27782777
"ids": [
2779-
"a1b2c3d4e5f67890",
2780-
"b2c3d4e5f6789012"
2778+
"17336125542407",
2779+
"77b0749a1faae425"
27812780
],
27822781
"state": "nj"
27832782
}
@@ -2786,30 +2785,32 @@
27862785
},
27872786
"responses": {
27882787
"200": {
2789-
"description": "Deep links for each opportunity",
2788+
"description": "Redirect paths for each ID",
27902789
"content": {
27912790
"application/json": {
27922791
"schema": {
2793-
"allOf": [
2794-
{
2795-
"$ref": "#/components/schemas/SuccessEnvelope"
2796-
},
2797-
{
2792+
"type": "object",
2793+
"properties": {
2794+
"data": {
27982795
"type": "object",
2799-
"properties": {
2800-
"data": {
2801-
"type": "object",
2802-
"additionalProperties": {
2803-
"type": "object",
2804-
"additionalProperties": {
2805-
"type": "string",
2806-
"format": "uri"
2807-
}
2808-
}
2809-
}
2796+
"additionalProperties": {
2797+
"type": "string",
2798+
"nullable": true,
2799+
"description": "Redirect path (e.g. /api/v1/deeplink/{id}) or null if unavailable"
28102800
}
2801+
},
2802+
"updated_at": {
2803+
"type": "string",
2804+
"format": "date-time"
28112805
}
2812-
]
2806+
}
2807+
},
2808+
"example": {
2809+
"data": {
2810+
"17336125542407": "/api/v1/deeplink/17336125542407",
2811+
"77b0749a1faae425": null
2812+
},
2813+
"updated_at": "2026-02-11T12:00:15.000Z"
28132814
}
28142815
}
28152816
}

0 commit comments

Comments
 (0)