Go to Slack

Working with workspace tokens

Developer preview

Workspace apps are currently in developer preview. You are welcome to install as internal integrations or distribute to other workspaces, but we aren't yet accepting workspace app submissions for the Slack app directory.

Workspace tokens are OAuth 2.0 bearer tokens representing your Slack app's ongoing relationship and agency with a specific Slack workspace.

In this document we'll cover:

You'll find methods, events, and features supporting workspace tokens stamped with this delicious token candy: workspace

And in case you're on the lookout, this other important documentation is part of this developer preview:

Follow along with your own app

Create a developer preview app

It might be helpful to have one while following along. Keep in mind that during the developer preview, these apps cannot be distributed in the directory.

Does this sound familiar?

Traditional Slack apps are sturdy and stalwart app containers and conveyors of many kinds of tokens, and they certainly get the job done.

But they are not without their quirks. Which is your favorite?

  • A workspace wouldn't install your bot user because it asks for too many permissions.
  • The user who installed your app left the workspace and now your app is uninstalled too.
  • You wanted your bot user to do something that only user tokens could do.
  • You became overwhelmed with so many tokens to juggle just for a single workspace.
  • You were ready to use a feature requiring new permission scopes but didn't want to ask users to reinstall your app.
  • It's unclear when your app is part of a conversation.
  • Team owners don't want your slash command installed in all channels.
  • You wanted to offer a focused, low-risk trial mode for your app but couldn't.

These quirks are largely factored out using workspace tokens and our revised permission model.

Introducing a revised permission model

Workspace apps operate on a new permission model that is both more workspace-centric and context-centric than the original model.

Once installed with your selected base-level permissions, your app can be added to channels, direct messages, and other conversation types as directed by the workspace's members and administrators.

Your app can ask for all the permissions it will ever need up front.

But, when and if you prefer, you can also request additional permissions conversationally, such as when you release a new feature, or are offering a trial mode, or just to more progressively inch your way into the hearts and minds of workspaces.

The Permissions API covers everything you need to know about determining your tokens current state and requesting progressive permissions.

One token to mind

You'll receive a single token at installation representing everything your app can do with the installing workspace — in real time, every channel your app is added to, every permission it's afforded, and its every capability will be bestowed upon this token.

No more bot tokens. No more user tokens. Just this one workspace token, representing your app and its relationship to a workspace. Take good care of it.

How do all the token types differ? See token types to compare.

Enjoy a nice chat with the installing user

Even without requesting any explicit list of scopes, installing your app yields a collection of scopes applied to a special direct message conversation with the installing user.

This is a great opportunity to progressively request additional scopes and resources by giving the installer an opportunity to select which channels and conversations to add your app to.

It's your moment to show off what your app can do in the safe confines of a private conversation.

Deep link to a conversation with your app from websites, messages, or even redirect to your app during installation flows.

Permissions API

Besides giving you a great interface to your app's permissions and a heartbeat as they change, the new Permissions API allows your app to interactively and progressively request additional permissions and capabilities within context to the actions your app takes.

This document is already long and the Permissions API is in another castle: Read the Permissions API documentation for the full story. šŸ°

Even so, the Permissions API is so pivotal to the workspace token experience, here are more highlights:

Installed for an entire workspace

When these new kinds of Slack apps are first installed, it's done so for an entire workspace. Installation is just a fact. An app is installed or it's not and some member of the workspace installed it, but that workspace member is not the app's "keeper."

Awarded permissions progressively

New Slack apps receive progressive permissions. The best way to upgrade permissions beyond a direct message interaction is through conversation — telling the user what your app can do and giving them a button that will begin a Slack native dialog for upgrading permissions.

Provisioned to channels, conversations, and resources

This permission system is resource-centric. Experientially, one might even say it's channel and conversation-centric. The permission scopes granted to your app are granted within the context of specific resources, channels, or conversations.

Often those permissions are narrow — maybe just a DM with 1 or 2 users. Maybe just read and write access to a single public channel. Or maybe your app has permission to understand the wider universe of the whole workspace.

One access token per workspace

All of these workspace permissions are encoded in a single access token. This access token can do anything your app has permission to do within the context of a single workspace. With the right scopes, your workspace token can even act on a user's behalf.

Follow along with this guide to discover the most salient new Slack app features.

Workspace-based apps are so fresh!
  • Workspace-based apps cannot yet be distributed to other workspaces. They're just for your own development and exploration now.
  • SDKs, libraries, and tools you are familiar with may outright just not work with workspace-based Slack apps yet.
  • Using the Events API isn't required but it's strongly recommended. It is the best way to learn about what's happening with your app, installations, and of new conversation opportunities.

Workspace tokens can't do that on Slack

In general, these new Slack apps cannot do the following:

  • Contain a bot user — workspace tokens make bot tokens and users obsolete; your app is a bot if you want it to be but you don't need a bot user feature to provide that functionality.
  • Connect to the RTM API — it's just not possible or practical with this permission model. Please use the Events API for near-real-time delivery instead.
  • Incoming webhooks aren't part of the new Slack app model. Apps should use chat.postMessage with the new channel & conversation selection model in the Permissions API instead.
  • Sign in with Slack is not yet available for new Slack apps.

Some functionality previously made possible through impersonating the authenticating user, like creating and inviting users to channels, is no longer possible with this model.

Something you really want to do but can't? Let us know!

Getting started

Wow that's a lot of text you've read so far! And you're only now getting started?

We think it's best to approach this new way of creating Slack apps as a fresh, new experience. Write something completely new. Hack. We don't recommend trying to make your old app run on this new model yet. Apps built with this new model cannot yet be added to the directory.

Build something fun, use some features you may not yet be familiar with, try something new, please break things.

No direct migration path for existing apps is provided yet; more detail on migration will be communicated in the coming weeks.

Create a workspace app

Did you create a workspace app yet? Go ahead and create this fancy new app container.

Install your app

Once created, install your new app onto your workspace. You don't need OAuth and you don't even need to code anything yet.

Approve default permissions

As part of installation, you'll be asked if your app can "Direct message users who use $APP, and view messages, activity, and files in that DM". That sounds fantastic. Approve it.

Essentially, all workspace apps are granted a special "application direct message" with the installing user.

Send your app's first message

Now your app can start conversing with you. Follow the prompts to send a test message. Try the in-page curl example to get a real feel for it.

curl -X POST --data 'token=xoxa-token-token-token-token&channel=%40episod&text=Hello%2C%20world!' https://slack.com/api/chat.postMessage

After that, visit your Slack workspace and open up the conversation with your new app.

Your app is now ready to do and be much more.

This new Slack app model definitely puts a focus on conversations but your app is not required to be a bot.

If you're familiar with the old Slack app model where apps could contain a separate "bot user" entity, you'll find that now your whole app is capable of being a bot, no special user or token required.

Instead of being given a blanket set of bot permissions, workspace apps are more narrowly and explicitly scoped.

Upon installation, your app was granted chat:write, im:read, and im:history all applied to that single conversation with you.

You can converse (if you want to)

Asking for progressive permissions is optional but awesome.

Your "app message" — that initial Hello world to your app's first user will remain a one-sided conversation until we provide your app with a way to receive messages from conversations like this one.

To truly hold court with a user, you'll need to put together a few different Slack app features:

  • the Events API - your conduit to real-time happenstance on the Slack workspace you're working against
  • the Web API - at the very least you'll need to use chat.postMessage to send messages to users in the channels your app participates

Default conversational permissions

Your app by default will be granted the chat:write, im:read, and im:history scopes granted toward a single resource: the app's installer. Your app can't send that "hello world" message to just any user — though it has those three scopes, they only apply to that single conversation.

This triad of scopes lets your app behave like a bot in that channel — if it wants to. And it should. Even if your app is just a slash command, anticipate that users might want to chat with it. Maybe you just want to respond with a friendly message on how to use the slash command.

To receive these messages, you should parlay these permissions into an Events API subscription to message.im. Then when a user sends a message via direct message to your bot, you'll receive a single event detailing its contents.

Your app is given the chat:write OAuth scope applied to this direct message, so it has access to chat.postMessage and you can respond to the user with that.

Installing workspace apps

During the Alpha, new Slack apps are currently installable via two approaches:

  • Installing your app to your own workspace through the guided App Management UI
    • This is the process we detailed in the "Hello world" example above
  • Installing your app to your own workspace using OAuth 2.0
    • With the new permission model, some responses to token acquisition methods differ from legacy Slack app OAuth.

Installing with OAuth 2.0

Slack OAuth 2.0 implementation remains largely unchanged for workspace apps. If you're new to Slack's OAuth sequence or OAuth 2.0 in general, we recommend reading our OAuth guide to understand the sequence of steps involved.

  1. First you, or Slack, send a user to Slack's authorization end point: https://slack.com/oauth/authorize with the appropriate parameters.
  2. Users determine whether they want to install the app given the permissions it is requesting
  3. (new) Users determine to which resources they want to give the app access: public channel(s), a direct message, a group DM, workspace user data, etc.
  4. Slack sends the user back to the redirect URI you registered in your app's management console, along with a short-lived verification code value
  5. You send a request to https://slack.com/api/oauth.access with a few parameters, including that code value we sent you in the last step
  6. Slack returns a workspace token beginning with xoxa-, representing your current permission level with that workspace.

As with all of our OAuth flows, apps can be installed multiple times by the same user or different users. In the new model, apps are installed onto the whole workspace but the installing user decides which resources to provision to the Slack app.

There are other ways for users to elevate the permissions and resources afforded to your app. Read all about them in the Permissions API.

OAuth installation response

When negotiating workspace tokens with oauth.token, you'll receive JSON payloads differing significantly from the typical response found in oauth.access.

Dwell on this little bit of well-intentioned complexity:

    "ok": true,
    "access_token": "xoxa-access-token-string",
    "token_type": "app",
    "app_id": "A012345678",
    "app_user_id": "U0AB12ABC",
    "installer_user_id": "U061F7AUR",
    "authorizing_user_id": "U061F7AUR",
    "workspace_name": "Subarachnoid Workspace",
    "team_id": "T061EG9Z9",
    "scopes": {
        "app_home": [
        "workspace": [],
        "channel": [
        "group": [
        "mpim": [
        "im": [
        "user": []
    "single_channel_id": "C061EG9T2"

This structure communicates a short story:

  1. An access token has been awarded or refreshed on the workspace identified by T061EG9Z9 ("Subarachnoid Workspace") for your Slack app identified by the ID A012345678.
  2. The user who originally installed the app is the same user currently performing the authorization flow, user U061F7AUR.
  3. The user approved the app for the chat:write scope, but access was only granted to a single public channel resource, C061EG9T2.
  4. The app is automatically awarded the ability to read, write, and peruse the history of its conversation with the installing user in its app_home. Subscribe to these messages using the Events API event message.app_home.

oauth.token response field guide

  • access_token - Your new workspace token that begins with xoxa. It can be very long.
  • token_type - You'll see app here. Workspace tokens were once known as app tokens. Maybe someday this value will become team.
  • app_id - This is the unique ID for your whole Slack app.
  • app_user_id - This is the user ID of your app. It's a user! It's an app! It's a user! It's an app! The user ID is unique to the workspace installing it.
  • installer_user_id - This is the user ID of the user that originally installed this app.
  • authorizing_user_id - This user ID belongs to the user currently undergoing the authorization process.
  • workspace_name - This is what the workspace calls itself.
  • team_id - This is the unique ID for the workspace.
  • permissions - This field is no longer available. Use apps.permissions.info to look up all of your app's permissions for this workspace instead.
  • scopes - the OAuth scopes awarded to your app in this particular installation attempt.
  • single_channel_id - if this app is approved for a single channel, that channel will be listed here. See single channel authorizations for more info.

Use apps.permissions.info to look up your app's permissions on the fly.

Scopes categorized by resource

Scopes are grouped by resource type:

  • app_home - your app's direct message conversation with the installer of this app
  • team - workspace-level permissions assigned to your app
  • channel - public channels
  • group - private channels
  • mpim - multi-member direct messages
  • im - direct messages
  • user - permissions to work with or as specific users

The Permissions API describes in more detail how resources and scopes work together to enforce what your app can do.

Single channel authorizations

To request access to only a single channel, add single_channel=true to the querystring you generate for the oauth/authorize step of the OAuth flow.

Users will be asked to approve your app's requested scopes just for a single channel they choose. When the approval process is complete, the response to oauth.token or oauth.access will contain a single_channel_id field noting the channel resource.

Repeating this process multiple times on the same workspace adds additional channel grants to your app, one by one.

Use this approach with the chat:write and channels:history scopes to effectively install a bot into a single channel.

Ask for only chat:write just to post notifications into a single channel, turning chat.postMessage into a replacement for incoming webhooks.

Events API

The Events API is a central ingredient to workspace apps.

While you no longer can subscribe to "bot events," they're also irrelevant to your token type. The meaning of "workspace events" deepens and instead of being delivered through the perspective of your installing user, you receive only the events resourced to your app.

New permission-oriented app events

These new app events are available for the Events API as part of the new Permissions API.

Keep your app apprised on which scopes and resources it has access to for a specific workspace. These events are made even more useful when progressively negotiating new permissions via the apps.permissions.request method.

  • resources_added - your app was granted access to resources (like specific channels, a collection of channels, specific IM, emoji, etc.)
  • resources_removed - access that your app had to a set of resources has been removed
  • scope_granted - your app was given access to a specific scope
  • scope_denied - your app was denied access to a specific scope
  • message.app_home - Dispatches when a user sends your app a message via their direct message-like App Home interface.

Incoming webhooks

Incoming webhooks are not supported by workspace apps.

Emulate the behavior of an incoming webhook by asking for only the chat:write scope and use a [single channel authorization](# single_channel_authorization). Then build and post your messages to the target channel using chat.postMessage.


Workspace apps can't connect to the RTM API. There's no permission scope in the progressive model that grants the level of access required to connect to Slack's message server. For near real time event delivery, you must use the Events API.

How do I migrate my existing Slack app?

We're not quite ready to migrate existing Slack apps to the workspace token model. For now, consider this all part of an elaborate developer preview. We'll let you know when workspace tokens are ready for production apps.

How do I distribute my workspace app?

Install a workspace apps into any workspace using OAuth 2.0. Workspace apps cannot yet be listed in the Slack app directory.

Thanks for trying our developer preview for workspace apps! We welcome your feedback. Email us at developers@slack.com.