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

# Slack

> Set up Slack messaging and understand threading, addressing, and delivery.

Connect an agent to Slack as its own app. Formation supports direct messages, group
conversations and channel threads; each agent keeps its own perspective and
credentials even when several agents share a workspace.

## Set up Slack

Follow [Automatic Slack setup](https://docs.formation.texturehq.com/slack-automatic-setup.md) to create and install an
app through Formation. You can also generate a manifest and connect an existing app
with its App ID, bot token and signing secret. Use the agent's app and account,
not another agent's credentials.

Set a stable, publicly reachable HTTPS `PUBLIC_URL` before setup. Formation uses the
HTTP Events API, not Socket Mode. After installation, send a DM and invite the
app to its intended channels. A connected app does not automatically discover
and join every public channel.

Managed apps use `/api/slack/events/{appID}`. Manual apps use `/slack/events`.
Use the exact URL shown by the setup flow. Changing Formation's hostname requires
updating the app's stored event URL; managed apps provide **Update Slack
configuration** for this.

## Permissions and connection health

The generated manifest includes the event subscriptions and bot scopes Formation
needs. Existing apps may need updated scopes and a reinstall when capabilities
change. **Check permissions** on a managed app checks the token's live identity
and granted scopes. **Update Slack permissions** updates the existing app and
opens Slack approval for the same installation.

Missing `files:read` prevents attachment fetches. Channel and DM names require
metadata scopes (`channels:read`, `groups:read`, `im:read`, `mpim:read`) as well
as user access. Valid scopes do not prove membership in a particular channel.

The dashboard resolves channel and participant names through the owning
installation, with cached names and stored IDs as fallbacks. A failed metadata
lookup does not hide conversation history.

## Messages, threads and identity

Slack events route by `(api_app_id, team_id)` to one agent connector. The lookup
selects that installation's signing secret; then Formation verifies the timestamped
HMAC. An unknown route and an invalid signature both receive `401`. Timestamps
must fall within five minutes of Formation's clock.

| Slack field | Purpose in Formation |
| - | - |
| `event.channel` | Reply destination, using Slack's channel ID |
| `event.thread_ts`, or `event.ts` for a root | Conversation thread |
| `event.ts` | Opaque external message ID, preserved without float conversion |
| `event.user` | Participant identity inside this agent's perspective |
| `event.text` | Original Slack `mrkdwn` body |
| `event_id` | Durable ingress deduplication key within the installation |

Being present in a channel does not mean every message addresses the agent.
[Addressing](https://docs.formation.texturehq.com/runtime/addressing.md) decides whether it observes or engages.
Self-authored echoes are dropped; another participant's bot flag is a message
signal, not a global classification of that participant as an agent or human.
Formation does not tell an agent that a peer is hosted by the same deployment.

Inbound Slack formatting is normalized for model context. Outbound canonical
Markdown is rendered to Slack's format at delivery, with chunking as needed.
Formation conversation keys are internal identities and are never passed as Slack
channel IDs.

## Attachments

Image attachments can be fetched for a turn when the selected model supports
image input and authorization succeeds. If the image cannot be fetched or shown,
the prompt reports that limitation instead of implying the agent saw it.

For documents, `list_documents` and `read_document` read authorized PDF, DOCX and
UTF-8 TXT attachments, including eligible earlier uploads. See [Document
reading](https://docs.formation.texturehq.com/runtime/document-reading.md) for format coverage, pagination and limits.
Scanned PDFs and omitted document structures are not silently treated as read.

Attachment access uses the owning connector's credentials, current audience
checks, URL/redirect restrictions and byte limits. A file URL in an event is not
permission to send a Slack token to an arbitrary host.

## Delivery and troubleshooting

Ingress acknowledges accepted events promptly and runs work outside the HTTP
request lifetime. PostgreSQL-backed event claims distinguish completed duplicates
from in-flight work; transient claim failures return a retryable response.
An in-memory dedupe set also exists as a fallback, not the production durability
guarantee. Durable claims alone do not make all runtime configuration
multi-replica ready.

Slack sends have bounded recovery for explicitly rejected HTTP 429 responses.
Ambiguous network outcomes are not blindly retried, and a partially delivered
multi-part reply is not reported as fully delivered. See [Slack delivery
recovery](https://github.com/TextureHQ/formation/blob/main/docs/runtime/slack-delivery-recovery.md).

Formation uses best-effort reactions for working, done and failed states. Reactions
can fail independently of a reply and are not delivery receipts. If an agent
is silent, check the event URL, app permissions, channel membership, engagement
verdict and run/delivery outcome in [Observability](https://docs.formation.texturehq.com/runtime/observability.md).

Implementation: [`internal/connector/slack`](https://github.com/TextureHQ/formation/tree/main/internal/connector/slack)
and [`internal/app/slack_ingress.go`](https://github.com/TextureHQ/formation/blob/main/internal/app/slack_ingress.go).


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