draftkings apiDashboard ↗

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.

OptionPlansBest for
Poll /api/v1/pick6/historyAll plansScheduled jobs and simple scripts
/api/v1/streamDeveloper, ProductionA long-running worker that can reconnect
Signed webhooksProductionA 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/webhooks uses 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.

Illustrative delivery
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.

Signature check in Node.js
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 responseWhat happens
2xxDelivered.
403That hook is disabled. Other hooks keep running.
429That hook cools down for a bounded time. A Retry-After header is honored, up to one hour.
Other failure or timeoutRetries with exponential backoff, up to a terminal attempt, capped at one hour between tries.
3xxTreated 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.

Snapshot, then stream
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.change events carry data. checkpoint events 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=latest on 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.

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

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.