Developer Docs

Track who votes for your bot and when — with real-time webhooks and a simple REST API.

Base URL https://api.botradar.gg

Overview

BotRadar gives you two ways to track votes:

📡
Webhooks (push)

We POST a vote event to your server the instant someone votes.

🔎
API (pull)

Query recent voters, or check if a user voted in the last 12 hours.

A common setup: reward users who vote (currency, a role, perks) and use the API to gate those rewards behind a recent vote.

Quickstart

  1. 1
    Configure your endpoint. On your Dashboard, open 🔌 Webhooks & API for your bot and set a Webhook URL + Authorization secret.
  2. 2
    Send a test. Hit Send test event to confirm your endpoint receives a type: "test" payload.
  3. 3
    Grab your API token from the same panel to use the pull API. Keep it secret.

Vote webhooks

When someone votes, we send a POST to your webhook URL with your secret in the Authorization header:

HTTP
POST /your/webhook  HTTP/1.1
Authorization: your-secret-here
Content-Type: application/json

{
  "bot":       "716390085896962058",
  "user":      "205680187394752512",
  "type":      "upvote",
  "isWeekend": false,
  "votedAt":   "2026-07-04T18:49:00+00:00"
}
Respond with any 2xx status to acknowledge. Non-2xx responses (or timeouts) are retried a few times — so keep your handler fast and do heavy work asynchronously.

Example receiver

JavaScript
import express from "express";
const app = express();
app.use(express.json());

app.post("/webhook/votes", (req, res) => {
  if (req.get("Authorization") !== process.env.BOTRADAR_SECRET) {
    return res.sendStatus(401);           // reject forged requests
  }
  const { user, type, votedAt } = req.body;
  if (type === "upvote") {
    console.log(`${user} voted at ${votedAt}`);
    // grant your reward here
  }
  res.sendStatus(200);                     // acknowledge quickly
});

app.listen(3000);

Verifying requests

Anyone could POST to your public URL, so always confirm the Authorization header matches the secret you set. Reject anything else with 401.

Treat your secret and API token like passwords — never commit them or expose them in client-side code.

The bot API

Authenticate by sending your bot's API token in the Authorization header (raw token, or Bearer <token>).

Shell
# Recent voters (who + when)
curl -H "Authorization: YOUR_API_TOKEN" \
  https://api.botradar.gg/api/bots/YOUR_BOT_ID/votes

# Has a user voted in the last 12h?
curl -H "Authorization: YOUR_API_TOKEN" \
  "https://api.botradar.gg/api/bots/YOUR_BOT_ID/check?userId=205680187394752512"

/votes returns an array of { user_id, voted_at }, newest first — pass ?limit= to cap how many (default 100, max 1000). /check?userId=<id> returns { voted: 0 | 1 }, where 1 means that user voted within the last 12 hours.

Fair use. Don't poll on every command — cache a user's /check result for the 12-hour vote window, and post server stats every 15–30 minutes rather than continuously. IDs are Discord snowflakes, so always handle them as strings.

Posting server stats

Keep your listing's server count up to date by POSTing it on a schedule (every 15–30 minutes is plenty). Send your API token in the Authorization header and the count as JSON:

Shell
# Update your bot's server (guild) count
curl -X POST -H "Authorization: YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"server_count": 1337}' \
  https://api.botradar.gg/api/bots/YOUR_BOT_ID/stats
The endpoint returns { ok: true, server_count } with the value we stored. Post from your bot's ready handler and on an interval so the number stays fresh.

Reference

Webhook payload fields

FieldTypeDescription
botstringYour bot's Discord ID.
userstringID of the user who voted.
typestringupvote or test.
isWeekendbooleanTrue on Sat/Sun.
votedAtISO 8601When the vote happened (UTC).

Endpoints

MethodPathAuthReturns
POSTyour webhook URLyour secretvote event (we send)
GET/api/bots/{id}/votesAPI token[{ user_id, voted_at }]
GET/api/bots/{id}/checkAPI token{ voted }
POST/api/bots/{id}/statsAPI token{ ok, server_count }

Query parameters

EndpointParamTypeDescription
/voteslimitintMax results, 1–1000 (default 100).
/checkuserIdstringRequired. Discord user ID to look up.

Request body

EndpointFieldTypeDescription
/statsserver_countint ≥ 0Current guild count.

Status codes

CodeMeaning
200OK.
401Missing or invalid API token.
404Bot not found.
422Invalid body/params (e.g. a negative server_count).
429Rate limited — a user can only vote once per bot every 12h.