API

Everything your bot needs: post stats, check votes and receive vote webhooks. Generate a token in your bot’s API & webhooks page.

Authentication

Send the token in the Authorization header, raw or as Bearer. Limit: 60 requests per minute per token.

Authorization: nk_your_token

Base URL: https://nookie.sbs/api/v1

POST /bots/stats

Call it every 30 minutes or so. The Top.gg format (server_count, shard_count) also works, so migrating is just a URL change. Verified bots do not need this: Nookie reads their server count from Discord every 6 hours, and that number wins over the one you send.

curl -X POST https://nookie.sbs/api/v1/bots/stats \
  -H "Authorization: nk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"serverCount": 1520, "shardCount": 2}'

GET /bots/:id/check?userId=:userId

True if the user voted in the last 12 hours. Use it to unlock vote rewards.

{ "voted": true, "votedAt": "2026-09-26T18:00:00Z", "nextVoteAt": "2026-09-27T06:00:00Z" }

GET /bots/:id/votes?limit=100

Recent votes.

[{ "user": "987654321098765432", "username": "someone", "votedAt": "2026-09-26T18:00:00Z" }]

GET /bots/:id

Public bot info. No token needed.

Vote webhook

On every vote we POST this JSON to your webhook URL. Answer with any 2xx. If your server fails we retry after 30s, 2min, 10min, 1h and 6h.

{
  "type": "vote",            // "test" when sent from the settings page
  "bot": "123456789012345678",
  "user": "987654321098765432",
  "username": "someone",
  "votedAt": "2026-09-26T18:00:00Z",
  "votesMonth": 42,
  "votesTotal": 1337
}

Verifying

The Authorization header carries your secret. X-Nookie-Signature is an HMAC-SHA256 of the raw body using the same secret. X-Nookie-Delivery is unique per delivery, use it to ignore duplicates.

import crypto from 'node:crypto';

app.post('/nookie', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = 'sha256=' + crypto.createHmac('sha256', process.env.NOOKIE_SECRET)
    .update(req.body).digest('hex');
  if (req.get('X-Nookie-Signature') !== expected) return res.sendStatus(401);

  const vote = JSON.parse(req.body);
  // give the reward to vote.user
  res.sendStatus(204);
});