Claude Tag API: Manage Claude in Slack Channels From Code

TL;DR
The Claude Tag API beta lets Enterprise admins turn Claude on per Slack channel, set instructions, models and guest policy, and attach Access bundles from code.
Last updated: October 26, 2026
The Claude Tag API, in beta since October 23, 2026, lets a Claude Enterprise organization manage Claude Tag, Claude working as a teammate in Slack, from its own systems instead of the claude.ai admin page. You can turn Claude on channel by channel from an approval workflow, set per-channel instructions, model, environment and guest policy, attach Access bundles, and audit which settings apply in every channel and where each value comes from. It is 14 endpoints under /v1/organizations/claude_tag/, called with a scoped Admin API key and the beta header anthropic-beta: experimental-claude-tag-2026-10-21.
If you haven't seen Claude Tag, our overview of Claude Tag in Slack covers the product. This post is about running it as configuration.
What shipped#
From the Claude Platform release notes for October 23 and the Claude Tag API docs:
| Resource | Endpoints |
|---|---|
| Slack channels | Set up, list or find by Slack IDs, get, update, remove (5) |
| Slack workspaces | List or find by Slack ID, get, update (3) |
| Bundles | List, get (read-only, 2) |
| Bundle targets | List, attach to a channel or workspace, get, detach (4) |
This release covers Slack. The docs list what stays in claude.ai:
- connecting and disconnecting a Slack workspace or Enterprise Grid;
- your organization's Slack defaults;
- creating and editing Access bundles;
- spend limits;
- every Claude Tag setting other than the five below.
The five settings#
| Setting | What it is |
|---|---|
enabled | Whether Claude is on. The nearest level that sets it wins, so true on a channel turns Claude on even if its workspace stores false |
instructions | Standing guidance, at most 8,192 characters. Additive: every level's text is joined, broadest first |
model | The model new sessions start on, a model ID your organization can use with Claude Tag |
environment_id | The cloud environment sessions run in, prefixed env_ |
guest_policy | What Claude does while a Slack guest is in the channel: allow, restrict or channel_only |
Settings live at three levels: the channel, its workspace, and the organization's Slack defaults. Each level stores only what was set on it. A read returns what the channel or workspace stores. Add include_inherited=true to any GET to see what actually applies, with sources naming the level each value came from.
%% title: How Claude Tag API settings resolve for one Slack channel
flowchart TD
A["Organization Slack defaults (claude.ai only)"] --> B["Workspace settings (API or claude.ai)"]
B --> C["Channel settings (API or claude.ai)"]
C --> D{"include_inherited=true?"}
D -->|"No"| E["settings: what the channel stores, null if unset"]
D -->|"Yes"| F["settings: what applies, sources: which level set each value"]Set it up#
- Prerequisites. You need a Claude Enterprise plan with Claude Tag set up and at least one Slack workspace or Enterprise Grid connected. The API is not available to Claude Platform (Claude Console) organizations.
- Create a key. Your primary owner creates an Admin API key in claude.ai > Organization settings > API with
read:claude_tag(everyGET),write:claude_tag(everyPOSTandDELETE), or both.writedoes not grant reads, so an integration that looks a channel up and then changes it needs both scopes. A key created in the Claude Console does not work here. - Send three headers:
x-api-key,anthropic-version: 2023-06-01andanthropic-beta: experimental-claude-tag-2026-10-21. The SDKs expose the endpoints underclient.beta.organization.claudeTag(TypeScript) andclient.beta.organization.claude_tag(Python), and theantCLI underant beta:organization:claude-tag. Both send the version and beta headers for you.
The quick start from the docs lists your workspaces:
curl "https://api.anthropic.com/v1/organizations/claude_tag/slack_workspaces" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: experimental-claude-tag-2026-10-21"
Turn Claude on only in approved channels#
This is the docs' first example workflow. An owner turns Claude off on the Slack defaults in claude.ai. Then your approval system sets each approved channel up with enabled: true and attaches the Access bundles that team was approved for:
import Anthropic from "@anthropic-ai/sdk";
// An Admin API key with read:claude_tag and write:claude_tag, from claude.ai.
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_ADMIN_KEY });
const tag = client.beta.organization.claudeTag;
// Called by your approval system when a channel is approved.
async function approveChannel(workspaceId: string, channelId: string, bundleIds: string[]) {
// Sets the channel up if needed and applies settings. Safe to repeat.
const channel = await tag.slackChannels.create({
slack: { workspace_id: workspaceId, channel_id: channelId },
settings: {
enabled: true,
instructions: "Answer in the language of the question.",
guest_policy: { type: "restrict" },
},
});
// Attach the Access bundles the team was approved for. Also idempotent.
for (const bundleId of bundleIds) {
await tag.bundles.targets.create(bundleId, {
target: { type: "slack_channel", slack_channel_id: channel.id },
});
}
// Read what actually applies, and where each value comes from.
const effective = await tag.slackChannels.retrieve(channel.id, { include_inherited: true });
console.log(effective.settings.model, effective.sources.model);
return channel.id;
}
await approveChannel("T01ABCD2EFG", "C05HJKL6MNP", ["capp_011CZkZjLP1cWxj5EtMmdgbq"]);
We type-checked this with tsc --strict against @anthropic-ai/sdk 1.3.0, the current version, but did not run it against a live organization. The guest_policy type is a closed union, so a typo such as "deny" fails to compile. Both calls are safe to repeat. Setting up a channel that already exists returns it with 200 and applies the settings, and attaching a pair that is already attached returns the existing target. That is what makes them usable from a retrying job.
The other two documented workflows:
- Configuration in version control. Key your config by Slack's own IDs and find each channel with
slackChannels.list({ slack_workspace_id, slack_channel_id }). Read withoutinclude_inherited, compare, and send only the settings that differ, withnullfor any your repository no longer declares. Then have an owner turn on API / Terraform read-only mode, so nobody changes the same settings by hand in claude.ai or Slack. - Audits. List workspaces and each workspace's channels with
include_inherited=true. Flag anything your policy forbids, such asenabled: truewithout an approval on file, orguest_policyset toallow. Then list every Bundle's targets to see where access to sensitive systems is attached.
Rules that will bite#
Leave out to keep, null to clear. A setting you omit is unchanged, and one you send as null is cleared so the level inherits it again. A request is all or nothing: if any value is refused, nothing in it is stored.
Last write wins. No request takes a precondition, so two callers that read and then change the same setting overwrite each other. A 409 only means another change overlapped your request while it ran. Read the resource again and resend.
Changing guest_policy can end sessions. On a channel, it can end sessions running there, in the background, and the response does not wait for it.
Slack IDs mean two things. In a query parameter, slack_channel_id and slack_workspace_id are Slack's own IDs (C..., T...). In a request body or response, they are the API's IDs (slch_..., slws_...). Slack's own IDs in a body are always under slack.
A 404 can mean a missing header. A request without the beta header, or from an organization where the API isn't enabled, returns 404 as if the endpoint didn't exist. To tell that apart from a missing resource, list your workspaces with the same key and headers. That request names nothing, so a 404 there means the header or enablement is the problem.
Read-only mode does not make the API read-only. Despite the name, it makes claude.ai and Slack refuse people's changes to what the API manages, so only keys make those changes. Every endpoint behaves the same either way.
IDs can change. A channel that is removed and set up again gets a new id. While read-only mode is off, setting up an empty channel again in claude.ai can replace its record too.
Remove needs Claude off. Removing a channel where enabled resolves to true returns 400 with slack_channel_enabled. Set enabled to false first.
Rate limits are per organization, shared by all keys:
| Budget | Requests | Burst | Refill |
|---|---|---|---|
| Reads | Every GET | 120 | 2 per second |
| Changes | Every POST and DELETE | 60 | 1 per second |
A 429 comes with retry-after. List endpoints use an opaque cursor, default 20 per page and at most 100, newest first. A channel list page can come back short or empty while next_page is still set, so keep paging until it is null. The SDK iterators do that for you.
Compliance configurations block writes. Under a configuration such as zero data retention, where Claude Tag stores nothing new, setting up channels, updating settings and attaching Bundles return 403 with compliance_configuration_restricted.
What people are actually saying#
- The beta is three days old and we found no Hacker News or Reddit thread about it. Interest so far is Anthropic's own: the Claude Code 2.1.310 changelog shipped several fixes to the Claude Tag admin pages the same week.
- The read-only mode naming ("API / Terraform read-only mode") signals the intended use: Claude Tag as infrastructure-as-code. If you run Slack governance through a pipeline already, this is the piece that was missing.
FAQ#
What is the Claude Tag API?#
A beta Admin API for Claude Enterprise organizations. It reads and changes Claude Tag settings on Slack channels and workspaces, shows what applies and why, and attaches Access bundles.
What do I need to call it?#
Claude Enterprise with Claude Tag and Slack connected, and an Admin API key with read:claude_tag and/or write:claude_tag. Send anthropic-beta: experimental-claude-tag-2026-10-21 on every request.
Which settings can the API change?#
enabled, instructions, model, environment_id and guest_policy, on channels and workspaces. Slack defaults and Bundle creation stay in claude.ai.
Why do I get a 404 from every endpoint?#
Usually a missing beta header, or the API is not enabled for your organization. List workspaces with the same key and headers to check.
Does it work for Claude Platform (Console) organizations?#
No. It is for Claude Enterprise only, and Console keys are refused.
Continue Reading#
- Anthropic Claude Tag Turns Slack Into a Shared Agent Workspace - what Claude Tag is and how teams use it
- Claude Security Continuous Scanning: Fix Tracking, API and MCP - another Enterprise surface that just got an API
- Claude API 2026-10-21: Breaking Changes and SDK Migration - the SDK 1.x line this example uses
Sources#
Get the next deep dive like this in your inbox
One email a week on Anthropic and the rest of the AI dev stack. Free.
Read next on Claude Code
Anthropic Claude Tag Turns Slack Into a Shared Agent Workspace
Claude Tag brings Claude into Slack for Team and Enterprise users. What shared agent identity, channel context and team-visible work mean for developers.
8 min readClaude Security Continuous Scanning: Fix Tracking, API and MCP
Claude Security now rescans repos as commits land, marks findings fixed when the fix ships, and adds an API, MCP connector and webhooks. Setup, limits and cost.
8 min readClaude API 2026-10-21: Breaking Changes and SDK Migration
Claude API version 2026-10-21 removes temperature, top_p and top_k, and new major SDKs (TypeScript 1.0, Python 2.0) send it by default. What breaks and how to migrate.
9 min readTechnical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.







