All Articles
Engineering5 min read

Privileged Intents and Bot Verification: What Discord Will and Will Not Let Your Bot Read

The three privileged intents, the hundred-server threshold that changes everything, what verification actually asks for — and how to design a bot that never needs to read message content in the first place.


Two mechanisms decide what a Discord bot can see: intents, which declare the event classes it receives, and verification, which gates the sensitive ones once the bot is widely installed. Both are usually discovered halfway through a project, which is the expensive moment to discover them.

What an intent is

When a bot opens its gateway connection it declares which categories of events it wants. Discord then sends only those. This exists for scale — a bot that does not care about voice state should not receive every voice update in every server it is in — and it has become the main privacy control on the platform.

Most intents are unrestricted: guilds, messages, reactions, voice states. Three are privileged, and those three are where the friction lives.

The three privileged intents

Server Members covers the member list and join and leave events. Presence covers online status and activity. Message Content covers the actual text of messages, plus embeds, attachments and components — with the important exception that a bot always sees content in messages it sent itself, in direct messages it receives, and in messages where it is mentioned.

That exception is the design lever. A bot invoked by a mention or a slash command does not need the Message Content intent to read the thing it was invoked with. A bot that scans everything to look for a trigger word does.

The hundred-server threshold

Below roughly a hundred servers, a developer can switch privileged intents on in the developer portal without review. At and above that number, the bot must be verified and the intents must be applied for and approved individually.

For a bot built for a single community this threshold never arrives, which is a genuine and underrated advantage of a purpose-built bot: it can use what it needs without a review process, and it will not be switched off by a policy change aimed at public bots.

What verification actually asks

Verification asks the developer to justify each privileged intent against what the bot does. A vague answer or an intent the described features do not require is the usual reason an application comes back. The practical implication is that “we might need it later” is not an argument that works, and building on the assumption that it is will cost you a rewrite.

The process also involves identity verification for the developer account, which is worth knowing before you build a business on an anonymous account.

Designing so you do not need message content

Almost everything communities want from a bot can be built on interactions. Slash commands carry their own arguments. Buttons and select menus carry the identity of who pressed them. Modals collect structured input. In every case the bot receives exactly what it needs and nothing else.

The features that genuinely need message content are narrow: keyword-based auto-moderation, which Discord’s own AutoMod now covers natively, and analytics over message text, which is rarely worth the privacy cost. If your specification needs the intent, it is worth asking whether the feature is worth it — and Discord will ask you the same question.

Presence is more expensive than it looks

The presence intent produces a very high event volume — every status change of every member in every server. For a large community it dominates the bot’s traffic and memory, usually to power a feature nobody asked for. Unless a documented requirement depends on live presence, leave it off.

Scale changes the shape

Beyond a few thousand servers a bot must shard its gateway connection across several sockets, and the global request limit plus per-route limits start constraining anything that loops over members. A single-community bot avoids all of this; a public bot is designed around it from the start. These are different products, and asking one to behave like the other is where most “our bot got slow” stories begin.

What to ask when you commission one

Which intents does this need, and why each one. What happens if the bot is offline for an hour. Where does the data live and who can reach it. Does the design assume message content, and if so, what would the feature look like without it. Four questions, and the answers tell you whether the thing was designed or assembled.

What happens if an intent is refused or revoked

An intent is not granted permanently. It can be refused at verification, and it can be withdrawn later if the justification no longer matches what the app does. When that happens the events simply stop arriving — the bot does not crash, it goes quiet, which is a considerably worse failure mode.

The defensive design is to fail loudly. Check at startup which intents were actually granted, log a clear error when a required one is missing, and disable the affected feature explicitly rather than letting it silently do nothing. A bot that announces what it cannot do is debuggable; one that pretends everything is fine is not.

Testing without the privileged ones

A common trap: the bot works in development, where it is in one server and the developer switched every intent on, and then behaves differently in production. Develop with exactly the intents the production application has been granted, not with all of them.

The same applies to permissions. Test with the role the bot will actually hold, positioned where it will actually sit in the hierarchy — the majority of “it worked yesterday” reports come from a role order change rather than from code.

Migrating an existing bot off message content

If you inherit a bot built around prefix commands, the migration is mostly mechanical: each prefix command becomes a slash command with typed arguments, each keyword trigger becomes either a button, a context-menu entry or an AutoMod rule. The work is in the inventory, not in the individual conversions.

Do the inventory honestly. Most legacy bots have a handful of commands that anyone uses and a long tail nobody has invoked in a year. Migrating the tail is the part that makes the project look expensive; deleting it is usually the correct decision and the one nobody wants to make.

The developer portal checklist

Before a bot goes anywhere near production: intents set to exactly what the code uses; the OAuth invite scoped to the permissions actually needed rather than Administrator; the token stored outside the repository; two-factor authentication on the developer account; and a description in the portal that matches what the app really does, because that description is what a reviewer reads.

None of this takes an hour, and all of it is harder to add once the bot is live in a community that depends on it.

Sources

  1. 01What are Privileged Intents?Discord Developer Support
  2. 02GatewayDiscord Developer Documentation
  3. 03Gateway Intentsdiscord.js Guide
  4. 04Discord Developer Terms of ServiceDiscord Developer Support
  5. 05Discord Developer PolicyDiscord Developer Support
  6. 06My Bot is Being Rate LimitedDiscord Developer Support
  7. 07Auto Moderation in DiscordDiscord Safety Center

A bot that needs message content is a bot that will be harder to approve.

We design against interactions first — slash commands, buttons, modals — so the bot stays cheap to run, easy to verify and useful from day one.

Have your bot designed properly