INDEPENDENT DEVELOPER REFERENCE
DraftKings API webhooks and change streams
Signed Pick6 change webhooks on Production and a resumable stream on Developer: signature checks, retries, replay and limits.
Editorial review: · Not a live coverage report
What push delivery covers
Pick6 changes: Developer and Production include the resumable stream, and Production also includes signed webhooks. Native sportsbook scopes: paid plans can use a server-side WebSocket at /api/v1/sportsbook/ws. ESPN-attributed sportsbook rows and DFS rows have no push delivery. Delivery follows the changes we capture, so it inherits the partial category coverage of Pick6. It is not a complete or low-latency feed of the source.
| Option | Plans | Best for |
|---|---|---|
Poll /api/v1/pick6/history | All plans | Scheduled jobs and simple scripts |
/api/v1/stream | Developer, Production | A long-running worker that can reconnect |
| Signed webhooks | Production | A public HTTPS endpoint that should receive events |
Create a receiver
Manage hooks in the dashboard. Add your URL, copy its signing secret, and watch delivery attempts there. The secret is shown once and is not returned by later reads.
- Destinations must be public HTTPS hostnames on port 443 that resolve to public IPv4 addresses.
- Redirects fail, so register the final URL.
- An account can have five active hooks. Another returns 409.
/api/account/webhooksuses your signed-in dashboard session, not an API key.
The event you receive
Each POST body is JSON with an id, a type of pick6.change and the change under change. The change holds the sequence number, the new row and the previous row.
POST /your/path HTTP/1.1
content-type: application/json
x-dk-event-id: pick6:2262
x-dk-signature: t=1793750000,v1=<hex>
{"id":"pick6:2262","type":"pick6.change","change":{"seq":"2262", ...}}Do not rely on delivery order. Use the sequence number in the event ID, and tolerate an unfamiliar field.
Verify every callback
x-dk-signature has the form t=<unix seconds>,v1=<hex>. The value is HMAC-SHA256 of the timestamp, a dot and the exact raw body, keyed with your signing secret. Verify before you parse, using the raw bytes and a constant-time comparison.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(header, rawBody, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(
String(header).split(",").map((part) => part.split("=", 2)),
);
const timestamp = Number(parts.t);
if (!Number.isInteger(timestamp) || !/^[a-f0-9]{64}$/.test(parts.v1 ?? ""))
return false;
if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest();
return timingSafeEqual(expected, Buffer.from(parts.v1, "hex"));
}The webhook receiver is a full server built on node:http. Run it with DRAFTKINGS_WEBHOOK_SECRET and PORT set: node webhook-receiver.mjs.
Retries and duplicates
Delivery is at-least-once, so the same event can arrive twice. Store x-dk-event-id and skip one you have seen. Retries keep the same event ID and body. Respond with a 2xx quickly, and do slow work after that.
| Your response | What happens |
|---|---|
| 2xx | Delivered. |
| 403 | That hook is disabled. Other hooks keep running. |
| 429 | That hook cools down for a bounded time. A Retry-After header is honored, up to one hour. |
| Other failure or timeout | Retries with exponential backoff, up to a terminal attempt, capped at one hour between tries. |
| 3xx | Treated as a failure. Redirects are not followed. |
Replay and retention
From the dashboard you can requeue at most 100 retained changes for an active hook by giving a cursor range. Replay does not erase attempt history. Retention is finite: no unlimited replay window is promised, and storage pressure can pause writes and dispatch while preserving pending evidence.
Keep your own copy of anything you need long term. Your receiver's database is your archive, not ours.
The stream on Developer plans
The stream delivers the same Pick6 changes over Server-Sent Events. Start with a snapshot, save its snapshot_cursor, then connect with that cursor. Each connection lasts at most 55 seconds and costs one request, as does the snapshot.
curl --fail-with-body "https://draftkingsapi.com/api/v1/stream/snapshot?sport=NFL" \
-H "Authorization: Bearer $DRAFTKINGS_API_KEY"
curl -N "https://draftkingsapi.com/api/v1/stream" \
-H "Authorization: Bearer $DRAFTKINGS_API_KEY" \
-H "Last-Event-ID: YOUR_SNAPSHOT_CURSOR"- Persist the last event ID and reconnect with it. Continuous streaming costs about 60 connections an hour, so plan the allowance. See the freshness guide for cheaper polling.
pick6.changeevents carry data.checkpointevents advance the cursor when nothing changed.- The stream is not sport-filtered. Apply your snapshot's sport filter to incoming changes.
- A snapshot is bounded to 10,000 rows or 2 MB, and a larger one returns 413. Add
sport. - A purged cursor returns 410, which needs a new snapshot. A cursor ahead of retained data returns 409. Without a cursor, send
start=lateston purpose; otherwise the stream returns 428.
The stream client handles this with a state file: node stream-client.mjs --sport NFL.
Try it
Test your signature code locally before you register a URL: run node webhook-receiver.mjs and post a body signed with your test secret.
Endpoint docs
Working assets
Check the recorded data
Questions
Does the API have webhooks for sportsbook odds?
No. Webhooks and the stream cover Pick6 changes only. For sportsbook and DFS rows, poll the REST endpoints on a schedule.
Which plan includes webhooks?
Production includes signed webhooks. Developer and Production include the Pick6 change stream. Free can poll Pick6 history.
Can a webhook be delivered twice?
Yes. Delivery is at-least-once. Deduplicate on the x-dk-event-id header, which stays the same across retries.
Do webhooks count against my request allowance?
Webhook deliveries are not API calls you make, and the metering code applies to authenticated API requests. Stream connections and snapshots each count as one request.
Related resources
Follow recorded Pick6 changes with a resumable cursor, read sportsbook history by sequence, and compute moves without overclaiming.
Does the API support webhooks?Yes, for Pick6 changes on the Production plan. Callbacks are signed and delivered at least once. Sportsbook and DFS have no webhooks.
Which plans include the Pick6 change stream?Developer and Production on the monthly contract. Each connection lasts up to 55 seconds, costs one request and resumes from a saved ID.
pricing DraftKings Pick6 observations APIInspect selected multi-sport Pick6 market rows, explicit selections, standings multipliers and actual changed observations.
Independent service operated by DD Inc., not affiliated with or endorsed by DraftKings. Technical access is not a redistribution license. No wagering: this service does not place, recommend or settle entries or bets. Check sources and status for actual capture context.