Vote Checking

Ask Discordium whether a Discord user has voted for your bot. This is the pull half of vote rewards (for push, see Vote Webhooks). Requires a token with the votes:read scope, created for a bot listing.

What “voted” means

voted: true means the user currently has an eligible vote: one cast within Discordium's active 12-hour voting window. It does not mean “this user has ever voted”. A vote older than the window answers voted: false with both timestamps null, which also means the user can vote again right now.

Check one user

GET/webhooks/votes/check?userId=<discord-user-id>

// Has this user voted in the last 12 hours?
const res = await fetch(
    "https://api.discordium.org/api/v1/webhooks/votes/check?userId=" + interaction.user.id,
    { headers: { Authorization: `Bearer ${process.env.DISCORDIUM_API_TOKEN}` } },
);
const { voted } = await res.json();

Response for a user with an active vote:

{
  "voted": true,
  "votedAt": "2026-08-24T18:42:00.000Z",
  "nextVoteAt": "2026-08-25T06:42:00.000Z"
}

And for a user with no currently eligible vote:

{
  "voted": false,
  "votedAt": null,
  "nextVoteAt": null
}
FieldTypeRequiredDescription
votedboolean-True while the vote is inside the active voting window.
votedAtstring | null-ISO timestamp of the eligible vote; null when voted is false.
nextVoteAtstring | null-When the user can vote again; null means they can vote right now.

The token identifies your bot. There is no parameter for “which bot”, so a token can only ever read its own listing's votes. userId must be a Discord user ID (a snowflake, digits only).

Check many users

POST/webhooks/votes/check

// Check up to 50 users with one request.
const res = await fetch("https://api.discordium.org/api/v1/webhooks/votes/check", {
    method: "POST",
    headers: {
        Authorization: `Bearer ${process.env.DISCORDIUM_API_TOKEN}`,
        "Content-Type": "application/json",
    },
    body: JSON.stringify({ userIds: ["123456789012345678", "876543210987654321"] }),
});
const { votes } = await res.json();
// votes["123456789012345678"] -> { voted, votedAt, nextVoteAt }

Up to 50 user IDs per request, answered from one database lookup, keyed by the IDs you sent. Each entry has exactly the single-check shape.

Rate limit

120 checked users per minute per bot. A single check costs 1; a batch costs one per unique user ID, so batches are how a busy bot checks thousands of users a minute inside the budget. Exceeding it answers 429 with the seconds to wait. The limit is per bot, so regenerating tokens does not reset it.

Building a vote reward system

The usual shape: a command checks eligibility, then either rewards or asks for the vote.

// A typical /claim command: reward only users with an active vote.
async function handleClaim(interaction) {
    const res = await fetch(
        "https://api.discordium.org/api/v1/webhooks/votes/check?userId=" + interaction.user.id,
        { headers: { Authorization: `Bearer ${process.env.DISCORDIUM_API_TOKEN}` } },
    );
    const { voted, nextVoteAt } = await res.json();

    if (!voted) {
        return interaction.reply(
            "Vote for the bot on Discordium first, then claim your reward!",
        );
    }

    // Your job, not Discordium's: decide the reward, store that THIS vote was
    // already claimed (nextVoteAt marks the window), and hand it out.
    await grantDailyReward(interaction.user.id, nextVoteAt);
    return interaction.reply("Reward claimed. Thanks for voting!");
}

Discordium verifies eligibility; it does not manage your rewards. Deciding what to grant, how often, storing who already claimed this vote (store nextVoteAt or the window alongside the claim), and preventing double-claims on your side is your bot's job. A simple rule that works: one claim per user per voting window.

Errors

StatusTypeRequiredDescription
400--userId is not a Discord snowflake, or the batch is empty/over 50 IDs.
401--Missing or invalid token, or the token lacks votes:read.
403--The token does not belong to a bot listing.
429--Vote-check budget exceeded; the response says how long to wait.