# Permissions

> The scopes an app can hold, and what each one opens.

Each endpoint and event needs a permission (a _scope_), given to the app by whoever manages it (a workspace admin, or the member who made it when the workspace
allows that) under _Manage → Installed apps → the app → Permissions_. Removing a permission takes effect at once.
Subscribing to an event in _Event subscriptions_ adds the permission it needs.

An app made by a member follows that member: if they leave the workspace or delete their account the app is deactivated, and if they leave a private channel the app leaves it too. An admin can reactivate it: deactivating an app revokes its token and webhook URLs, so reactivating always issues new ones.

| Scope               | Opens                                                                            |
| ------------------- | -------------------------------------------------------------------------------- |
| `incoming-webhook`  | Incoming webhook URLs                                                            |
| `chat:write`        | `POST /messages`                                                                 |
| `reactions:write`   | `POST` and `DELETE /reactions`                                                   |
| `channels:read`     | `GET /channels`: public channels, each with `is_member`                          |
| `groups:read`       | adds to `GET /channels` the private channels the app already belongs to          |
| `channels:join`     | `POST /channels/{id}/join` (public channels only)                                |
| `channels:history`  | `GET /channels/{id}/messages`, and the `message.channel` and `message.im` events |
| `users:read`        | `GET /users` (ids and names, never emails)                                       |
| `app_mentions:read` | the `app_mention` event                                                          |
| `commands`          | slash commands the app registered, and answering them                            |

An app can read or write inside a channel only while it belongs to it. It joins public channels itself
(`channels:join`); a private channel needs a person to add it.

A missing permission answers `403` with `error: "missing_scope"` and `needed` naming it.

