# Slack (Slack apps with OAuth v2): OAuth app setup guide

> Curated guide, updated 2026-10-30. Source: https://oauthseus.vercel.app/guides/slack

**Difficulty:** hard. Under an hour for an internal app, an afternoon to go unlisted-public, and 10 active installs plus up to ~12 weeks of Marketplace review to ship a commercial agent that reads messages _[documented s1,s4,s7]_

Creating a Slack app and running OAuth v2 is quick: a single-workspace app takes under an hour, and turning on public (unlisted) distribution so other workspaces can install it takes an afternoon. The catch for AI agents is in the API Terms. Since May 29, 2025, commercially distributed apps outside the Slack Marketplace get 1 request per minute and 15 messages per call on conversations.history and conversations.replies, and Slack calls the Marketplace the only appropriate channel for commercial distribution. Getting listed requires 10+ active installs first, then roughly 2 to 12 weeks of review.

**Your work:** 3–8 hours. **Waiting on provider:** 2–12 weeks (review depends on path).

Slack does not review internal (single-workspace) or unlisted distributed apps. Turning on public distribution is a self-serve checklist. A Marketplace listing is reviewed by the Slack Marketplace team in two parts: a preliminary review ('up to 10 business days') and a functional review ('up to 10 weeks for new submissions', 6 weeks for published apps resubmitting changes). Slack says it cannot speed review up, and resubmitting during the preliminary stage resets your place in the queue. Separately, each customer workspace may need a workspace or org admin to approve the app, and Slack sets no timeline for that.

## Launch paths

| Path | Difficulty | Your work | Provider wait |
|---|---|---|---|
| Single-workspace (internal / undistributed) app | easy | 15–60 min | None |
| Public distribution without the Marketplace (unlisted) | moderate | 3–8 hours | None |
| Slack Marketplace listing | hard | 2–5 days | 2–12 weeks |

## Do these first

1. Decide your path. Internal (customers build their own app) keeps full rate limits. Unlisted is for pilots. The Marketplace is the endgame for a commercial agent.
2. Have an agent draft an app manifest with minimal scopes and an HTTPS redirect URL, then create the app from it at https://api.slack.com/apps
3. Build the OAuth v2 flow with a state check and per-team token storage. Use the Events API rather than polling conversations.history.
4. Activate public distribution and start a pilot, aiming for 10 active workspaces.
5. In parallel, prepare the Marketplace materials (privacy policy, support page, demo video, test accounts) so you can submit as soon as you hit 10 installs, and allow up to ~12 weeks for review.

## What you're registering

**Slack app (created at api.slack.com/apps).** Your product registers one Slack app, which has one client ID and secret. Each workspace that installs it, or each Enterprise org for an org-wide install, creates its own installation and its own bot token (xoxb-). Users who authorize user scopes each get a user token (xoxp-), returned under authed_user. Your backend stores tokens keyed by team.id, or by enterprise.id when is_enterprise_install is true, plus the user ID. If you request bot scopes with `scope` and user scopes with `user_scope`, one OAuth flow can return both token types.

OAuth v2 tokens do not expire by default. They stay valid until the app is uninstalled, a user removes the authorization, the installing user is deactivated, or you call auth.revoke.

Token rotation is opt-in and cannot be turned off once enabled. With it on, access tokens (xoxe.xoxb-/xoxe.xoxp-) expire every 12 hours, refresh tokens can be used only once, and Slack enforces a limit of 2 active tokens.

Scopes add up across re-installs and cannot be downgraded without revoking the token. When you add a scope, every existing workspace has to reinstall.

The authorization code expires after 10 minutes. Apps that use more than basic scopes are uninstalled automatically if the installing user leaves the workspace.

## What you'll need

- **Slack workspace you can create apps in**: Each app is tied to one development workspace. Some workspaces block members from creating or installing apps, so a free sandbox or developer workspace you own is the safest choice. _[documented s8]_
- **HTTPS redirect URL (and HTTPS for all request URLs)**: Redirect URLs must be HTTPS and cannot contain '#'. The redirect_uri you send must match a configured Redirect URL or be a subdirectory of one. Distributed apps also need SSL on interactivity, options-load, and Events API request URLs. Socket Mode avoids needing public request URLs during development. _[documented s2,s3]_
- **OAuth v2 install flow with state parameter**: Your backend redirects users to https://slack.com/oauth/v2/authorize with client_id, scope, user_scope, redirect_uri, and state. It verifies state on return, then calls oauth.v2.access with code, client_id, and client_secret. The Marketplace requires the state check. _[documented s5]_
- **10+ active workspace installs before Marketplace submission**: Your app has to be installed and tested on at least 10 workspaces that were active in the past 28 days. Apps below this threshold are blocked from submitting. You reach it by running an unlisted pilot first. _[documented s4]_
- **Landing page, privacy policy, support page**: Your landing page needs a clear install path (an Add to Slack button) and a link to your privacy policy. The privacy policy must cover how data is used, how long it is kept, how people can access, transfer, or delete their data, and a contact email or web form. Support must be reachable without creating another account. _[documented s5]_
- **Minimal, non-restricted scopes**: Reviewers approve only scopes they can see in use. Legacy or restricted scopes and broad-access scopes are rejected, including identity.*, read, post, client, admin.*, search:read, and triggers:*. Request only the scopes needed for the methods you call. Prefer bot scopes, and use user scopes only when you must act as the user. _[documented s4]_
- **Reviewer test access and demo video**: Provide test account credentials for your own service and any third-party service, with dummy data. Reviewers cannot log in to your Slack workspace, so they must be able to install the app themselves. A short video of install, OAuth, setup, use, and uninstall speeds up the review. _[documented s4]_
- **Compliance with API Terms data restrictions (AI-specific)**: If your app is offered outside your own organization, you may not train an LLM on API data. You may not bulk export message or file data. You may not keep persistent copies, archives, indexes, or long-term stores of other organizations' API data. This rules out a 'sync everything into a vector DB' design for third-party agents. _[documented s7]_

## Steps

### 1. Create the Slack app (from scratch or from a manifest) (5–15 min, agent prepares, you submit)

1. Go to https://api.slack.com/apps and click "Create New App". The docs link to https://api.slack.com/apps?new_app=1, which opens the same dialog.
2. To build by hand, select "Blank app" and click "Continue". Current docs call this "Blank app"; older docs and tutorials say "From scratch". To configure everything at once, choose the manifest option and paste a manifest an agent wrote.
3. Enter the "App Name" and pick the "Workspace" where you will develop. You can still distribute the app to other workspaces later.
4. Click "Create".
5. Open "Basic Information" and find "App Credentials". Copy the Client ID, Client Secret, and Signing Secret into your secret store, not into code.
   - App Name: `<Your product name>` (Shown to installing users and admins. You can rename the app later.)

[Creating an app from app settings](https://docs.slack.dev/app-management/quickstart-app-settings) · [Your apps](https://api.slack.com/apps) _[documented s8]_

### 2. Add bot and user token scopes (10–30 min, agent prepares, you submit)

1. Open "OAuth & Permissions" and scroll to "Scopes".
2. Under "Bot Token Scopes", click "Add an OAuth Scope" for each permission the bot needs. Typical agent scopes are app_mentions:read, chat:write, im:history, and channels:history.
3. Add scopes under "User Token Scopes" only when the agent must act as a specific user, such as reading that user's DMs or posting as them.
4. You can uncheck a scope to make it optional, so users can decline it. If you do, handle missing_scope errors gracefully.
5. Keep the list minimal. Scopes add up across re-installs, and you cannot remove a scope from an issued token without revoking the token.

[Scopes reference](https://docs.slack.dev/reference/scopes) · [Installing with OAuth](https://docs.slack.dev/authentication/installing-with-oauth) _[documented s8,s2]_

### 3. Register HTTPS redirect URLs (5–15 min, agent prepares, you submit)

1. On "OAuth & Permissions", go to "Redirect URLs" and click "Add New Redirect URL".
2. Enter an HTTPS URL such as https://app.example.com/slack/oauth/callback. http:// URLs and URLs with '#' are rejected.
3. Click "Add", then "Save URLs".
4. For local development, use an HTTPS tunnel URL (ngrok or similar), or a separate dev app with its own redirect URL.
5. If you register more than one URL, send the same redirect_uri in both the authorize step and the oauth.v2.access step. Otherwise you get bad_redirect_uri.
   - Redirect URL: `https://<your-domain>/slack/oauth/callback` (Must be HTTPS. The redirect_uri you send can be this URL or a subdirectory of it.)

[Installing with OAuth: request scopes](https://docs.slack.dev/authentication/installing-with-oauth#asking) _[documented s2]_

### 4. Implement the OAuth v2 install flow and token storage (1–4 hours, agent can do)

1. Redirect users to https://slack.com/oauth/v2/authorize. Include client_id, scope (bot scopes, comma-separated), user_scope (if needed), redirect_uri, and an unguessable state value.
2. In the callback, check that state matches. Treat a mismatch as forgery. Read the code, which expires after 10 minutes.
3. Exchange the code by POSTing code, client_id, and client_secret to https://slack.com/api/oauth.v2.access.
4. Store access_token (xoxb-) and, if present, authed_user.access_token (xoxp-). Key them by team.id, or by enterprise.id when is_enterprise_install is true. Don't assume the team you passed in the 'team' parameter is where the app got installed.
5. Recommended for enterprise customers: call team.info and users.info to check the user connected with their corporate account.
6. Subscribe to app_uninstalled and tokens_revoked so you can delete tokens when access is removed.

[Installing with OAuth](https://docs.slack.dev/authentication/installing-with-oauth) · [oauth.v2.access](https://docs.slack.dev/reference/methods/oauth.v2.access) _[documented s2]_

### 5. (Optional) Turn on token rotation (30–120 min, agent prepares, you submit)

1. Test the refresh logic in a dev app first. Once on, rotation cannot be turned off, and tokens expire every 12 hours.
2. For unpublished apps, turn on token rotation under "OAuth & Permissions". For Marketplace apps, use "Published App Settings". In a manifest, set settings.token_rotation_enabled: true.
3. Refresh by calling oauth.v2.access with grant_type=refresh_token, refresh_token, client_id, and client_secret.
4. Save the new refresh_token every time. Refresh tokens are single-use, and only 2 active tokens are allowed.
5. To convert existing long-lived tokens, call oauth.v2.exchange once per token.

[Using token rotation](https://docs.slack.dev/authentication/using-token-rotation) _[documented s6]_

### 6. Install to your own workspace and test (5–15 min, you)

1. At the top of "OAuth & Permissions" (or under "Install App"), click "Install to Workspace", then "Allow".
2. Copy the Bot User OAuth Token from "OAuth Tokens". This is enough for internal apps.
3. Invite the bot to a test channel (/invite @YourApp) and test your API calls.
4. Whenever you add scopes or events that need scopes, click "Reinstall to Workspace".

[Creating an app: installing and authorizing](https://docs.slack.dev/app-management/quickstart-app-settings#installing) _[documented s8]_

### 7. Complete the Manage Distribution checklist and activate public distribution (10–30 min, you)

1. Open "Manage Distribution" in the sidebar under Settings and scroll to "Share Your App with Other Workspaces".
2. Work through the checklist. Make sure "Add OAuth Redirect URLs" is complete, which needs at least one HTTPS redirect URL. Then open "Remove Hard Coded Information" and tick the box confirming you have removed hard-coded workspace tokens and IDs.
3. Click "Activate Public Distribution".
4. Copy the shareable install URL or the embeddable "Add to Slack" button and put it on your site. You also get the slack-app-id meta tag.
5. Note: "Deactivate Public Distribution" uninstalls the app from every workspace except the original one.

[App lifecycle & distribution](https://docs.slack.dev/app-management/distribution) _[documented s3,s10]_

### 8. Run a pilot to reach 10+ active workspace installs (1–8 weeks, you)

1. Share the Add to Slack link with pilot customers. Some workspaces restrict installs to admins, use app approval requests, or allow only Marketplace-listed apps.
2. Tell pilot admins exactly which scopes you request and why. Admins decide based on the permission list.
3. Remember that unlisted commercial installs created after May 29, 2025 get 1 request per minute and 15 objects on conversations.history and conversations.replies. Design the pilot around the Events API (message events) instead of polling history.
4. Test install, onboarding, use, and uninstall on workspaces other than your dev workspace.

[Distribution: enabling admin approval](https://docs.slack.dev/app-management/distribution#approval) · [Rate limit changes for non-Marketplace apps](https://docs.slack.dev/changelog/2025/05/29/rate-limit-changes-for-non-marketplace-apps) _[documented s4,s3]_

### 9. Submit to the Slack Marketplace (1–3 days, agent prepares, you submit)

1. Before you submit, remove test slash commands and any scopes for features you haven't built yet.
2. In app settings, open "Submit to the Slack Marketplace". Fill in the listing information, give a reason for each scope, and add supplementary testing information, then fix any issues the automated checks flag.
3. Provide reviewer test accounts with dummy data under "Test account details". Reviewers must be able to install the app themselves.
4. Attach a short video demo of the full install and OAuth flow, setup, use, and uninstall.
5. Check the estimated review time shown on the submission page. Slack will not speed review up for a launch date.

[Slack Marketplace review process](https://docs.slack.dev/slack-marketplace/slack-marketplace-review-guide) · [Submission guidelines and requirements](https://docs.slack.dev/slack-marketplace/slack-marketplace-app-guidelines-and-requirements) _[documented s4]_

### 10. Respond to preliminary and functional review, then publish (2–8 hours, agent prepares, you submit)

1. Preliminary review covers your listing, links, scope reasons, and whether reviewers can install. Feedback takes up to 10 business days, and each resubmission at this stage resets your place in the queue.
2. Functional review: a reviewer installs and tests the app. Feedback takes up to 10 weeks for new apps. Resubmitting does not reset the queue once your app is assigned to a reviewer.
3. Feedback arrives in the submission flow and by email. Address every point before you resubmit.
4. Once approved, publish whenever you like. After publishing, the live config is locked. Use a separate staging app for future changes, and get scope changes approved before you add them to install links, or installs fail with unapproved_scope.

[The review process](https://docs.slack.dev/slack-marketplace/slack-marketplace-review-guide#review) _[documented s4]_

## Blockers

- **Agent can barely read history: 1 request/min, 15 messages** (high). Symptom: conversations.history or conversations.replies return ratelimited almost at once, and the limit maxes out at 15, on new installs of an app you distribute outside the Marketplace. Fix: This is the May 29, 2025 policy for commercially distributed non-Marketplace apps. Options:
- List the app on the Marketplace.
- Use the Events API (message events) to receive messages as they happen instead of polling history.
- Deploy as an internal customer-built app inside the customer's own workspace, which keeps 50+ requests per minute and 1,000 objects per call.
Installs that existed before the change are not affected. _[documented s1]_
- **Marketplace submission blocked: fewer than 10 active workspaces** (high). Symptom: You can't submit to the Slack Marketplace. Fix: Run an unlisted pilot until at least 10 workspaces have been active in the past 28 days and have tested the app. Plan for the reduced history limits during the pilot. _[documented s4]_
- **invalid_team_for_non_distributed_app** (medium). Symptom: Users from another workspace hit an error when they open your install link. Fix: Turn on public distribution under Manage Distribution, then click Activate Public Distribution. Without it, only the app's home workspace can install the app, plus other workspaces in the same Enterprise org if org-wide install is enabled. _[documented s2]_
- **bad_redirect_uri / redirect rejected** (medium). Symptom: OAuth fails at the authorize step or the oauth.v2.access step. Fix: Use HTTPS with no '#'. Make sure redirect_uri matches a configured Redirect URL or is a subdirectory of one. Send the identical redirect_uri in both the authorize step and the oauth.v2.access step. _[documented s2]_
- **Workspace only allows Marketplace apps or requires admin approval** (medium). Symptom: A user can't install the app, or sees a 'request to install' flow that sits waiting for an admin. Fix: Give admins a short scope justification and a security or privacy summary. Trim the scopes you request. For customers that only allow listed apps, the Marketplace is the only route, or they build an internal app themselves. _[documented s3]_
- **unapproved_scope after publishing** (medium). Symptom: New installs of your Marketplace app fail after you added a scope to the install link. Fix: The published config is locked. Submit the scope change for review, using a staging app and a demo video, publish once approved, and only then update your OAuth URLs. _[documented s4]_
- **Tokens die after 12 hours (rotation enabled)** (medium). Symptom: API calls fail with expired-token errors after about 12 hours, or the second refresh fails. Fix: Refresh before expires_in runs out, and save the new refresh_token from every response because they are single-use. If you refresh repeatedly, remember only 2 active tokens are allowed. Rotation cannot be turned off, so test in a dev app first. _[documented s6]_
- **App silently uninstalled when the installer leaves** (low). Symptom: A workspace's tokens stop working after the employee who installed the app leaves or becomes a guest. Fix: Handle the app_uninstalled and tokens_revoked events, and prompt another user in that workspace to reinstall. Add app collaborators so the dev-workspace app survives staff turnover. _[documented s3]_

## Agent vs. you

**An agent can:**
- Draft the full app manifest (JSON/YAML), including minimal bot and user scopes, redirect URLs, event subscriptions, org_deploy_enabled, and token_rotation_enabled
- Work out the minimum scope set from the API methods and events your product calls, and write a justification for each scope for admins and Marketplace reviewers
- Implement the OAuth v2 flow (authorize redirect, state check, oauth.v2.access exchange), per-team token storage, and refresh logic, with Bolt or by hand
- Re-architect history polling around the Events API to work within the non-Marketplace rate limits
- Draft the privacy policy, support page, landing page copy, and Marketplace listing text, then check them against the guidelines
- Check the redirect URL is HTTPS and has no '#', and find hard-coded workspace tokens or IDs in the codebase before you tick 'Remove Hard Coded Information'
- Triage Marketplace review feedback and make the code fixes

**You must:**
- Sign in to api.slack.com and create the app in a workspace you control
- Click 'Install to Workspace' and 'Allow' as the installing user
- Tick the 'Remove Hard Coded Information' attestation and click 'Activate Public Distribution'
- Recruit 10+ active pilot workspaces and work with their admins on app approval
- Provide reviewer test credentials, record the demo video, submit to the Marketplace, and choose when to publish
- Decide, and accept legal responsibility for, compliance with the Slack API Terms, including no LLM training and no persistent indexes of other organizations' data

## What we couldn't confirm

- Slack gives only maximum review times ('up to 10 business days', 'up to 10 weeks'). No official minimum or median is published. The submission page shows a live estimate we could not see without signing in.
- We did not confirm the current exact labels of the manifest create option and the token rotation toggle, or the exact sub-path of the Marketplace submission page. The pointer for those steps falls back to generic app-settings URLs.
- The Manage Distribution checklist items ('Add OAuth Redirect URLs', 'Remove Hard Coded Information') come from community and vendor docs, not current official text.
- We could not determine how Slack decides an unlisted app is 'commercially distributed' (and so rate limited) rather than a pilot. The changelog says new non-Marketplace installs get the reduced limits.
- The Real-time Search API was described as limited beta 'with select partners' on the May 2025 page. Its availability as of 2026-10-30 was not verified.
- The time customer workspace admins take to approve is unknown and varies by organization.

## Verification log

- 2026-10-30 · doc-review · **corrected**: Rate limits for conversations.history and conversations.replies on non-Marketplace apps. Much common advice still assumes Tier 3 (about 50 requests per minute, limit up to 1,000) for any distributed app. Since May 29, 2025, commercially distributed non-Marketplace apps get Tier 1: 1 request per minute and a maximum and default limit of 15 objects, for new apps and new installs. Existing installs, Marketplace apps, and internal customer-built apps are unaffected. The page was later updated to clarify that internal apps are exempt.
- 2026-10-30 · doc-review · **corrected**: Is unlisted public distribution an acceptable long-term commercial channel?. Older guides present 'Activate Public Distribution' plus an Add to Slack button as a complete launch path. The May 2025 API Terms update says the Marketplace is the only appropriate channel for commercially distributed apps, and that unlisted apps are for development and testing.
- 2026-10-30 · doc-review · **confirmed**: Marketplace review prerequisites and timeline. Prerequisite: 10+ active workspace installs, active within 28 days. Preliminary review takes up to 10 business days, and resubmitting resets the queue. Functional review takes up to 10 weeks for new apps and 6 weeks for updates. Slack cannot speed review up.
- 2026-10-30 · doc-review · **corrected**: Create-app dialog option label. Many tutorials say to choose 'From scratch'. The current official quickstart says to select 'Blank app' and click 'Continue'. The pointer targets 'Blank app'.
- 2026-10-30 · doc-review · **confirmed**: Token expiry and rotation. OAuth v2 tokens do not expire unless rotation is enabled. Rotation gives 12-hour tokens, single-use refresh tokens, and a 2-active-token limit, and it cannot be disabled once on.
- 2026-10-30 · doc-review · **confirmed**: API Terms restrictions relevant to AI agents. Third-party apps may not train LLMs on API data, bulk export message or file data, or create persistent copies or indexes of other organizations' API data.
- 2026-10-30 · doc-review · **confirmed**: HTTPS requirement for redirect URLs. Both redirect_uri and configured Redirect URLs must use HTTPS and cannot contain '#'. Distributed apps also need SSL on all request URLs.
- 2026-10-30 · http-probe · **confirmed**: Automated: developer console (https://api.slack.com/apps). Loaded: "Slack API: Applications | Slack".
- 2026-10-30 · http-probe · **confirmed**: Automated: OIDC discovery document (https://slack.com/.well-known/openid-configuration). Discovery document found. authorization_endpoint=https://slack.com/openid/connect/authorize; token_endpoint=https://slack.com/api/openid.connect.token; PKCE methods: not advertised; scopes: openid, profile, email.
- 2026-10-30 · http-probe · **confirmed**: Automated: authorize endpoint with a fake client_id (https://slack.com/oauth/v2/authorize). Endpoint answered HTTP 200.
- 2026-10-30 · doc-review · **confirmed**: Automated: 32 quotes re-fetched and matched against their cited pages. 32 of 32 quotes found verbatim in the live page HTML.  9/9 source URLs returned HTTP 200.

## Sources

- s1: [Rate limit changes for non-Marketplace apps (May 29, 2025)](https://docs.slack.dev/changelog/2025/05/29/rate-limit-changes-for-non-marketplace-apps) (official-blog, accessed 2026-10-30)
- s2: [Installing via OAuth authorization code flow](https://docs.slack.dev/authentication/installing-with-oauth) (official-docs, accessed 2026-10-30)
- s3: [App lifecycle & distribution](https://docs.slack.dev/app-management/distribution) (official-docs, accessed 2026-10-30)
- s4: [Slack Marketplace review process](https://docs.slack.dev/slack-marketplace/slack-marketplace-review-guide) (official-docs, accessed 2026-10-30)
- s5: [Submission guidelines and requirements](https://docs.slack.dev/slack-marketplace/slack-marketplace-app-guidelines-and-requirements) (official-policy, accessed 2026-10-30)
- s6: [Using token rotation](https://docs.slack.dev/authentication/using-token-rotation) (official-docs, accessed 2026-10-30)
- s7: [Slack API Terms of Service](https://slack.com/terms-of-service/api) (official-policy, accessed 2026-10-30)
- s8: [Creating an app from app settings](https://docs.slack.dev/app-management/quickstart-app-settings) (official-docs, accessed 2026-10-30)
- s10: [Panther Docs: Slack Logs (shows Manage Distribution checklist labels)](https://docs.panther.com/data-onboarding/supported-logs/slack) (community, accessed 2026-10-30)
- p1: [Live probe (console): Loaded: "Slack API: Applications | Slack".](https://api.slack.com/apps) (probe, accessed 2026-10-30)
- p2: [Live probe (oidc-discovery): Discovery document found. authorization_endpoint=https://slack.com/openid/connect/authorize; token_e](https://slack.com/.well-known/openid-configuration) (probe, accessed 2026-10-30)
- p3: [Live probe (authorize-endpoint): Endpoint answered HTTP 200.](https://slack.com/oauth/v2/authorize) (probe, accessed 2026-10-30)

Evidence tags: tested = exercised live; documented = official source, quote checked; inferred = reasoning; unverified = unconfirmed.