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

# Slack

> Connect a Slack workspace to Serval to power your Slack help desk, deliver approval requests by DM, sync users and user groups, and run workflows against the Slack Web API.

## About Slack

The Slack integration connects a single Slack workspace to your Serval team. It powers Serval's Slack help desk surfaces (tickets from channel messages and DMs, an @mention bot, an App Home tab, an AI assistant thread surface, a "Create a Ticket" message shortcut, and a slash command), delivers approval requests by direct message, and keeps your workspace's users and user groups synced into Serval.

A separate [**Slack Admin**](/sections/integrations/slack-admin) integration (Enterprise Grid org-admin, user tokens) is documented on its own page and is not covered here.

**Authentication:** Slack-app OAuth v2 install with bot scopes - either Serval's managed Slack app (one click, recommended) or your own white-label Slack app created from a Serval-generated manifest.

**Data sync:** Scheduled background syncs ingest workspace users and user groups on Serval's standard sync schedule; a manual sync from the UI forces a full re-sync. Workflow calls to Slack run on demand through Serval's proxy, and rate-limited responses are retried automatically with exponential backoff.

## What the Slack integration enables

| Capability                      | Description                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Help desk in Slack              | Create tickets from channel messages and DMs, respond via an @mention bot, browse the App Home tab, use Slack's AI assistant thread surface, run the "Create a Ticket" message shortcut, or use a slash command named after your app.                                                                                                                                                          |
| Approval requests via DM        | Serval opens a direct message with each approver to deliver approval requests (requires the `im:write` bot scope).                                                                                                                                                                                                                                                                             |
| Channel management workflows    | Create, rename, list, and search Slack channels - including public, private, private-plus-invite, and interest-group channel creation.                                                                                                                                                                                                                                                         |
| User management workflows       | Manage Slack user access and workspace membership: add or remove users from channels, invite, deactivate, or remove users (the invite, deactivate, and remove workflows run against the separate Slack Admin integration), and look up users and user groups. Workflows that change membership default to requiring the workflow installer's approval; read-only lookups run without approval. |
| Enterprise Grid admin workflows | Manage Slack using the Admin API for Enterprise Grid organizations - these run against the separate Slack Admin integration, documented on its own page.                                                                                                                                                                                                                                       |
| User and user-group sync        | Scheduled ingestion of workspace users and user groups. Group sync is a catalog-only resource sync, for reference and tagging - mentioning a synced group from Serval renders as a proper group mention in Slack. Group membership is managed in Slack, not Serval.                                                                                                                            |
| Full Slack Web API in workflows | A typed API request action covers the Slack Web API. Slack is method-based rather than REST - you supply the method name (for example `chat.postMessage` or `users.lookupByEmail`) - with cursor-based pagination supported. Organization-admin methods are the one exception: they go through the separate Slack Admin integration.                                                           |

Anything defined in the [Slack API](https://api.slack.com/methods) can be accessed through Serval, with one exception: organization-admin methods require the separate Slack Admin integration. A few of the catalog workflows above - name-based channel and user lookups, and inviting, deactivating, or removing workspace members - also connect through that companion Slack Admin integration rather than this one.

## Get your credentials

There are two ways to connect, and only one of them needs any setup on Slack's side.

<Tabs>
  <Tab title="Serval's Slack app (recommended)">
    No provider-side setup and no credentials are required. Choose **Use Serval's Slack App** - the option marked **Recommended** ("Connect instantly using Serval's managed Slack application.") - and Serval walks you through a standard Slack authorization screen. Skip ahead to **Connect in Serval**.

    <Note>
      Because the app requests the `incoming-webhook` scope, Slack will ask you to pick a channel during authorization. This is expected - the chosen channel is saved with the integration, and channel behavior is configured in Serval after connecting.
    </Note>

    <Note>
      On some self-hosted deployments this option is hidden (or returns the error "Slack OAuth is not configured in this environment"). In that case, use the **Your own Slack app** path instead.
    </Note>
  </Tab>

  <Tab title="Your own Slack app (white-label)">
    You'll create a Slack app from a manifest that Serval generates for you, then copy three values from the app's settings. See Slack's [app manifest reference](https://api.slack.com/reference/manifests) for background.

    <Warning>
      Always use the manifest Serval generates in the connect dialog. Do not hand-write it or reuse one from docs or another environment - the webhook, interactivity, slash-command, and OAuth redirect URLs inside it are specific to your exact Serval deployment.
    </Warning>

    <Steps>
      <Step title="Start the custom app flow in Serval">
        In the Serval connect dialog, choose **Use Your Own Slack App**. Set your **App Name** (this appears in Slack when the bot sends messages), and adjust the **Bot Scopes** picker only if your Slack app will deliberately differ from the defaults.
      </Step>

      <Step title="Copy the manifest and go to Slack">
        Click **Copy & Go to Slack** - this copies the generated manifest to your clipboard and opens [Slack's app creation page](https://api.slack.com/apps?new_app=1).
      </Step>

      <Step title="Create the app from the manifest">
        In Slack, choose **From a manifest**, select the workspace to install into, paste the manifest, click **Next**, review the summary, and click **Create**.
      </Step>

      <Step title="(Optional) Add a bot icon">
        Upload a custom bot icon under **Basic Information > Display Information**.
      </Step>

      <Step title="Copy your credentials">
        In [your app's settings](https://api.slack.com/apps), go to **Basic Information > App Credentials** and copy the **Client ID**, **Client Secret**, and **Signing Secret**.
      </Step>
    </Steps>

    <Tip>
      Plan to finish the Serval side within 10 minutes of submitting your credentials - the secure handoff token expires after that, and you would need to resubmit the form.
    </Tip>
  </Tab>
</Tabs>

## Connect in Serval

<Tabs>
  <Tab title="Serval's Slack app (recommended)">
    <Steps>
      <Step title="Choose the recommended option">
        In the Slack connect dialog, select **Use Serval's Slack App** - the option marked **Recommended** ("Connect instantly using Serval's managed Slack application.").
      </Step>

      <Step title="Authorize in Slack">
        You're redirected to Slack's authorization screen. Make sure the correct workspace is selected (top-right), choose a channel when prompted, and click **Allow**.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Your own Slack app (white-label)">
    <Steps>
      <Step title="Name your app">
        **App Name** - pre-filled with "Serval". Placeholder: "My Company IT". Helper text: "This appears in Slack when your app sends messages." If you clear the field, the connected integration is labeled "Custom App". The name is also slugified into your slash command (lowercase letters, numbers, underscores, and hyphens; up to 32 characters; falls back to "serval").
      </Step>

      <Step title="Review Bot Scopes (optional)">
        The **Bot Scopes** picker is pre-seeded with the 33 canonical defaults and has a **Reset to defaults** link. The field's own guidance: "Deselect any scope your Slack app isn't configured with (e.g., Slack Connect scopes if your workspace restricts shared-channel invitations) to avoid being blocked during install." You can also add custom scopes that aren't in the suggestion list. An entry containing characters Slack scope names don't use is rejected with: Invalid Slack bot scope "\<scope>". Use Slack scope names like channels:read or files:write.
      </Step>

      <Step title="Create the app in Slack">
        Use **Copy & Go to Slack** and follow the provider-side steps above, then return and click **I have my credentials**.
      </Step>

      <Step title="Enter your credentials">
        * **Client ID** (required) - placeholder "1234567890.1234567890".
        * **Client Secret** (required, masked) - placeholder "Enter your client secret". Used only during the OAuth exchange and never stored.
        * **Signing Secret** (required, masked) - placeholder "Enter your signing secret". Stored encrypted for webhook signature verification.

        The **Connect** button stays disabled until all three fields are filled in.
      </Step>

      <Step title="Authorize in Slack">
        Click **Connect**. You're redirected to Slack - make sure the correct workspace is selected (top-right), then click **Allow**. Complete this within 10 minutes of submitting the form. The connected integration is displayed as \<Workspace Name> (\<App Name>).
      </Step>
    </Steps>

    <Note>
      When reconnecting later, any extra scopes you previously added are pre-merged back into the Bot Scopes picker - but scopes you previously deselected are not remembered, so deselect them again before reconnecting. Because the Client Secret is never stored, you'll enter your credentials again on reconnect.
    </Note>
  </Tab>
</Tabs>

## Configure Slack as your help desk

After connecting, you land on the Slack app configuration page in Serval. To use Serval in a channel, first add it to the channel in Slack, then set that channel's mode in Serval.

<Steps>
  <Step title="Add Serval to a Slack channel">
    In the channel you want to use, type **@Serval** to mention the app and click **Add them** when prompted. The channel then appears on the Slack app configuration page in Serval.
  </Step>

  <Step title="Set the channel mode in Serval">
    Go to **Integrations > Slack**, find the channel you just added Serval to, and choose how Serval should operate in it. See [Channel configuration modes](#channel-configuration-modes) for what each mode does.
  </Step>

  <Step title="Connect additional channels">
    Repeat for any other channels: add Serval with **@Serval** then **Add them** in Slack, then set that channel's mode in Serval.
  </Step>
</Steps>

<Note>
  You can also enable **Direct Messaging** from the Slack app's help desk settings for private support interactions. Channel-based support and DMs can run at the same time - channels give the team visibility, while DMs give users a private option for sensitive requests.
</Note>

<Tip>
  When first setting up, start a channel in **Silent** mode: Serval creates tickets without posting in the channel, so you can watch how tickets are created and routed before switching it to **Help Desk** mode to fully activate responses.
</Tip>

## Channel configuration modes

Each Slack channel connected to Serval operates in one of these modes:

| Mode                           | Behavior                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Disabled** (default)         | Serval does nothing in this channel — it neither creates tickets nor responds to messages. Use this to add Serval to a channel before turning any features on.                                                                                                                                                   |
| **Help desk (Always respond)** | Full help desk: creates tickets from channel messages, posts ticket-detail cards in the channel, and the help agent attempts resolution using AI Skills and org-wide workflows. Escalates to a human when needed.                                                                                                |
| **Help desk (When relevant)**  | Same ticket creation and in-channel activity as **Help desk (Always respond)**, but the help agent replies only when it finds relevant context (knowledge, guidance, matching workflows). If it cannot help, it stays silent in the channel and hands off to a human instead of posting a "no context" reply.    |
| **Silent**                     | Monitors the channel and creates tickets from messages, but does not post ticket-detail cards or agent replies in the channel. New tickets without an **@Serval** mention are routed to human triage without in-channel noise. Mentioning **@Serval** in a message or thread turns the agent on for that ticket. |
| **On demand**                  | Ignores ambient channel messages. Creates tickets and responds only when **@Serval** is mentioned in a message or thread.                                                                                                                                                                                        |
| **Team only**                  | For internal Serval-team channels. Full help-desk behavior plus access to team-only workflows. Use only in channels restricted to your Serval team members.                                                                                                                                                      |
| **Redirect to DM**             | New conversations are moved to a direct message with the requester before the help agent runs. A single notice is posted in the channel thread; ticket details and agent replies happen in the DM.                                                                                                               |
| **Team inbox**                 | A dedicated channel where support agents triage **all** tickets for the team (see [Configure Team Inbox channels](#configure-team-inbox-channels)). Egress-only: routes existing tickets into the channel for triage; does not create new tickets from messages posted directly in the inbox.                    |
| **Team inbox on Escalation**   | Same as **Team inbox**, but only **escalated** tickets are routed to the channel. Egress-only.                                                                                                                                                                                                                   |

## Configure Team Inbox channels

A Team Inbox is a private channel where support agents triage every escalated ticket for your team within Slack. Tickets from DMs, help desk channels, and the web all appear as threads in one place, so agents can respond and collaborate without switching to the Serval web interface.

<Info>
  Team Inbox is especially valuable when tickets come from DMs or other sources that individual support agents can't otherwise see.
</Info>

<Steps>
  <Step title="Create a private Slack channel">
    Create a private channel for the team's inbox (for example `it-inbox` or `finance-support-inbox`) and invite only the support agents and managers who will handle tickets - not end users.
  </Step>

  <Step title="Add Serval to the channel">
    In the channel, type **@Serval** and click **Add them**, or connect the channel from the Slack app configuration page in Serval.
  </Step>

  <Step title="Set the mode to Team Inbox">
    In **Integrations > Slack**, find the channel and set its mode to **Team Inbox**. All escalated tickets for the team now sync into the channel automatically as threads.
  </Step>
</Steps>

Once configured, each ticket appears as a thread with its details and history. Reply in a thread to send your message to the end user, and use commands like **@Serval assign to me** to triage.

<Warning>
  Team Inbox mode is egress-only. Messages posted directly to the channel (outside a ticket thread) do not create new tickets.
</Warning>

## Resource sync

Serval supports resource sync for Slack **user groups** (Slack subteams - the `@`-mentionable groups in your workspace). This is a separate capability from the help desk and from workflows: it does not sync channels or DMs, only user groups.

<Steps>
  <Step title="Open the Slack app settings">
    In Serval, go to **Integrations > Slack** and open the app's settings page.
  </Step>

  <Step title="Enable resource sync">
    Turn on **Resource sync**. Serval then ingests the workspace's active user groups on its standard sync schedule; disabled groups are skipped. A manual sync from the UI forces a full re-sync.
  </Step>
</Steps>

Each synced group is cataloged in Serval with its name and `@handle` so the help desk agent and workflows can reference it - for example, when a reply needs to mention a Slack user group, Serval renders it as a proper group mention in Slack.

<Note>
  This is a catalog-only sync: Serval learns which groups exist and their handles, but it does **not** add or remove users from Slack groups through access requests (unlike Buildkite or OneLogin). Group membership stays managed in Slack.
</Note>

## Verifying the connection

After connecting, Serval runs five health checks:

* **Test Slack Connection** - verifies the integration is connected and the OAuth token is valid. Success: "Successfully authenticated with Slack workspace \[workspace name]". Failure: "Unable to authenticate with Slack. Please verify the app is still installed and its OAuth token has not been revoked."
* **List Slack Users** - checks Serval can read users from the workspace. Success: "Successfully listed Slack users (sample size: \[number])". Failure: "Unable to list Slack users. Please verify the app has the users:read scope and has not been removed from the workspace."
* **List Slack Channels** - checks Serval can read public and private channels. Success: "Successfully listed Slack channels (sample size: \[number])". Failure: "Unable to list Slack channels. Please verify the app has the channels:read and groups:read scopes and has not been removed from the workspace."
* **List Slack Scopes** - reports the OAuth scopes actually granted to the token. Success: "Successfully read Slack token scopes (\[number] granted)". Failure: "Unable to read Slack token scopes. Please verify the app is still installed and its OAuth token has not been revoked."
* **Send Approval Requests via Slack** - checks the token has the `im:write` scope needed to open DMs for approval requests. Success: "Slack app has the im:write scope required to send approval requests." Failure: "Slack approval requests cannot be sent because the app is missing the im:write scope." If the check itself can't reach Slack, you'll instead see: "Unable to verify Slack approval request permissions. Please verify the app is still installed and its OAuth token has not been revoked."

<Tip>
  If the connection test is green but approval requests never arrive, run **List Slack Scopes** to see what the token was actually granted - the most common cause is a custom app installed without `im:write`. Fix the scopes in your Slack app and reconnect so a new token is issued.
</Tip>

## Gotchas and troubleshooting

<AccordionGroup>
  <Accordion title="Slack blocked the install with a scope error">
    Slack blocks the install if Serval requests scopes your Slack app isn't actually configured with - the scopes requested at install time must all be present on your app. To change scopes on a custom app: adjust the **Bot Scopes** picker in Serval (which regenerates the manifest), update the app at api.slack.com with the new manifest (or matching scope edits), then reconnect so a token with the new grants is issued. Use the **List Slack Scopes** health check to see what the current token actually has.
  </Accordion>

  <Accordion title="Install blocked in workspaces that restrict Slack Connect">
    The default scope set includes the `conversations.connect` scopes for shared channels. If your workspace restricts shared-channel invitations, deselect those scopes in the **Bot Scopes** picker before installing. Note that a non-default selection replaces the canonical scope list wholesale (extra scopes you add are layered on top).
  </Accordion>

  <Accordion title="&#x22;Invalid state&#x22; error after authorizing in Slack">
    Custom-app credentials travel in a signed token that expires 10 minutes after you submit the form. If you take longer than that to finish the Slack authorization, the callback rejects with "Invalid state". Re-open the connect dialog, resubmit your credentials, and complete the authorization promptly. For security, the Client Secret is used only during the exchange and is never stored; only the access token and Signing Secret are stored, encrypted.
  </Accordion>

  <Accordion title="Slack asked me to pick a channel during authorization">
    Expected. Because the app requests the `incoming-webhook` scope, Slack shows a channel selector on the authorization screen. The selected channel's id and name are saved with the integration, and channel behavior is configured in Serval after connecting.
  </Accordion>

  <Accordion title="Can't add a second Slack integration for the same workspace">
    A Serval team can only have one Slack integration per workspace - either the managed app or a custom app, not both. To switch approaches, disconnect the existing integration first.
  </Accordion>

  <Accordion title="Managed option missing, or &#x22;Slack OAuth is not configured in this environment&#x22;">
    Deployments without Serval-operated Slack credentials (for example, some self-hosted environments) can't use the managed one-click install - the connect dialog hides that option, or the attempt fails with "Slack OAuth is not configured in this environment". Use the **Use Your Own Slack App** flow instead.
  </Accordion>

  <Accordion title="Enterprise Grid: install is workspace-scoped, and admin actions don't work">
    Even on Enterprise Grid, the integration connects a single workspace, not the whole organization - workspace-scoped actions like sending messages require a workspace connection, and the app is not org-deployed. Organization-level admin workflows require the separate **Slack Admin** integration, which uses different scopes and user tokens instead of bot tokens - see the [Slack Admin](/sections/integrations/slack-admin) docs page.
  </Accordion>

  <Accordion title="A reused or hand-edited manifest produces a broken app">
    The manifest is generated server-side so the webhook, interactivity, slash-command, and OAuth redirect URLs always match your exact Serval deployment. Copy it fresh from the connect dialog every time - never from documentation, a teammate, or another environment. Serval refuses to generate a manifest with an unreachable webhook address rather than emit a broken one.
  </Accordion>

  <Accordion title="Which bot scopes does Serval request by default?">
    The default set is exactly 33 bot scopes: app\_mentions:read, channels:history, channels:join, channels:manage, channels:read, channels:write.invites, chat:write, chat:write.customize, commands, conversations.connect:manage, conversations.connect:read, conversations.connect:write, files:read, files:write, groups:history, groups:read, groups:write, im:history, im:read, im:write, incoming-webhook, metadata.message:read, mpim:history, mpim:read, reactions:read, reactions:write, team:read, usergroups:read, usergroups:write, users:read, users:read.email, users.profile:read, and assistant:write. No user-level scopes are requested for regular Slack installs. See Slack's [permission scopes reference](https://api.slack.com/scopes) for what each scope grants.
  </Accordion>
</AccordionGroup>

***

Need help? Contact [**support@serval.com**](mailto:support@serval.com) for assistance with your Slack integration.
