Skip to main content
Permissions are referenced by name throughout the SDK. You declare them in requiredPermissions, check them with can(), and read them from a PermissionSet. The names below are the exact strings to use. There are 31 permissions, codes 0 through 30. Names are what you write; the integer codes are the wire contract, and they matter only if you decode a raw grant yourself. For how declaring and granting work together, see the Permissions concept.

Administrator

If your bot holds administrator in a server, can() returns true for every other permission there. Ask for it only when your bot genuinely needs full control.
The expansion happens in can() only. administrator stays a distinct bit in a decoded PermissionSet, so a set where only administrator is true still has every other boolean false. Read it through can(), not by inspecting the booleans directly.

Server management

Most bots should not hold manage_server. It is only needed to mint or rotate webhooks. If your bot posts webhook embeds, have a human create the webhook in the Cloak app and pass its url in an environment variable instead. See Webhook embeds.

Viewing

view_text is what puts a text channel on your bot’s firehose. Without it in a given channel, your bot does not receive that channel’s messages at all.

Messaging

Members

Voice

voice_listen is the permission that decides whether your bot can hear anything. voice_connect does not imply it.Without it, your bot joins voice and publishes audio normally, the SFU sends it nothing, and it is never given a key that could decrypt anyone. joinVoice() deliberately succeeds without it, because publishing while deaf is the normal configuration for a music or announcement bot. The failure mode for a bot that was supposed to listen is total silence with no error anywhere. See Voice keys.
A bot holding voice_video still cannot publish camera or screenshare. A bot session’s media credential is minted microphone-only, so video is denied at the credential rather than by the SDK, and peer-to-peer video is deleted from the platform. There is no video path to enable.

Using names in code

Every name above is a value of the PermissionName type.
Ask only for the permissions your bot actually uses. A smaller request is easier for a server admin to approve, and it keeps the bot’s footprint honest.

PermissionName

A union of all 31 names, so you get autocomplete and compile-time checking.

PERMISSION_CODES

Maps each name to its wire code, 0 through 30.

PERMISSION_NAMES

Every name, indexed by wire code: PERMISSION_NAMES[14] is 'message_send'. That holds because the code map is dense with no gaps.

PermissionSet

The resolved capability set for one server: 31 named booleans plus a numeric rank. You get one from permissions(serverId), and the same shape is spread into the permissionsUpdate payload.
number
The bot’s effective rank in the server. Moderation actions compare ranks: your bot cannot kick, ban, or time out a member whose rank is not below its own.
boolean
One boolean per permission name. true means the bot holds it in this server.

decodePermArray

Decodes a raw code-indexed boolean array plus a rank into a named PermissionSet. Missing or falsy entries decode to false. You need this only when reading a grant off a raw frame; the SDK already decodes the ones it delivers.
decodePermArray does not expand administrator. A set decoded from an administrator grant has administrator: true and every other boolean false. Only can() applies the implies-all rule.

Next

Permissions concept

How declaring and granting fit together.

Errors

Reading the permission a denial names.

Client

can(), permissions(), and visibleChannelIds().

Voice keys

Why voice_listen decides what a bot hears.