Permissions API
Legacy workspace apps are deprecated and will retire in August 2021. Learn more.
Whether your app asks for permissions progressively or requires them all at installation, workspace apps may use the Permissions API to programmatically manage workspace access.

- Overview
- Flow and states
- Resources
- Permission scopes
- Monitoring change with the Events API
- Asking for additional permissions progressively
- Methods for the Web API
- Events API events
Permissions API Overview
The Permissions API grants you the serenity to deftly manage your app's capabilities, privileges, and resources:
- Capabilities - the things your app can do for a workspace, like offering slash commands or posting interactive notifications. Sometimes, but not always, represented by a scope.
- Privileges - the things your app is allowed to do for a workspace, like being granted the ability to learn more about users or examine channel history. Typically represented by a scope. Scopes apply workspace-wide and travel to whichever resources your app is granted.
- Resources - the where and what your app can act and act on, like a list of channels, specific direct message conversations, and a workspace.
The Permissions API is not a single API but a collection of Web API methods and Events API event types that inform your app about permission and access change over time while also providing your app with the hooks needed to progressively ask for additional permissions. OAuth 2.0 is still required to manage initial application installation for distributed apps.
Workspace token-based Slack apps are required for the Permissions API. It cannot be used with traditional user and bot token-based Slack apps or legacy custom integrations.
Flow and states
Where does OAuth end and these permission APIs begin? In the infinitesimal space between the reticulated splines of each. They work together.
Here is a description of your hopefully never-ending, non-linear Permissions API lifecycle :
A user installs your app for the first (or nth) time
This is part of the Slack app installation flow, either using OAuth or the streamlined single workspace installation flow.

All workspace apps request default permissions from the installing user — the opportunity to have a direct message conversation with the app. Additional permissions can be requested at this time, or they can be saved for later.
A user adds your app to a resource
During the installation process or during the normal course of user business, a user might add your app directly to a resource.

One way they might do this is by inviting your app to a public or private channel, or by adding your slash command to a channel, or by discovering your app in the sidebar.
If subscribed, you'll receive resources_added
events as this happens.
A user removes your app from a resource
This happens to all apps. Your app is asked to leave a channel or is removed from it in some other way.
When this happens, your scopes and access will no longer apply to the resource and you'll get a resources_removed
event, if subscribed.
Your app requests additional permissions
If progressive permissions is an attractive concept to you, then bask in the opportunity to conversationally suggest expanding your app's permission purview.

While your app can't make this request out of the blue, there are many opportunities to initiate this flow and it's an ideal way to gate paid features, trial new functionality, and change your app's capabilities over time.
Implementation details can be found in the progressive permissions section below.
Your app is awarded or rejected those permissions
It's not enough to ask for progressive permissions, you need to be granted or rejected them to.

This step is actually just like the other resources_added
step above — the net result is your app gains resources and is notified about it.
Your app waits for stuff to happen
Your app is probably doing other things, just things with the permissions, resources, and capabilities afforded to it. But as far as the Permissions API goes, your app just waits for a new change to occur.
Maybe your app makes occasional requests to apps.permissions.resources.list
and apps.permissions.scopes.list
while waiting — just in case.
Resources
Each OAuth scope governs your app's capabilities against a set of resources.
A single resource might be a specific direct message conversation, a private channel, or maybe even a wildcard.
Today, workspace apps support only these resources:
app_home
- where your app interacts with users 1:1channel
- public channelsim
- private direct messages between two usersmpim
- private multi-party direct messagesgroup
- private channelsteam
- information about the workspace itself and its inhabitants
Expect this list to include users
and files
and more in the future.
Wildcard resources
These little tricksters let a user add your application to all of something. Today, only the channels
resource can be communicated as a wildcard, meaning a user can indicate your app should be installed in all public channels. All channels that is, except those explicitly excluded.
Here's what it looks like when a user selects a channel wildcard:

Find the status of any wildcard permissions granted to your app using apps.permissions.info
:
{
"ok": true,
"info": {
"channel": {
"scopes": [
"channels:history",
"chat:write"
],
"resources": {
"ids": [],
"wildcard": true,
"excluded_ids": [ "C01234BCD"]
}
}
}
}
The above structure says your app may read the history of and post messages to all public channels, except the channel identified by C01234BCD
.
Wildcard exclusions
You won't be able to read or write data about excluded resources.
Users may block workspace apps from a list the channels at installation time, even when installing to a wildcard like all public channels.
You'll find a list of excluded channel IDs in excluded_ids
arrays returned in apps.permissions.info
.
The resources listed in excluded_ids
supersede any wildcard-awarded grants. If your app is "kicked" or forced to leave a channel, that channel ID will be included in excluded_ids
.
OAuth permission scopes
As with all Slack apps, workspace apps are governed by the OAuth 2.0 scopes system.
OAuth permission scopes apply globally to workspaces your app is installed on. However, each specific resource those scopes work against are governed by granted resources. So if your app has the chat:write
and channels:history
scopes, those scopes travel with your app to any channel resource it's allowed to use, like a #general
channel.
To determine which OAuth scopes are supported with workspace apps, look for the workspace token labels. Only the scopes with this label work with workspace-based apps and the Permissions API.
Discover the currently supported scopes for workspace apps here.
Monitoring change with the Events API
If you're working with workspace apps or with the Permissions API, then chances are you'll want to use the Events API too. And if you do that, you'll want to subscribe to these app event types, which require no specific OAuth scope.
resources_added
The thing about this event is that you need to be ready for it at any time. In a world of workspace apps, a user might discover your app and open a conversation with it. Or discover your slash command and add it to a dozen channels willy-nilly.
For direct messages, you won't get a chance to say "yeah, but" — the conversation will open and you'll get the base-level grant to converse as if they're an installer.
{
"token": "verification_token",
"team_id": "T061EG9R6",
"api_app_id": "A0BLA3EP2",
"event": {
"type": "resources_added",
"resources": [
{
"resource": {
"type": "channel",
"grant": {
"type": "specific",
"resource_id": "C061EG9SL"
}
},
"scopes": [
"channels:read"
]
}
]
},
"type": "event_callback",
"authed_teams": [],
"event_id": "Ev0CV7H3KJ",
"event_time": 1501110008
}
Here's another example of a resources_added
event, this time our app is being awarded the users:read
scope against the team
resource. We can read the list of users and information about those users.
{
"token": "verification_token",
"team_id": "T061EG9R6",
"api_app_id": "A0BLA3EP2",
"event": {
"type": "resources_added",
"resources": [
{
"resource": {
"type": "workspace",
"grant": {
"type": "specific",
"resource_id": "T061EG9R6"
}
},
"scopes": [
"users:read"
]
}
]
},
"type": "event_callback",
"authed_teams": [],
"event_id": "Ev0CQ92RH7",
"event_time": 1501174698
}
See resources_added
for more information.
resources_removed
Users and admins can remove your app from channels and other conversations. Maybe someday they can seek and destroy a piecemeal permission. If you're keeping track, this event subscription will tell you which grants have gone the way of the dodo.
{
"token": "verification_token",
"team_id": "T061EG9R6",
"api_app_id": "A0BLA3EP2",
"event": {
"type": "resources_removed",
"resources": [
{
"resource": {
"type": "channel",
"grant": {
"type": "specific",
"resource_id": "C061EG9SL"
}
},
"scopes": [
"channels:read"
]
}
]
},
"type": "event_callback",
"authed_teams": [],
"event_id": "Ev0CV7JG72",
"event_time": 1501110117
}
See resources_removed
for more information.
scope_granted
When subscribed to this event, you'll receive it when a user approves specific scopes to your app. Often paired with resources_added
events, though it depends on what the scopes are being added to.
See scope_granted
for more information.
scope_denied
When subscribed to this event, you'll receive it when a user rejects the overtures of your apps.permission.request
.
See scope_denied
for more information.
Progressive permissions
Request for permissions all up front during installation, or ask for them incrementally using the Permissions API.
Learn more about building progressive permission upgrade flows.
Methods for the Web API
Look up your app's current state of permissions with a workspace or leverage a trigger_id
to make a progressive permissions request with these two workspace token API methods.
Examine current permissions
Look up your token's current permission state at will with apps.permissions.resources.list
and apps.permissions.scopes.list
. You'll find a complete inventory of afforded OAuth scopes and resources.
Your app's home
What's an app_home
? It's like a virtual house for your Slack app. Today, it's a handy way of knowing which users you can have open direct message conversations with — the ones users can find under Apps in the sidebar.

The resources correspond to those direct message conversations and scopes
are your app's powers granted to those same conversations.
The best way to receive and differentiate messages in App Home is by subscribing to message.app_home
events with the Events API. No additional scopes are required.
Request permissions with apps.permissions.request
This is your powerful write request initiating everything awesome about progressive permissions.
When successful, Slack presents a delightful dialog to the intended user, requesting the scopes in context to the appropriate resources.
The real trick with the method, if you haven't read deeper yet, is that you need a trigger_id
and you can only get one of those from a slash command invocation or an interactive message action. Learn more about triggers.
Which means that your app needs to incite a user to do something — click a button, select from a menu, or type a slash command to inspire your app to ask the user for more permission.
Events for the Events API
resources_added
- Dispatches when access to a set of resources is granted for your appresources_removed
- Dispatches when access to a set of resources is removed for your appscope_granted
- Dispatches when OAuth scopes are granted to your appscope_denied
- Dispatches when scopes were denied to your app as a result of aapps.permissions.request
message.app_home
- Dispatches when a user sends your app a message via their direct message-like App Home interface.
Triggers and how to find them
Learn more about finding and using triggers.