INDEPENDENT DEVELOPER REFERENCE
Build a DraftKings data Discord bot
Post recorded Pick6 changes to a Discord channel with an incoming webhook: polling, cursors, quota math and message wording.
Editorial review: · Not a live coverage report
What to build
The simplest useful bot is one scheduled script: read new Pick6 changes, format each one, and post it to a Discord incoming webhook. It needs no bot account, no gateway connection and no extra dependencies. It reports recorded data and should never tell readers what to enter.
Set up the two secrets
Create a webhook in your Discord channel settings under Integrations, and copy its URL. Treat that URL as a secret, since anyone holding it can post to the channel. Keep both values in the environment.
export DRAFTKINGS_API_KEY='dk_...'
export DISCORD_WEBHOOK_URL='https://discord.com/api/webhooks/...'
node discord-alerts.mjs --sport NHL --stat "Shots on Goal" --dry-run--dry-run prints messages rather than sending them, so you can check the wording and volume first. The alert bot uses only built-in Node.js modules, and it stores its cursor in a state file.
Poll with a saved cursor
Read /api/v1/pick6/history with after set to your stored cursor. Post the rows, then save pagination.next_after. Saving last means a crash can repeat a message but cannot lose one.
const url = new URL("/api/v1/pick6/history", BASE);
url.searchParams.set("sport", "NHL");
url.searchParams.set("stat", "Shots on Goal");
url.searchParams.set("after", String(state.after));
url.searchParams.set("limit", "25");
const page = await (await fetch(url, {
headers: { Authorization: `Bearer ${KEY}` },
signal: AbortSignal.timeout(20_000),
})).json();
for (const row of page.data) await postToDiscord(formatChange(row));
state.after = page.pagination.next_after;
await saveState(state);Start after from 0 only if you want the backlog posted. Otherwise page to the latest cursor once with posting disabled, then begin. Without this, your first run could post every retained change.
Do the quota math first
Decide your schedule from your plan's allowance, not from how fast you would like updates. Pick6 worker targets are five minutes, so polling more often returns no newer data.
| Plan | Requests per month | Even spacing if this job is your only traffic |
|---|---|---|
| Free | 500 | One request every 86 minutes |
| Developer | 10,000 | One request every 4.3 minutes |
| Production | 50,000 | One request every 0.9 minutes |
A 5-minute poll is about 8,640 requests in a 30-day month. That uses most of Developer and is far beyond Free, where one poll every few hours is more realistic. Limit each run to a few pages, and raise the interval when other jobs share the key's account. On Developer and above, the stream is an alternative for a long-running process, though each connection also costs a request.
Respect Discord's limits
Discord rate-limits webhooks and replies with 429 and a retry delay. Send messages one at a time, honor Retry-After, and combine many changes into one message rather than a post for each. Cap messages per run, and log how many changes you held back.
async function postToDiscord(content) {
for (let attempt = 0; attempt < 3; attempt++) {
const response = await fetch(process.env.DISCORD_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content, allowed_mentions: { parse: [] } }),
signal: AbortSignal.timeout(10_000),
});
if (response.status !== 429) return response.ok;
const wait = Number(response.headers.get("retry-after") ?? 2);
await new Promise((r) => setTimeout(r, wait * 1000));
}
return false;
}allowed_mentions with an empty parse list stops source text from pinging the channel.
Write factual messages
State what was recorded and when. Do not recommend a side, say a line is good value, predict a result or use betting call-outs. This service does not place, recommend or settle entries or bets, and your bot's wording should not suggest otherwise.
Recorded change, NHL Shots on Goal
EXAMPLE PLAYER: target 1.5 -> 2.5
More: 1x -> 1.3x
Observed 2026-11-03 18:24 UTC. Standings multiplier, not odds. Not an offer.- Include
observed_atin every message. - Skip or mark rows with
is_paused: true. - Describe multipliers as standings multipliers, not odds.
- Say that the feed is selected captures, not the whole board.
Public servers and redistribution
Posting to a private channel for yourself is different from running a public or paid server. Technical access is not a redistribution license, so posting data to a large or commercial audience is your rights question to review first. If you do run a public bot, show the disclaimer that it is independent, not affiliated with or endorsed by DraftKings, and contains no wagering advice. Local gambling and advertising rules may apply to you as well.
Try it
Run a dry run before connecting a channel: node discord-alerts.mjs --sport NHL --stat "Shots on Goal" --dry-run.
Endpoint docs
Working assets
Check the recorded data
Questions
Do I need a Discord bot account?
No. A channel incoming webhook is enough for posting messages. You need a bot account only if people must run commands that trigger lookups.
How often should my bot poll?
Pick6 worker targets are five minutes, so polling more often adds no newer data. On Free, poll far less often, because 500 monthly requests is roughly one call every 86 minutes.
Can the bot alert on sportsbook lines?
It can poll /api/v1/history on the same pattern with offset paging, ordered by seq. Sportsbook data is mainlines only, and there is no push delivery for it.
Can I run this bot on a public server?
Check your rights first. An API key gives technical access and is not a redistribution license. State clearly that the bot is independent and offers no wagering advice.
Related resources
Follow recorded Pick6 changes with a resumable cursor, read sportsbook history by sequence, and compute moves without overclaiming.
DraftKings API webhooks and change streamsSigned Pick6 change webhooks on Production and a resumable stream on Developer: signature checks, retries, replay and limits.
DraftKings API errors and rate limitsWhat each status means, what counts against your plan, when limits reset, and how to write retry logic that does not waste quota.
Can I redistribute data from this API?An API key gives technical access, not a redistribution license. Rows carry rights notes, and you must resolve rights for anything you publish.
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.