---
title: Slack | Keycard
description: Send messages and interact with Slack workspaces
---

[Slack developer console](https://api.slack.com/apps)[OAuth setup guide](https://api.slack.com/authentication/oauth-v2)[API docs](https://api.slack.com/docs)

Adding Slack provisions a resource (the upstream Slack API at `https://slack.com/api`, with default scopes pre-set) and a provider for Slack’s OAuth issuer - auto-provisioned on first install, or reused if you already connected another Slack resource.

Your application calls Keycard’s [token-exchange endpoint](/sdk/oauth/index.md) with the user’s identity, gets back a token scoped to this resource, and uses it to call Slack directly. Identity, [policy](/admin/access-policies/index.md), and audit log apply to every exchange - the OAuth client secret stays inside Keycard. Each exchange is recorded in the audit log with the user identity, the resource accessed, and the policy decision.

## Scopes

SCOPES

OAuth permissions Keycard requests on install. Override or add scopes in Console.

- chat:write

  default

- channels:read

  default

- users:read

  default

- app\_mentions:read

- assistant:write

- bookmarks:read

- bookmarks:write

- calls:read

- calls:write

- canvases:read

- canvases:write

- channels:history

- channels:join

- channels:manage

- channels:write.invites

- channels:write.topic

- chat:write.customize

- chat:write.public

- commands

- conversations.connect:manage

- conversations.connect:read

- conversations.connect:write

- datastore:read

- datastore:write

- dnd:read

- emoji:read

- files:read

- files:write

- groups:history

- groups:read

- groups:write

- groups:write.invites

- groups:write.topic

- im:history

- im:read

- im:write

- im:write.topic

- incoming-webhook

- links:read

- links:write

- links.embed:write

- lists:read

- lists:write

- metadata.message:read

- mpim:history

- mpim:read

- mpim:write.topic

- pins:read

- pins:write

- reactions:read

- reactions:write

- reminders:read

- reminders:write

- remote\_files:read

- remote\_files:share

- remote\_files:write

- search:read.enterprise

- search:read.files

- search:read.public

- search:read.private

- search:read.mpim

- search:read.im

- search:read.users

- team:read

- team.billing:read

- team.preferences:read

- tokens.basic

- triggers:read

- triggers:write

- usergroups:read

- usergroups:write

- users:read.email

- users:write

- users.profile:read

- workflows.templates:read

- workflows.templates:write

Show all 76 scopes  Show defaults only

Note

The Slack verification endpoint uses `POST` rather than `GET`. Keycard runs this verification automatically when you add the resource.

## Use Slack from your code

USE FROM CODE

Call Slack from your application with a Keycard-issued token scoped to this resource.

After installing Slack, your application exchanges a Keycard-issued access token for a token scoped to this resource. Pass the user’s access token as the `subject_token`.

- [Python](#tab-panel-126)
- [TypeScript](#tab-panel-127)

```
from keycardai.oauth import Client, BasicAuth, TokenType
import requests


# Exchange the user's Keycard token for a Slack token.
with Client(
    "https://<zone-id>.keycard.cloud",
    auth=BasicAuth("<your-client-id>", "<your-client-secret>"),
) as client:
    response = client.exchange_token(
        subject_token=user_access_token,
        subject_token_type=TokenType.ACCESS_TOKEN,
        resource="https://slack.com/api",
    )


# Call Slack directly with the exchanged token.
r = requests.get(
    "https://slack.com/api/<endpoint>",
    headers={"Authorization": f"Bearer {response.access_token}"},
)
```

```
import { TokenExchangeClient } from "@keycardai/oauth/tokenExchange";


const client = new TokenExchangeClient("https://<zone-id>.keycard.cloud", {
  clientId: "<your-client-id>",
  clientSecret: "<your-client-secret>",
});


const response = await client.exchangeToken({
  subjectToken: userAccessToken,
  resource: "https://slack.com/api",
});


// Call Slack directly with the exchanged token.
const res = await fetch("https://slack.com/api/<endpoint>", {
  headers: { Authorization: `Bearer ${response.accessToken}` },
});
```

See the [OAuth SDK → Token Exchange](/sdk/oauth/#token-exchange/index.md) reference for the full client API.

## Setup

SETUP

Register your OAuth credentials with Keycard so the resource can issue tokens.

### Create a Slack app

1. Go to the [Slack API Dashboard](https://api.slack.com/apps)
2. Click **Create New App** → **From scratch**
3. Enter an app name and select the workspace you want to develop against
4. Click **Create App**

### Set the redirect URL

1. In **OAuth & Permissions**, scroll to **Redirect URLs**
2. Click **Add New Redirect URL**
3. Enter the redirect URI provided by Keycard
4. Click **Save URLs**

### Get credentials

1. In **Basic Information**, scroll to **App Credentials**
2. Note the **Client ID** and **Client Secret**

### Register in Keycard

1. Open [Keycard Console](https://console.keycard.ai) → your zone → **Resources**

2. Click **Explore Resources**

3. Find and click **Slack** in the catalog

4. In the configuration dialog:

   - Enter the **Client ID** and **Client Secret** from your Slack app
   - Review the **User scopes** - the defaults (`chat:write`, `channels:read`, `users:read`) are pre-populated

5. Click **Add Slack API**

### Configure the Slack provider

After adding the resource, go to the **Slack provider** settings and expand **Advanced options**. Slack’s OAuth v2 API uses non-standard parameter names, so you must set the following values:

| Setting           | Value                      |
| ----------------- | -------------------------- |
| Scope Parameter   | `user_scope`               |
| Scope Separator   | `,` (comma)                |
| Access Token Path | `authed_user.access_token` |

Note

These values are defined in the catalog and should be set automatically when adding Slack from the catalog. If they are not pre-populated, set them manually - without them, token exchange will fail or return a bot token instead of a user token.

## Troubleshooting

TROUBLESHOOTING

Common errors when wiring Slack into your zone.

Error: invalid\_auth

The token is invalid or has been revoked. Reconnect the provider in Keycard Console. If the issue persists, check that the app is still installed in the workspace.

Error: missing\_scope

The token doesn’t have the required scopes. Verify the scopes configured in both Slack’s app settings and your Keycard resource match. You may need to reinstall the app to pick up new scopes.

Error: not\_allowed\_token\_type

You may be using a bot token where a user token is expected, or vice versa. Check the scope type (Bot vs User) in your Slack app configuration.

## Related

RELATED

- [Catalog overview](/admin/catalog/index.md) - browse other API and MCP servers
- [Access policies](/admin/access-policies/index.md) - control who can use Slack
- [Identity providers](/admin/identity-providers/index.md) - control who can sign in

[PreviousSentry](/admin/catalog/api-servers/sentry/index.md)
