# Slack

**One hlix Slack app, installed into your workspace with OAuth.** After that, a direct message to the bot or an `@hlix` mention in a channel reaches the same chat agent the dashboard talks to, with your workspace's projects, models and tools.

## What it does

| Capability | State |
| --- | --- |
| Direct message → chat agent | Works |
| `@mention` in a channel → chat agent | Works |
| Follow-up messages in a thread the agent replied in | Works |
| Thread context — recent channel messages sent with the request | Works, capped at 10 messages |
| Tool activity rendered as Block Kit cards | Works |
| Request verification | Works — Slack's signing secret, checked by the adapter |
| Mapping a Slack account to a hlix user | **Not implemented.** Workspace membership is the whole authorization |
| Enterprise Grid org-wide installs | **Refused.** See below |

Every message is recorded in the [audit log](/concepts/audit/) as `integration.channel.dispatched`, with the Slack user id and name on the row.

## Prerequisites

- A hlix workspace, and agency `owner` or `admin` — connecting and revoking an installation is workspace administration
- Permission to install an app in the Slack workspace
- The deployment configured with the hlix Slack app (operator work, below)

## Connect it

1. **Start the install** from the dashboard under **Integrations → Slack**, or open:

   ```text
   https://server.hlix.ai/v1/api/integrations/slack/install
   ```

   The workspace is carried in an HMAC-signed `state` parameter, so the callback binds the installation to the workspace you started from — not to whichever one happens to be active when Slack redirects back.

2. **Approve the scopes** on Slack's consent screen. hlix requests exactly:

   ```text
   app_mentions:read   assistant:write   channels:history   chat:write
   groups:history      im:history        im:read            im:write
   ```

   `users:read.email` is deliberately **not** among them — hlix maps no Slack user to a hlix user, so it has no reason to read anyone's email.

3. **Confirm.** Slack redirects back to the dashboard with `?installed=1`, and the installation appears in the list:

   ```bash
   curl https://server.hlix.ai/v1/api/integrations/slack \
     -H "X-Organization-Id: $HLIX_ORG" \
     -H "Authorization: Bearer $HLIX_TOKEN"
   ```

4. **Talk to it.** DM the bot, or invite it to a channel and `@mention` it.

## Disconnect

```bash
curl -X POST https://server.hlix.ai/v1/api/integrations/slack/$INSTALL_ID/revoke \
  -H "X-Organization-Id: $HLIX_ORG" \
  -H "Authorization: Bearer $HLIX_TOKEN"
```

Revoking takes effect on the next message — a revoked installation resolves to no workspace, and the message is dropped. The row is kept as a tombstone rather than deleted, so the record that the workspace *was* connected survives.

## Who can act through Slack

Everyone who can reach the bot, with the workspace's full agent toolbelt — which can create tasks and execute cycles. hlix does not map Slack accounts to hlix users, so channel membership is the access boundary.
**Slack Connect and shared channels widen this:** Adding the bot to a **shared** channel grants external members the agent and its tools, exactly as if they were in your workspace. Keep the bot out of externally shared channels unless you intend that.

## Enterprise Grid

An org-wide Grid install is **refused** at the callback with `?error=enterprise_install_unsupported`. Its installation key is the `enterprise_id`, while an inbound message names the individual workspace's `team_id` — so most of the Grid's workspaces would resolve to no installation and their messages would be dropped silently. Installing into a single workspace within a Grid works normally.

## Operator configuration

1. **Create the Slack app** at [api.slack.com/apps](https://api.slack.com/apps), with the bot scopes listed above.

2. **Set the Event Subscriptions request URL** to the channel webhook, and subscribe to `app_mention`, `message.im`, and `message.channels`:

   ```text
   https://server.hlix.ai/webhooks/channels/slack
   ```

3. **Set the OAuth redirect URL** to the callback:

   ```text
   https://server.hlix.ai/v1/api/integrations/slack/callback
   ```

4. **Set the environment**, all four:

   ```text
   SLACK_CLIENT_ID
   SLACK_CLIENT_SECRET
   SLACK_SIGNING_SECRET
   SLACK_REDIRECT_URI   # the callback URL from step 3
   ```

   There is deliberately **no `SLACK_BOT_TOKEN`.** hlix runs one app across many customer workspaces and resolves each workspace's bot token from its own installation row. Setting a static bot token alongside `SLACK_CLIENT_ID` is how a deployment silently becomes single-workspace.

## Security

Every request carries Slack's signature, verified against `SLACK_SIGNING_SECRET` by the adapter before hlix sees a message. The workspace is derived server-side from the event's `team_id` and never from anything a caller supplies; a `team_id` with no live installation resolves to no workspace and is dropped without a reply — an unknown team is either a revoked install or a forged request, and answering would confirm the endpoint to the latter.

A Slack workspace can be connected to at most **one** hlix workspace at a time. A second workspace trying to connect the same team is refused by a database constraint, not by a check that could be raced.

## If it does not respond

- **A callback redirect with `?error=enterprise_install_unsupported`** — an org-wide Grid install. Install into a single workspace instead.
- **`?error=workspace_already_connected`** — another hlix workspace holds a live installation of that Slack workspace. Revoke it there first.
- **`?error=invalid_state_stale`** — the install took longer than 10 minutes between start and callback. Start again.
- **`?error=token_exchange_slack_error`** — Slack rejected the code. Usually a `SLACK_REDIRECT_URI` that does not exactly match the app's configured redirect URL.
- **`403` — ``admin only``** on a revoke. Connecting and disconnecting is `owner`/`admin` work.
- **`503` — ``Slack is not configured on this server``** — the deployment is missing `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, or `SLACK_SIGNING_SECRET`. Those three are what "configured" means; `SLACK_REDIRECT_URI` is not among them.
- **`500` — ``Slack OAuth not configured``** on install or callback — `SLACK_REDIRECT_URI` is missing. The webhook keeps working and only the install flow fails, which is why this is a different status from the one above. Both are operator fixes, not user ones.
- **Slack shows a retry / timeout on the event URL** — a cold start exceeded Slack's 3-second acknowledgement window. Slack retries up to three times; the first message after an idle period is the one likely to see it.
- **No reply and no error** — check that the workspace's installation is not revoked, and that the bot is actually in the channel you mentioned it from.

## Next steps

[Telegram](/integrations/telegram/)
  [Linear](/integrations/linear/)
  [Audit log](/concepts/audit/)
  [Integrations](/integrations/)