Blog / Developers: 3 Patterns for Discord Webhook Voting and Overlays

Developers: 3 Patterns for Discord Webhook Voting and Overlays

September 9, 2026by PickThe.Games

Developers: 3 Patterns for Discord Webhook Voting and Overlays

Developer tracing webhook vote event

Yes, you can implement voting entirely through webhooks. Discord's native poll object works through incoming webhook execution, so you post a poll to a channel with a single JSON call. Separately, platforms like top.gg and DisQ send outgoing vote events to your own endpoint whenever someone votes for your bot or server. Your two build tasks are constructing valid poll payloads and securing an endpoint to receive vote events. Check the constraints first: duration runs within a supported range of hours, and you get a limited number of answers per poll.

*

> TL;DR:

>

> - Webhook-based voting requires constructing valid JSON payloads with specific field constraints, especially ensuring correct duration and answer character limits.

> - Securing and verifying incoming vote webhooks involves signature validation, event logging, replay prevention, and rate limiting to avoid fraud and duplicates.

> - Final poll results should be retrieved after expiry using the is_finalized flag instead of trusting live counts, which may still be in processing.

> - Using webhooks for voting works best for quick, public decisions, while more complex ballots or scheduled votes benefit from dedicated bot implementations.

> - Testing with staged environments and adhering to recommended durations and answer limits improves reliability and reduces support issues.

*

Table of Contents

Discord webhook voting: the poll object and API rules

The Discord poll object has strict rules, and getting them wrong just means a rejected request rather than a broken poll. Your webhook execution request needs a poll object in the JSON body. You can add plain content above it, but not embeds, since Discord's webhook resource treats polls and embeds as mutually exclusive in the same message.

Inside the poll object, four fields matter most:

  • question.text: plain text only, capped at 300 characters.
  • answers: an array of poll_media objects, each capped at 55 characters. Wrap every answer in its own poll_media object rather than passing a bare string, or the request fails.
  • duration: a whole number of hours within a valid range. Fractional or out-of-range values return a 400 error, and this trips up more developers than any other field, according to community webhook guides.
  • allow_multiselect and layout_type: a boolean and an integer respectively, with layout_type currently fixed at 1.

You can create or modify a channel webhook only with the MANAGE_WEBHOOKS permission, and executing that webhook usually needs its token. One detail worth flagging early: append ?wait=true to the execute URL and Discord returns the full created message object. Leave it off and you get a bare 204 with no body, which is fine for fire-and-forget posts but useless if you need the message ID for later reference.

How do you send a poll via a Discord webhook?

Three steps get a poll live: build the JSON, fire the request, confirm the response. Here's the minimal version, a 24 hour single-select poll sent with curl.

1. Send the poll with curl. Point at your webhook URL, set Content-Type: application/json, and pass a body containing question, an answers array of poll_media objects, duration: 24, allow_multiselect: false, and layout_type: 1. This is the same structure documented in Discord's guide to the Poll API.

2. Send it with Node.js. Use fetch with method: "POST", the same JSON body, and add ?wait=true to the URL. Check response.status for 200 (with wait=true) or 204 (without), and parse the body only when you expect one.

3. Add multiselect and custom emoji. Set allow_multiselect: true to let voters pick more than one answer. For emoji, use emoji.name for a Unicode character or emoji.id for a custom server emoji, nested inside each poll_media answer object.

4. Test before you ship. Strip stray Unicode from question and answer text, set allowed_mentions explicitly so a poll doesn't accidentally ping @everyone, and run every new payload through a staging channel before it touches a live server.

None of this requires a bot process running, making it compatible with features like Discord AI Girlfriend Bots that enhance Discord integrations. A single webhook URL and an HTTP client are enough to post a working poll, which is exactly why webhook-based polling is the fastest route to "discord webhook voting" for a side project or a lightweight integration.

How do external platforms send vote webhooks to your bot?

Discovery platforms work the opposite direction: instead of you pushing a poll, they push a vote event to you. When someone upvotes your bot on top.gg, their servers fire a POST request to whatever endpoint you registered, carrying a payload with fields like data.user.platform_id, data.weight, and data.expires_at, according to top.gg's webhook documentation. DisQ follows a similar model, and its payloads can include an HMAC signature header for verification, per DisQ's webhooks overview.

Before that endpoint touches production traffic, it needs to handle a few things properly:

  • Expose a public HTTPS URL that parses incoming JSON and responds quickly, with a 2xx status.
  • Verify the platform-specific signature or shared secret on every request, and reject anything that fails.
  • Enforce a replay window so a captured request can't be resent hours later to trigger a duplicate reward.
  • Log the raw event ID before you do anything else with the payload, so duplicate deliveries get caught rather than double-counted.
Pro Tip: Fire a test event from your dashboard before you accept a single real vote. Top.gg and similar platforms let you trigger a sample payload against your endpoint, which is the fastest way to confirm your signature verification actually works rather than silently passing everything through.

Note the data.weight field carefully. Top.gg applies weekend multipliers, so a single vote can count for more than one, and reward logic that ignores this will under-pay or over-pay users depending on when they vote.

What causes voting webhooks to fail, and how do you fix it?

Most failures come from three places: bad payloads, premature trust in interim results, and unprotected endpoints.

Validate poll parameters before you ever send the request, not after Discord bounces it back. Check duration is a whole number between 1 and 720, confirm you have no more than 10 answers, and confirm every answer sits under 55 characters. Catching these client-side saves you a wasted round trip and an unhelpful 400 response.

The bigger trap is finalisation. In-progress answer_counts on a poll are usually close to accurate, but Discord's own Poll resource documentation is explicit that a background job finalises the real tally, and only the is_finalized flag confirms results are locked. If you're paying out a prize or logging an official winner, poll the resource after expiry and check that flag rather than trusting whatever number showed at the moment the poll closed.

On the inbound side, treat every vote webhook as hostile until proven otherwise:

  • Verify HMAC signatures and reject any request where the signature doesn't match.
  • Check the User-Agent and any platform-specific headers rather than trusting the payload shape alone.
  • Persist event IDs so a replayed or duplicated delivery gets ignored rather than reprocessed.
  • Rate-limit the endpoint itself, since a spoofed flood is cheap to launch and expensive to clean up after.

Roughly a fifth of poll-related support questions in developer communities trace back to developers editing a posted poll message directly instead of letting it expire naturally. Design around close and expiry, not manual edits.

Which integration pattern fits your voting use case?

Three patterns cover most real deployments, and picking the right one saves you from over-building.

1. Reward pipeline. Validate the incoming webhook, push the event onto a queue, update your database, then issue the reward through your bot token or a scheduled direct message. Keeping validation and reward issuance in separate steps means a slow database write never blocks your webhook response.

2. Live overlay. Forward validated vote or poll events to a WebSocket or server-sent-events stream that feeds OBS or a custom overlay. Store timestamps alongside each event so a viewer refreshing the page doesn't trigger a duplicate on the leaderboard.

3. Bot fallback. Webhook polls are the right call for quick, public, single-round decisions with no setup overhead. Reach for a full bot instead when you need private ballots, ranked-choice voting, or elections that need rescheduling, since bot-based voting projects handle that logic far more cleanly than a one-shot webhook ever could.

Pro Tip: If your goal is genuinely just "help my group agree on a game", building your own poll pipeline is often more plumbing than the problem deserves. Pickthe already handles the swipe, veto, and Discord integration side of group voting, including live vote overlays for streamers who want the same OBS pattern without wiring it themselves.

A working checklist for Discord webhook voting

Every webhook voting system Pickthe has looked at fails in the same handful of places, so the checklist writes itself: validate every payload before it leaves your server, verify signatures on everything coming in, prefer finalised counts over live tallies, log event IDs from day one, and keep poll durations moderate.

A working checklist for Discord webhook voting — overview diagram

Our recommended defaults: 24 hours per poll, four to six answers rather than the full ten, and single-select unless multi-select genuinely serves the decision. Shorter polls with fewer choices get higher completion rates in practice, and ten near-identical answer options mostly just splits your vote count and muddies the result.

Use test events and a staging channel before anything touches production. It costs you five minutes and saves you a broken poll in front of an actual Discord server. If you're building overlay or reward logic on top of vote events, the Discord game picker guide and its companion piece on why simple polls fall short for game selection are worth reading before you commit to a full custom build.

> — PickThe

Skip the plumbing: vote on games, not just polls

Webhook polls are great for a quick yes or no, but they run out of road fast once your group needs to weigh compatibility, platform, and everyone's actual preference in one go. That's the gap Pickthe fills: real-time swiping and voting across a shared board, a veto system so one bad pick doesn't ruin the night, and a crossplay compatibility checker that rules out games half your group can't even join.

Pickthe

Streamers get the overlay side too, with OBS-ready leaderboards viewers can vote on through a sharable link, no bot hosting or signature verification required on your end. If your Discord server already leans on polls for game nights, the game night picker is the natural next step: point your group at a board, let them swipe, and let the veto system settle the rest in minutes rather than another round of thumbs-up reactions in a channel nobody scrolls back through.

Sources

Recommended

Find games your group can play

Create a board, invite friends, swipe on games. Free.

Related posts