> ## Documentation Index
> Fetch the complete documentation index at: https://docs.r28.ai/charter/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Charter works for any HTTP API, including the user's own. The packs are examples of the result, not the limit: an API with no pack is declared the same way, following https://raw.githubusercontent.com/r28ai/charter/main/docs/.mintlify/skills/declaring-charter-tools/SKILL.md.
> Charter is for agents that act in customers' accounts: every call is checked field by field before it's sent, the app says whose account each call is for, and the same declarations list what each tool can reach. https://docs.r28.ai/charter/llms.txt says what it is and lists every page.

# Register a Slack app

> The Slack app your users' workspaces install: a redirect URL, the pack's bot scopes, and the client ID and secret the flow needs, with a screenshot for each screen.

Before your users can connect their workspaces, Slack needs an app that you own
and they install. You register it once, it takes about five minutes, and every
workspace that connects afterwards goes through the same app.

Only connecting your own workspace? [Set up Slack](https://docs.r28.ai/charter/charter/auth/setup/slack.md) is
shorter: an app from a prefilled manifest and the bot token it shows you.

Every Slack link below opens in a new tab, so this page stays where you left it.

**1. Create the app**

Open [api.slack.com/apps](https://api.slack.com/apps) and click **Create an App**.

![Slack's Your Apps page, with a green Create an App button in the middle.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/01-your-apps.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=e2730a7d4f11aac733b9e7be1dcca96e)

Choose **From scratch**.

![The Create an app dialog, offering From a manifest and From scratch.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/02-from-scratch.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=09907ddcbbab8152fc1984cfd08aa7c8)

Name the app and pick the workspace to develop it in, then click **Create App**.
Your users see this name on the consent screen and on every message the app
posts. You can rename the app later, but you can't move it to another workspace.

![The Name app & choose workspace dialog, with Example App as the app name and a workspace selected.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/03-name-app.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=c46bddd6f7153ade01d18b3f4c7f5679)

> [!TIP]
>
> **Prefer a manifest?** Use the one on [Set up Slack](https://docs.r28.ai/charter/charter/auth/setup/slack.md),
> which already has the pack's scopes, and add your callback under `oauth_config`:
> `"redirect_urls": ["https://app.example.com/oauth/slack/callback"]`. That does
> steps 2 and 3 for you.

**2. Add your redirect URL**

In the sidebar, open **OAuth & Permissions**. Under **Redirect URLs**, click
**Add New Redirect URL**, enter your app's callback route, click **Add**, then
**Save URLs**.

![The Redirect URLs section of OAuth & Permissions, listing https://app.example.com/oauth/slack/callback, with Add New Redirect URL and Save URLs buttons.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/04-redirect-urls.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=1d840a5cf9e91b25dfa4f5c55f17a143)

Slack only sends the browser back to a URL on this list. Register the exact
`redirect_uri` your flow sends, scheme and path included.

**3. Add the bot scopes**

On the same page, scroll to **Scopes**. Under **Bot Token Scopes**, click
**Add an OAuth Scope** once for each scope your tools need.

![Bot Token Scopes listing channels:history, chat:write and users:read, each with its description, and an Add an OAuth Scope button.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/05-scopes.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=e9615a27aef2e628712a031149cc2340)

The pack's tools declare nineteen scopes:

```text slack scopes theme={null}
channels:history  channels:join  channels:manage  channels:read
channels:write.invites  chat:write  groups:history  groups:read
groups:write  groups:write.invites  im:history  im:read  im:write
mpim:history  mpim:read  mpim:write  reactions:read  reactions:write
users:read
```

[`scopes_for(slack.TOOLS)`](https://docs.r28.ai/charter/charter/reference/oauth#scopes_for) returns the same list,
so if you only hand out some of the tools, ask it for theirs and leave the rest
off. The link your app builds asks for scopes too, and Slack refuses to grant a
scope the app hasn't been given here.

**4. Copy the client ID and secret**

Open **Basic Information** and scroll to **App Credentials**. Copy the
**Client ID**, then click **Show** next to **Client Secret** and copy that too.
The signing secret and verification token are for events, which the flow
doesn't use.

![Basic Information's App Credentials: App ID and Client ID (hidden), Client Secret and Signing Secret masked with Show and Regenerate buttons.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/06-app-credentials.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=1faf226b3a8a579610d0e19d53eaa6de)

```bash theme={null}
export SLACK_CLIENT_ID=1234567890.1234567890
export SLACK_CLIENT_SECRET=...
```

Keep the secret on your server. Anyone who has it can complete a grant as your
app.

**5. Turn on public distribution**

Until you do this, only the workspace you picked in step 1 can install the app.
Open **Manage Distribution**, work through its checklist (it checks that the
redirect URL uses HTTPS and that nothing is hard-coded), then click
**Activate Public Distribution**.

Distributing the app isn't the same as listing it in the Slack Marketplace.
Workspaces install it from your own link, and you only need Slack's review if
you also want a Marketplace listing.

**6. Connect a workspace**

Your app's "Connect Slack" button opens the link that
[`flow.authorize()`](https://docs.r28.ai/charter/charter/reference/oauth#oauth2flow-authorize) builds. The user
picks a workspace, reviews what the app can see and do, and clicks **Allow**.

![Slack's consent screen: a workspace picker, what Example App can view and the actions it can take, and Cancel and Allow buttons.](https://mintcdn.com/r28-ai-inc/xppyW240SSmPx0hQ/charter/images/setup/slack/07-consent.webp?fit=max\&auto=format\&n=xppyW240SSmPx0hQ\&q=85\&s=0b317c7bd830c6a4830d35f3f594342d)

```python slack_connect.py theme={null}
from charter.auth import OAuth2Flow

flow = OAuth2Flow(
    SLACK,  # the server constant, from /auth/providers/slack
    client_id=os.environ["SLACK_CLIENT_ID"],
    client_secret=os.environ["SLACK_CLIENT_SECRET"],
    redirect_uri="https://app.example.com/oauth/slack/callback",
)
request = flow.authorize(SLACK_SCOPES)  # request.url is the link to open

# At the callback, after checking state:
grant = await flow.exchange(code, code_verifier=verifier, expect_refresh_token=False)
# grant.access_token is that workspace's xoxb- bot token: store it against the user.
```

`expect_refresh_token=False` is there because an app with token rotation off
gets a bot token that never expires and no refresh token comes with it.
[Slack's provider page](https://docs.r28.ai/charter/charter/auth/providers/slack.md#two-shapes-of-slack-app) covers
turning rotation on and what changes when you do.

## When it does not work

> **“redirect\_uri did not match any configured URIs”**
>
> The flow sent a `redirect_uri` that isn't on the app's list. Add it under
> **OAuth & Permissions → Redirect URLs** exactly as the flow sends it, then
> **Save URLs**. Forgetting that last click is the usual cause.

> **A workspace other than yours can't install the app**
>
> Public distribution is off, so only the development workspace can install.
> See step 5.

> **“invalid\_scope”, or missing\_scope from a tool later**
>
> The link asked for a scope the app doesn't have, or a tool needs a scope the
> grant doesn't cover. Add it under **Bot Token Scopes**, then have that
> workspace connect again. A grant only covers the scopes it was issued for.

> **not\_in\_channel**
>
> The bot reads only the channels it has been invited to. In the channel, type
> `/invite @your-app`.

## Related

* [Slack](https://docs.r28.ai/charter/charter/auth/providers/slack.md) — the server constant, both token shapes, and refresh under rotation
* [Getting the grant](https://docs.r28.ai/charter/charter/auth/oauth-flow.md) — the two routes, `state` and PKCE, inside your app
* [Every pack](https://docs.r28.ai/charter/charter/auth/your-users.md) — what each pack's users connect with, and what you store
* [Set up Slack](https://docs.r28.ai/charter/charter/auth/setup/slack.md) — your own workspace, from a manifest


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.