Go to Slack

Working with workspace tokens

Developer preview

Welcome to the workspace token-based Slack app developer preview, still under active development.

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

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 team wouldn't install your bot user because it asks for too many permissions.
  • The user who installed your app left the team 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 team.
  • 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 token-based Slack apps operate on a new permission model that is both more team-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 team'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 teams.

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 team — 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 team. 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 team

When these new kinds of Slack apps are first installed, it's done so for an entire team. Installation is just a fact. An app is installed or it's not and some member of the team installed it, but that team 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 team.

One access token per team

All of these team 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 team.

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 teams. They're just for your own development and exploration now.
  • SDKs, libraries, and tools you are familiar with may outright just not work with team-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:

  • Impersonate users — your app can't post as as team member, nor award reacji on behalf of a user. Your app is your app and only your app. (Some impersonation options will be made available at a later date.)
  • 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 token-based Slack app

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

Install your app

Once created, install your new app onto your team. 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 "Access a private conversation with you". That sounds fantastic. Approve it.

Essentially, all workspace token-based Slack 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 team 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 token-based 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 team 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 messages.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 token-based apps

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

  • Installing your app to your own team through the guided App Management UI
    • This is the process we detailed in the "Hello world" example above
  • Installing your app to your own team 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 token-based Slack 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, team 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.token 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 team.

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 team 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.

Important: If your app is distributed to other teams and/or you want to obtain tokens via OAuth 2.0, you'll need to use the oauth.token API method instead of oauth.access on the part of the OAuth 2.0 flow where you exchange the code for an access token.

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-1234567890-12345678901-12345678901-52c0d150863a591bfcedf0644c4b5ce2",
    "token_type": "app",
    "app_id": "A01234567",
    "app_user_id": "U0B234567",
    "installer_user_id": "U12345678",
    "authorizing_user_id": "W0HTT3Q0G",
    "team_name": "Subarachnoid Workspace",
    "team_id": "T01234567",
    "permissions": [
            "scopes": [
            "resource_type": "im",
            "resource_id": "D1AB23CDE"
            "scopes": [
            "resource_type": "channel",
            "resource_id": 0

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 workspace.
  • 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 team 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.
  • team_name - This is what the team calls itself.
  • team_id - This is the unique ID for the team.
  • permissions - Here's where we communicate all the details of your permissions. It's an array of the different permissions you have. Each array contains:
    • scopes - the OAuth scopes associated with this permission, further scoped by the resource_id.
    • resource_type - the type of resource this permission describes: like a channel, a im, etc.
    • resource_id - the unique ID correlated to the resource_type — the direct message ID for resources of type im, the channel ID for a public channel, etc.

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

Seek further answers in our documentation for the Permissions API.


New 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.

Events API

The Events API is a central ingredient to workspace token-based apps.

While you no longer can subscribe to "bot events," they're also irrelevant to your token type. The meaning of "team 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 team. 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

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.

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