Go to Slack

Using OAuth 2.0

OAuth 2.0 is a protocol that lets your app request authorization to private details in a user's Slack account without getting their password.

You'll need to register your app before getting started. A registered app is assigned a unique Client ID and Client Secret which will be used in the OAuth flow. The Client Secret should not be shared.

The easiest way to enable teams to install your app is with the Add to Slack button.

Sign in with Slack is the best way to log individual team members into your application.

The OAuth Flow

Slack uses OAuth 2.0's authorization code grant flow to issue access tokens on behalf of users.

Negotiating tokens with Slack's OAuth 2.0 authorization flow

Step 1 - Authorization

Your web or mobile app should redirect users to the following URL:


The following values should be passed as GET parameters:

  • client_id - issued when you created your app (required)
  • scope - permissions to request (see below) (required)
  • redirect_uri - URL to redirect back to (see below) (optional)
  • state - unique string to be passed back upon completion (optional)
  • team - Slack team ID to attempt to restrict to (optional)

The scope parameter is a space-separated list of OAuth scopes, indicating which parts of the Slack user's account you'd like your app to be able to access. The complete list of scopes can be found here.

The state parameter should be used to avoid forgery attacks by passing in a value that's unique to the user you're authenticating and checking it when auth completes.

How the team parameter behaves

When a valid team ID is passed to team and the authenticating user is already signed in to that team, passing this parameter ensures the user will auth against that team.

If the user is not signed in yet, the user will be asked to specify a team to sign in to. That team will then be used as they complete the authorization flow, regardless of any team parameter you provided when the flow began.

If you omit the optional team parameter, the user will be allowed to choose which team they are authenticating against.

For the best user experience, use the Add to Slack button to direct users to approve your application for access and Sign in with Slack to log users in.

Step 2 - Token Issuing

If the user authorizes your app, Slack will redirect back to your specified redirect_uri with a temporary code in a code GET parameter, as well as a state parameter if you provided one in the previous step. If the states don't match, the request may have been created by a third party and you should abort the process.

Authorization codes may only be exchanged once and expire 10 minutes after issuance.

If all is well, exchange the authorization code for an access token using the oauth.access API method (method documentation).


  • client_id - issued when you created your app (required)
  • client_secret - issued when you created your app (required)
  • code - a temporary authorization code (required)
  • redirect_uri - must match the originally submitted URI (if one was sent)

You'll receive a JSON response containing an access_token (among other details):

    "access_token": "xoxp-23984754863-2348975623103",
    "scope": "read"

You can then use this token to call API methods on behalf of the user.

Please note that these access tokens do not expire.

Bot user access tokens

If your Slack app includes a bot user, upon approval the JSON response will contain an additional node containing an access token to be specifically used for your bot user, within the context of the approving team.

When you connect to rtm.start or use Web API methods on behalf of your bot user, you should use this bot user access token instead of the top-level access token granted to your application.

Here's a more verbose example JSON response including a Bot user access token:

    "access_token": "xoxp-XXXXXXXX-XXXXXXXX-XXXXX",
    "scope": "incoming-webhook,commands,bot",
    "team_name": "Team Installing Your Hook",
    "team_id": "XXXXXXXXXX",
    "incoming_webhook": {
        "url": "https://hooks.slack.com/TXXXXX/BXXXXX/XXXXXXXXXX",
        "channel": "#channel-it-will-post-to",
        "configuration_url": "https://teamname.slack.com/services/BXXXXX"

Within this response, the bot node contains two fields related to your bot user: bot_user_id and bot_access_token. Bot access tokens always begin with xoxb.

Secure your bot user tokens, as with all tokens and credentials. Do not share tokens with users or anyone else. Bot user tokens have particularly expansive capabilities not afforded to typical user tokens issued on behalf of team members.

Step 2a - Denied Requests

If the user denies your request, Slack redirects back to your redirect_uri with an error parameter.


Applications should handle this condition appropriately.

Storing tokens and credentials

Store your application's credentials and user tokens with care. Read our article on safely storing credentials.

Redirect URIs

The redirect_uri parameter is optional. If left out, Slack will redirect users to the callback URL configured in your app's settings. If provided, the redirect URL's host and port must exactly match the callback URL. The redirect URL's path must reference a subdirectory of the callback URL.

CALLBACK: http://example.com/path

GOOD: https://example.com/path
GOOD: http://example.com/path/subdir/other
BAD:  http://example.com/bar
BAD:  http://example.com/
BAD:  http://example.com:8080/path
BAD:  http://oauth.example.com:8080/path
BAD:  http://example.org

Handling Multiple Authorizations

Your application may send a user through the OAuth flow multiple times.

You can utilize this behavior to re-verify a user's identity or to retrieve a user's access token again as needed. You can also use it to upgrade an access token's OAuth scopes.

If your application requires a basic set of permissions to function, but can utilize optional permissions for advanced functionality, requesting additional scopes separately ensures that your application will have the access it needs to function without initially deterring users from approving it.

When your user is ready to indulge themselves in features requiring additional permissions, send them through the OAuth flow again, this time requesting the additional scopes you need.

For example, if your app uses Slack to sign in to your service, you may want to restrict your initial OAuth request to just the identify scope. If that same app also has an optional feature to import files from Slack using files:read, you can initiate the application approval process again, within context of the user's action, so they understand why the additional permissions are being requested.

This ensures that your app retains critical functionality (signing in to your app) without requiring optional permissions (access to the user's files) and also provides better context for the user.

Appending Scopes

When you initially send a user through the OAuth flow, you receive a token that has the set of scopes you requested. Any subsequent time(s) you send that same user through the OAuth flow, any new scopes you request will be added to that initial set.

For example, if you initially request channels:read and channels:write from a user, the initial token will have only be scoped to identify channels:read. If you send that same user through a second OAuth flow, this time requesting files:write, the resulting token will have the new scope added to the previous set: channels:read channels:write files:write.

This process can be repeated any number of times, and each scope you request is additive to the scopes you've already been awarded. It is not possible to downgrade an access token's scopes.

As you make Web API requests, a X-OAuth-Scopes HTTP header will be returned with every response indicating which scopes the calling token currently has:

X-OAuth-Scopes: identity.basic,reactions:read

Verifying user identity without installing anything

Use Sign in with Slack instead when you just want to log team members in and verify their identity without having them "install" something. If you need to ask for specific authorization scopes from a user, you can switch to the Add to Slack flow to request them. Additional scopes awarded there will be appended to the same OAuth token for that user.

Revoking tokens

If you want to dispose of an OAuth token, use auth.revoke. It works with tokens from Sign in with Slack as well as from Add to Slack.

By revoking the last token associated between your application and a team, your application will be effectively uninstalled for that team.

Revoking tokens and asking a user to authenticate again is the best way to start over and incrementally add more limited OAuth scopes to a token.