> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cloak.chat/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> All 31 permission names you can declare or check, their wire codes, and the runtime helpers.

Permissions are referenced by name throughout the SDK. You declare them in [`requiredPermissions`](/api-reference/client#constructor-options), check them with [`can()`](/api-reference/client#can), and read them from a [`PermissionSet`](#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](/concepts/permissions).

```ts theme={null}
const client = new Client({
  token: process.env.CLOAK_TOKEN!,
  requiredPermissions: ['view_text', 'message_send', 'reaction_add'],
});
```

## Administrator

| Name            | Code | Controls                 |
| --------------- | ---- | ------------------------ |
| `administrator` | 0    | Grants every permission. |

If your bot holds `administrator` in a server, [`can()`](/api-reference/client#can) returns `true` for every other permission there. Ask for it only when your bot genuinely needs full control.

<Note>
  The expansion happens in `can()` only. `administrator` stays a distinct bit in a decoded [`PermissionSet`](#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.
</Note>

## Server management

| Name               | Code | Controls                                     |
| ------------------ | ---- | -------------------------------------------- |
| `manage_channels`  | 3    | Create, edit, and delete channels.           |
| `view_audit`       | 4    | View the audit log.                          |
| `view_insights`    | 5    | View server insights.                        |
| `manage_server`    | 6    | Change server settings, and manage webhooks. |
| `invite_creation`  | 7    | Create invites to the server.                |
| `emoji_gif_manage` | 10   | Manage the server's emoji and GIFs.          |
| `event_invite`     | 29   | Invite members to calendar events.           |

<Tip>
  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](/guides/webhook-embeds).
</Tip>

## Viewing

| Name                   | Code | Controls                                                |
| ---------------------- | ---- | ------------------------------------------------------- |
| `view_text`            | 1    | View text channels. Required to receive their messages. |
| `view_voice`           | 2    | View voice channels.                                    |
| `message_read_history` | 20   | Read past messages in a channel.                        |

<Note>
  `view_text` is what puts a text channel on your bot's [firehose](/concepts/message-delivery). Without it in a given channel, your bot does not receive that channel's messages at all.
</Note>

## Messaging

| Name             | Code | Controls                                                                           |
| ---------------- | ---- | ---------------------------------------------------------------------------------- |
| `message_send`   | 14   | Send messages. Also all that [`sendCard()`](/api-reference/client#sendcard) needs. |
| `message_manage` | 15   | Manage other members' messages, such as deleting them.                             |
| `embed_link`     | 16   | Post links that render as unfurled previews.                                       |
| `upload_file`    | 17   | Attach files.                                                                      |
| `reaction_add`   | 18   | Add reactions to messages.                                                         |
| `mention_roles`  | 19   | Mention roles.                                                                     |
| `commands`       | 21   | Use commands.                                                                      |

## Members

| Name              | Code | Controls                         |
| ----------------- | ---- | -------------------------------- |
| `nickname_change` | 8    | Change the bot's own nickname.   |
| `nickname_manage` | 9    | Change other members' nicknames. |
| `member_kick`     | 11   | Remove members from the server.  |
| `member_ban`      | 12   | Ban members from the server.     |
| `member_timeout`  | 13   | Time members out.                |

## Voice

| Name             | Code | Controls                                                         |
| ---------------- | ---- | ---------------------------------------------------------------- |
| `voice_connect`  | 22   | Connect to voice channels.                                       |
| `voice_speak`    | 23   | Speak in voice channels.                                         |
| `voice_video`    | 24   | Share video in voice channels. Not available to bots, see below. |
| `voice_activity` | 25   | Use voice activity detection.                                    |
| `members_mute`   | 26   | Mute members in voice.                                           |
| `members_deafen` | 27   | Deafen members in voice.                                         |
| `members_move`   | 28   | Move members between voice channels.                             |
| `voice_listen`   | 30   | Receive other members' voice media.                              |

<Warning>
  **`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()`](/api-reference/client#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](/voice/keys).
</Warning>

<Note>
  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.
</Note>

## Using names in code

Every name above is a value of the `PermissionName` type.

```ts theme={null}
import type { PermissionName } from '@cloak-software/bot-sdk';

const needed: PermissionName[] = ['view_text', 'message_send'];
```

<Tip>
  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.
</Tip>

### PermissionName

```ts theme={null}
type PermissionName = 'administrator' | 'view_text' | /* ...29 more... */ | 'voice_listen';
```

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

### PERMISSION\_CODES

```ts theme={null}
const PERMISSION_CODES: Record<PermissionName, number>
```

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

```ts theme={null}
import { PERMISSION_CODES } from '@cloak-software/bot-sdk';

PERMISSION_CODES.message_send; // 14
```

### PERMISSION\_NAMES

```ts theme={null}
const PERMISSION_NAMES: PermissionName[]
```

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

### PermissionSet

```ts theme={null}
type PermissionSet = { effectiveRank: number } & Record<PermissionName, boolean>;
```

The resolved capability set for one server: 31 named booleans plus a numeric rank. You get one from [`permissions(serverId)`](/api-reference/client#permissions), and the same shape is spread into the [`permissionsUpdate`](/api-reference/events#permissionsupdate) payload.

<ResponseField name="effectiveRank" type="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.
</ResponseField>

<ResponseField name="[permission]" type="boolean">
  One boolean per permission name. `true` means the bot holds it in this server.
</ResponseField>

```ts theme={null}
client.on('permissionsUpdate', ({ serverId, effectiveRank, ...perms }) => {
  console.log(`send in ${serverId}: ${perms.message_send}, rank ${effectiveRank}`);
});
```

### decodePermArray

```ts theme={null}
decodePermArray(permArray: unknown[], effectiveRank: number): PermissionSet
```

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](/guides/raw-frames); the SDK already decodes the ones it delivers.

```ts theme={null}
import { decodePermArray } from '@cloak-software/bot-sdk';

const set = decodePermArray(rawBooleans, rank);
if (set.message_send) { /* ... */ }
```

<Warning>
  `decodePermArray` does **not** expand `administrator`. A set decoded from an administrator grant has `administrator: true` and every other boolean `false`. Only [`can()`](/api-reference/client#can) applies the implies-all rule.
</Warning>

## Next

<CardGroup cols={2}>
  <Card title="Permissions concept" icon="key" href="/concepts/permissions">
    How declaring and granting fit together.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/api-reference/errors">
    Reading the permission a denial names.
  </Card>

  <Card title="Client" icon="book" href="/api-reference/client">
    can(), permissions(), and visibleChannelIds().
  </Card>

  <Card title="Voice keys" icon="microphone" href="/voice/keys">
    Why voice\_listen decides what a bot hears.
  </Card>
</CardGroup>
