Slack Code
Slack Code is how humans work with agents to build with AI in Slack using dedicated channels built for working with agents, called code channels. When a user mentions your agent app, your app can create a code channel where users can collaborate with your agent on a task.
Your app controls the channel including its title, status, context bar, and view tabs via the agents.conversations.* and agents.sessions.* API methods. A code channel looks and acts like a normal channel: users send messages, your agent responds, and everyone in the channel can follow along.
Code channels also display a status for the session, a context bar of agent-supplied items (repository, branch, PR link, etc.), and view tabs that your agent manages (diffs, HTML, Block Kit, or canvases). They're meant to be semi-ephemeral: one channel is created per task, and they're archived when the session finishes. Once archived, the channel and its history remain viewable, searchable, and can be reopened if needed.
Session management and code channels
The agents.sessions.* API methods are unified API methods that work for both code channels and session threads. The thread_ts parameter selects the session type: pass it for a thread session, omit it for a code channel. These methods require only the chat:write scope. Refer to Agent sessions for more details on thread-based usage.
| Method | Use |
|---|---|
agents.sessions.rename | Rename a session. Can be used for both session threads and code channels. |
agents.sessions.setStatus | Set status and create thread sessions. This method does not support a loading_message. While a session is in processing, Slack shows the standard "Working…" loading UX so code channels and session threads look and behave the same. For code channels, thread_ts is not supported. The channel is one session, so separate agent sessions in its threads are not allowed. |
Code channel management
The agents.conversations.* API methods manage tasks specific to code channels, such as creating the channel and setting channel-level properties (context bar, external resources). They require the code_channels:manage scope.
| Method | Description |
|---|---|
agents.conversations.create | Create a code channel. |
agents.conversations.archive | Archive a code channel, optionally recording a summary. |
agents.conversations.setProperties | Set context bar items and external resource details. |
agents.conversations.setCommands | Register the agent's per-channel slash commands. |
agents.conversations.setView | Create or update a view tab (html, diff, block_kit, or canvas). |
agents.conversations.listViews | List views attached to the channel. |
agents.conversations.removeView | Remove a view tab. |
agents.conversations.getCanvas | Read a canvas's content and its comment threads. |
agents.conversations.setCanvasContent | Replace a canvas's content while preserving comment anchors. |
Enabling code channels for your app
If your app already responds to mentions, follow these steps to enable them for use with code channels:
-
Enable code channels in your app manifest as follows:
features:code_channels:enabled: trueslash_command_url: https://example.com/slack/code-channel-commands # optionalWith
features.code_channels.enabledset totrue, your app receivesapp_mentionevents when users mention it, so your app can decide whether to create a code channel or reply in-place. It can also call theagents.conversations.*API methods.The optional
slash_command_urlfield tells Slack where to deliver invocations of your agent's runtime-registered slash commands. It must behttps://(orhttp://), and at most 3000 characters. Socket Mode and hosted apps don't need this. Refer to agent slash commands for details. -
Handle mentions. When a user mentions your agent (e.g.,
@YourAgent please fix the flaky login test) in any channel, your app receives a normalapp_mentionevent via the Events API (or Socket Mode). Your app decides whether to create a dedicated code channel.Your app can also receive an
app_mentionevent inside a code channel it didn't create; for example, if a user started the channel via Slack's ephemeral prompt in a DM, or from Slack's own code channel UI. To recognize it, call theconversations.infoAPI method on the channel and check thatproperties.record_channel.record_typeis set toagent_channel. Refer to code channels properties for more details. -
Create the code channel. Call the
agents.conversations.createAPI method with the origin channel and message timestamp. Slack creates the channel, matches privacy, and invites your bot:POST /api/agents.conversations.create{"name": "Fix flaky login test","session_id": "ses_abc123","origin_channel_id": "C0123456789","origin_message_ts": "1717171717.123456"} -
Set status and context as users and agents begin working:
POST /api/agents.sessions.setStatus{"channel_id": "C9876543210","status": "processing"}POST /api/agents.conversations.setProperties{"channel_id": "C9876543210","code_channel": {"context_bar_items": [{ "key": "repo", "label": "borant/billing", "icon": "folder", "url": "https://github.com/borant/billing" }]}} -
Publish the diff so users can review work in the channel's code tab:
POST /api/agents.conversations.setView{"channel_id": "C9876543210","type": "diff","content": "diff --git a/cron.py b/cron.py\n--- a/cron.py\n+++ b/cron.py\n@@ ...","base_branch": "main","head_branch": "agent/migrate-cron"} -
Archive the channel when done, recording your final summary message on the channel:
POST /api/agents.conversations.archive{"channel_id": "C9876543210","summary_message_ts": "1717182000.456789"}
Refer to the code channel lifecycle for more details about the end-to-end flow.
Scopes
The two API families require different scopes. The agents.sessions.* API methods require chat:write, while the agents.conversations.* API methods require code_channels:manage.
You'll also want the standard scopes any conversational agent uses: app_mentions:read to receive mentions, chat:write to reply, and channels:history (or groups:history for private channels) to receive message events.
If your app already subscribes to message.channels (and/or message.groups) to receive messages elsewhere, those subscriptions also deliver messages from code channels, with no additional subscription needed. If you want to subscribe only to messages in code channels (and agent session threads), the message.session event type allows that. It requires the same channels:history / groups:history scopes and delivers the same message event payloads. The only difference is which channels the messages are routed from. An app may subscribe to both message.session and message.channels / message.groups without receiving duplicates; each message is delivered at most once.
Authorization model
All agents.conversations.* API methods other than create operate on an existing code channel, and are governed by the same rule: the caller must be the agent bot assigned to the channel, or a member of the channel. Calls against a channel that isn't a code channel fail with not_agent_channel; calls from a bot that isn't the channel's agent fail with not_authorized. Your bot must be in the channel (it is invited automatically at creation).
Next steps
- Read more about the code channel lifecycle: from creation through archive.
- Refer to the code channel properties reference for more about context bar items and external resource details.
- Learn about Agent slash commands for registering per-channel slash commands your agent offers.
- See session threads for more about thread-based sessions using the
agents.sessions.*API methods.