Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

multiagent-orchestration changedmanaged-agents/multiagent-orchestration

Nearest release: v2.1.296, published under an hour after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+759added
Lines−1,004removed
From line 14 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits27to this page, all time

## Hand work to other agents ## Predefined and inline agents ## Delegate to subagents ### How it works ### List the subagents ### Create the session ### Connect agents to MCP servers ### Threads ## Dynamic workflows ### Turn on dynamic workflows ### Tell the agent when to use a run ## Give the session an advisor ### How consultations work ### Advisor threads ### Removing the advisor ## Move from the `coordinator` type ## How it works ## Configure the coordinator ### Give the session an advisor #### How consultations work #### Advisor threads #### Removing the advisor ## Create the session ## Connect agents to MCP servers ## Threads ### Primary thread events ### Session thread events ### Tool permissions and custom tools

The whole hunk

from line 14, old and new numbered
/
lines

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 14
1414 
1515Not sure a multiagent setup fits your problem? See [when to use multiagent systems (and when not to)](https://claude.com/blog/building-multi-agent-systems-when-and-how-to-use-them).
1616 
17## How it works
18 
19All agents share the same sandbox, filesystem, and [vault credentials](https://platform.claude.com/docs/en/managed-agents/vaults), but each agent runs in its own **session thread**, a context-isolated event stream with its own conversation history. The coordinator reports activity in the **primary thread** (which is the same as the session-level [event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming)); additional threads are spawned at runtime when the coordinator delegates work.
20 
21Threads are persistent: the coordinator can send a follow-up to an agent it called earlier, and that agent retains everything from its previous turns.
22 
23Each agent uses its own configuration: model, system prompt, tools, MCP servers, and skills. Session-level [agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) are the exception; they apply to the coordinator and its `self` copies. Tools, MCP servers, and context are not shared.
17## Hand work to other agents
18 
19The agent that a session runs can hand work to other agents in two ways. With **subagents**, it delegates tasks itself and reads what each subagent reports. With **dynamic workflows**, it writes a workflow: a program that runs many agents in the background and combines their results. It can also consult an **advisor** model for guidance while it does the work itself.
20 
21You decide which of these the agent can use, and the agent determines when to use them. To guide that choice, tell the agent in its system prompt when to use a workflow run. See [Tell the agent when to use a run](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#tell-the-agent-when-to-use-a-run). You can also limit the agent to agents that you list.
22 
23With subagents, the agent itself determines what happens next. A [subagent's thread](https://platform.claude.com/docs/en/managed-agents/session-threads) stays available until you archive it, so the agent can send it follow-up messages. With dynamic workflows, Claude writes a program to orchestrate agents without Claude's direct involvement. Context and results are passed programmatically from one agent to another, freeing up the main session thread to communicate with the user and check in on one or several running workflows to report on progress. The agent can't send follow-up messages to a run's threads, and the server archives each one by the end of its run.
24 
25| Approach | What happens | Use it when | Consider |
26| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27| [Subagents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#delegate-to-subagents) | The agent delegates tasks to its subagents. Each subagent works in its own [session thread](https://platform.claude.com/docs/en/managed-agents/session-threads), which you can list and stream. | The agent should follow up with a subagent after it reports, or it needs specialists that you list, with their own system prompts and tools. | Delegation is one level deep, and a session can have at most 25 child threads at a time, idle ones included. Advisor threads and a workflow run's threads don't count. |
28| [Dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#dynamic-workflows) | The agent writes a workflow: a program that runs many agents in phases and combines their results. The server runs it in the background as one workflow run, which you can follow. The workflow defines the agents or picks them from a list you give. | Most work that needs more than one agent: work with many pieces, parallel work, or a long task that should finish sooner. Examples are audits, migrations, deep research, and cross-checking. | Every agent in a run uses tokens, so set a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets) to cap the session's spend, runs included. Tell the agent in its system prompt when to use a run. You follow the run by its phases and can read each of its threads. |
29| [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) | The session's [primary thread](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#how-it-works) consults an advisor model mid-turn for guidance, such as planning an approach or reviewing work, and keeps doing the work itself. | One agent should do the work, with an advisor model's judgment at key moments such as planning or a final review. | Only the primary thread can consult the advisor, and consultations are billed at the advisor model's rates. |
30 
31You set these up in the `multiagent` block of the agent's definition, which has a `type`. With the `multiagent_20261001` type, an agent can use all three together, and you can turn each one on or off. By default, `subagents` and `workflows` are both enabled. `subagents` and `workflows` each have `inline_agents` enabled, the setting for [agents that the agent or a workflow defines itself](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents):
32 
33```json
34{
35 "multiagent": { "type": "multiagent_20261001" }
36}
37```
38 
39To set which agents the agent can call, see [Predefined and inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents). To turn a setting off, see [Turn on dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#turn-on-dynamic-workflows).
40 
41## Predefined and inline agents
42 
43Every subagent, and every agent in a workflow run, is one of two kinds:
44 
45* **Predefined agent:** An agent that you have already [created](https://platform.claude.com/docs/en/managed-agents/agent-setup), and that you list in the `multiagent` block. It uses its own configuration: model, system prompt, tools, MCP servers, and skills.
46* **Inline agent:** An agent that is not saved. The agent that the session runs, or a workflow, defines it when it hands out the work. It uses that agent's model, tools, MCP servers, and skills.
47 
48Both kinds work under `subagents` and under `workflows`:
49 
50| Kind of agent | Under `subagents` | Under `workflows` |
51| ------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
52| Predefined | The agent can delegate to the agents that you list in `subagents.predefined_agents`. | A workflow can use the agents that you list in `workflows.predefined_agents`. |
53| Inline | The agent can define an inline agent when it delegates. `subagents.inline_agents` turns this on or off. | A workflow can define inline agents, and it writes a system prompt for each. `workflows.inline_agents` turns this on or off. |
54 
55`subagents.predefined_agents` and `workflows.predefined_agents` are two separate lists. An agent in one list is not added to the other. Both lists are empty by default. An entry of either list takes one of these forms:
56 
57* `{"type": "agent", "id": agent.id}` references a previously created `agent` by ID. If no `version` is specified, the reference is pinned to the agent's latest version when the agent that lists it is created, or when an update sends the list.
58* `{"type": "agent", "id": agent.id, "version": agent.version}` pins a specific agent version.
59* `agent.id` alone, as a string, is short for `{"type": "agent", "id": agent.id}`.
60* `{"type": "self"}` lists the agent itself, so that copies of it can do the work. If the session was created with [agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session), those overrides also apply to these copies. Entries referenced by ID are unaffected.
61 
62The rules for these entries, and for the agents that they name, apply to both lists. See [List the subagents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#list-the-subagents).
63 
64Inline agents are on by default under both settings. To allow only the agents that you list, set `inline_agents` to `{"type": "disabled"}` under `subagents`, under `workflows`, or under both. A setting with inline agents off needs at least one agent in its `predefined_agents` list. With an empty list, the request fails with a 400 error. On an update, the server checks the settings as they stand after the update.
65 
66The following agent allows only the agents that it lists. It can delegate to one agent and to copies of itself, and a workflow can use version 2 of another agent:
67 
68```json
69{
70 "multiagent": {
71 "type": "multiagent_20261001",
72 "subagents": {
73 "type": "enabled",
74 "inline_agents": { "type": "disabled" },
75 "predefined_agents": ["agent_01J8XkN5uT3vHpLqRfWdY2", { "type": "self" }]
76 },
77 "workflows": {
78 "type": "enabled",
79 "inline_agents": { "type": "disabled" },
80 "predefined_agents": [
81 { "type": "agent", "id": "agent_01Lm4cV8yQ2tNs7XbKdR5h", "version": 2 }
82 ]
83 }
84 }
85}
86```
87 
88## Delegate to subagents
2489 
2590### What to delegate
2691 
from line 93
2893 
2994Patterns that work well:
3095 
31* **Parallelization:** Fan out independent subtasks simultaneously (searching multiple sources, analyzing separate files) and have the coordinator synthesize the results.
96* **Parallelization:** Fan out independent subtasks simultaneously (searching multiple sources, analyzing separate files) and have the agent synthesize the results.
3297* **Specialization:** Route to agents with domain-focused system prompts and tools, such as a security agent or a documentation agent, rather than loading a single agent with every capability.
33* **Escalation:** Consult a more capable agent or model for a subset of complex subtasks.
34 
35## Configure the coordinator
36 
37When [defining your agent](https://platform.claude.com/docs/en/managed-agents/agent-setup), set `multiagent` to declare the roster of agents the coordinator can delegate to:
98* **Escalation:** Consult a more capable agent or model for a subset of complex subtasks. To consult a model, [give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor).
99 
100### How it works
101 
102All agents share the same sandbox, filesystem, and [vault credentials](https://platform.claude.com/docs/en/managed-agents/vaults), but each agent runs in its own **session thread**, a context-isolated event stream with its own conversation history. The agent that the session runs reports activity in the **primary thread**, which is the session-level [event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming). Additional threads are spawned at runtime when it delegates work. A workflow run also creates threads.
103 
104A subagent's thread is persistent. The agent can send a follow-up to a subagent it called earlier, and that subagent retains everything from its previous turns.
105 
106Which configuration a subagent uses depends on whether it is a [predefined or an inline agent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents). Session-level [agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) apply to the agent that the session runs and to its `self` copies. Each agent keeps its own conversation history.
107 
108### List the subagents
109 
110When [defining your agent](https://platform.claude.com/docs/en/managed-agents/agent-setup), set `subagents.predefined_agents` in the `multiagent` block to list the agents that it can delegate to:
38111 
39112<CodeGroup defaultLanguage="CLI">
40113 ```bash cURL
41 coordinator=$(curl -fsS https://api.anthropic.com/v1/agents \
114 lead_agent=$(curl -fsS https://api.anthropic.com/v1/agents \
42115 -H "x-api-key: $ANTHROPIC_API_KEY" \
43116 -H "anthropic-version: 2023-06-01" \
44117 -H "anthropic-beta: managed-agents-2026-04-01" \
from line 127
54127 }
55128 ],
56129 "multiagent": {
57 "type": "coordinator",
58 "agents": [
59 {"type": "agent", "id": "$REVIEWER_AGENT_ID"},
60 {"type": "agent", "id": "$TEST_WRITER_AGENT_ID"}
61 ]
130 "type": "multiagent_20261001",
131 "subagents": {
132 "type": "enabled",
133 "predefined_agents": [
134 {"type": "agent", "id": "$REVIEWER_AGENT_ID"},
135 {"type": "agent", "id": "$TEST_WRITER_AGENT_ID"}
136 ]
137 }
62138 }
63139 }
64140 EOF
from line 143
67143 
68144 <CodeGroupItem>
69145 ```bash CLI
146 # Create the subagents, then read their IDs from the lockfile.
147 ant apply reviewer.md test-writer.md
148 REVIEWER_AGENT_ID=$(jq -er '.resources["./reviewer.md"].id' claude-lock.json)
149 TEST_WRITER_AGENT_ID=$(jq -er '.resources["./test-writer.md"].id' claude-lock.json)
150 
151 # Write the agent's definition, listing each subagent by ID.
152 cat > engineering-lead.md <<EOF
153 ---
154 name: Engineering Lead
155 model: claude-opus-5-5
156 tools:
157 - type: agent_toolset_20260401
158 multiagent:
159 type: multiagent_20261001
160 subagents:
161 type: enabled
162 predefined_agents:
163 - type: agent
164 id: $REVIEWER_AGENT_ID
165 - type: agent
166 id: $TEST_WRITER_AGENT_ID
167 ---
168 
169 You coordinate engineering work. Delegate code review to the reviewer agent
170 and test writing to the test agent.
171 EOF
172 
173 # Create the agent.
70174 ant apply engineering-lead.md reviewer.md test-writer.md
71175 ```
72 
73 <File filename="engineering-lead.md">
74 ```markdown
75 ---
76 name: Engineering Lead
77 model: claude-opus-5-5
78 tools:
79 - type: agent_toolset_20260401
80 multiagent:
81 type: coordinator
82 agents: # paths: ant apply substitutes {type: agent, id, version}
83 - ./reviewer.md
84 - ./test-writer.md
85 ---
86 
87 You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.
88 ```
89 </File>
90176 
91177 <File filename="reviewer.md">
92178 ```markdown
from line 198
112198 </CodeGroupItem>
113199 
114200 ```python Python
115 coordinator = client.beta.agents.create(
201 lead_agent = client.beta.agents.create(
116202 name="Engineering Lead",
117203 model="claude-opus-5-5",
118204 system="You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.",
from line 206
120206 {"type": "agent_toolset_20260401"},
121207 ],
122208 multiagent={
123 "type": "coordinator",
124 "agents": [
125 {"type": "agent", "id": reviewer_agent.id},
126 {"type": "agent", "id": test_writer_agent.id},
127 ],
209 "type": "multiagent_20261001",
210 "subagents": {
211 "type": "enabled",
212 "predefined_agents": [
213 {"type": "agent", "id": reviewer_agent.id},
214 {"type": "agent", "id": test_writer_agent.id},
215 ],
216 },
128217 },
129218 )
130219 ```
131220 
132221 ```typescript TypeScript
133 const coordinator = await client.beta.agents.create({
222 const leadAgent = await client.beta.agents.create({
134223 name: "Engineering Lead",
135224 model: "claude-opus-5-5",
136225 system:
137226 "You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.",
138227 tools: [{ type: "agent_toolset_20260401" }],
139228 multiagent: {
140 type: "coordinator",
141 agents: [
142 { type: "agent", id: reviewerAgent.id },
143 { type: "agent", id: testWriterAgent.id },
144 ],
229 type: "multiagent_20261001",
230 subagents: {
231 type: "enabled",
232 predefined_agents: [
233 { type: "agent", id: reviewerAgent.id },
234 { type: "agent", id: testWriterAgent.id },
235 ],
236 },
145237 },
146238 });
147239 ```
148240 
149241 ```csharp C#
150 var coordinator = await client.Beta.Agents.Create(new()
242 var leadAgent = await client.Beta.Agents.Create(new()
151243 {
152244 Name = "Engineering Lead",
153245 Model = BetaManagedAgentsModel.ClaudeOpus5_5,
from line 251
159251 Type = BetaManagedAgentsAgentToolset20260401ParamsType.AgentToolset20260401,
160252 },
161253 ],
162 Multiagent = new BetaManagedAgentsMultiagentParams
254 Multiagent = new BetaManagedAgentsMultiagent20261001Params
163255 {
164 Type = BetaManagedAgentsMultiagentParamsType.Coordinator,
165 Agents = [reviewerAgent.ID, testWriterAgent.ID],
256 Subagents = new BetaManagedAgentsMultiagentSubagentsEnabledParams
257 {
258 PredefinedAgents = [reviewerAgent.ID, testWriterAgent.ID],
259 },
166260 },
167261 });
168262 ```
169263 
170264 ```go Go
171 coordinator, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
265 leadAgent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
172266 Name: "Engineering Lead",
173267 Model: anthropic.BetaManagedAgentsModelConfigParams{ID: anthropic.BetaManagedAgentsModelClaudeOpus5_5},
174268 System: anthropic.String("You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent."),
from line 271
177271 Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
178272 },
179273 }},
180 Multiagent: anthropic.BetaManagedAgentsMultiagentParams{
181 Type: anthropic.BetaManagedAgentsMultiagentParamsTypeCoordinator,
182 Agents: []anthropic.BetaManagedAgentsMultiagentRosterEntryParamsUnion{
183 {OfString: anthropic.String(reviewerAgent.ID)},
184 {OfString: anthropic.String(testWriterAgent.ID)},
274 Multiagent: anthropic.BetaManagedAgentsMultiagentParamsUnion{
275 OfMultiagent20261001: &anthropic.BetaManagedAgentsMultiagent20261001Params{
276 Subagents: anthropic.BetaManagedAgentsMultiagentSubagentsParamsUnion{
277 OfEnabled: &anthropic.BetaManagedAgentsMultiagentSubagentsEnabledParams{
278 PredefinedAgents: []anthropic.BetaManagedAgentsMultiagentPredefinedAgentParamsUnion{
279 {OfString: anthropic.String(reviewerAgent.ID)},
280 {OfString: anthropic.String(testWriterAgent.ID)},
281 },
282 },
283 },
185284 },
186285 },
187286 })
from line 290
191290 ```
192291 
193292 ```java Java
194 var coordinator = client.beta().agents().create(
293 var leadAgent = client.beta().agents().create(
195294 AgentCreateParams.builder()
196295 .name("Engineering Lead")
197296 .model(BetaManagedAgentsModel.CLAUDE_OPUS_5_5)
from line 300
201300 .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
202301 .build()
203302 )
204 .multiagent(BetaManagedAgentsMultiagentParams.builder()
205 .type(BetaManagedAgentsMultiagentParams.Type.COORDINATOR)
206 .addAgent(BetaManagedAgentsAgentParams.builder()
207 .type(BetaManagedAgentsAgentParams.Type.AGENT)
208 .id(reviewerAgent.id())
209 .build())
210 .addAgent(BetaManagedAgentsAgentParams.builder()
211 .type(BetaManagedAgentsAgentParams.Type.AGENT)
212 .id(testWriterAgent.id())
303 .multiagent(BetaManagedAgentsMultiagent20261001Params.builder()
304 .subagents(BetaManagedAgentsMultiagentSubagentsEnabledParams.builder()
305 .addPredefinedAgent(BetaManagedAgentsAgentParams.builder()
306 .type(BetaManagedAgentsAgentParams.Type.AGENT)
307 .id(reviewerAgent.id())
308 .build())
309 .addPredefinedAgent(BetaManagedAgentsAgentParams.builder()
310 .type(BetaManagedAgentsAgentParams.Type.AGENT)
311 .id(testWriterAgent.id())
312 .build())
213313 .build())
214314 .build())
215315 .build()
from line 317
217317 ```
218318 
219319 ```php PHP
220 $coordinator = $client->beta->agents->create(
320 $leadAgent = $client->beta->agents->create(
221321 name: 'Engineering Lead',
222322 model: 'claude-opus-5-5',
223323 system: 'You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.',
from line 325
225325 ['type' => 'agent_toolset_20260401'],
226326 ],
227327 multiagent: [
228 'type' => 'coordinator',
229 'agents' => [
230 ['type' => 'agent', 'id' => $reviewerAgent->id],
231 ['type' => 'agent', 'id' => $testWriterAgent->id],
328 'type' => 'multiagent_20261001',
329 'subagents' => [
330 'type' => 'enabled',
331 'predefined_agents' => [
332 ['type' => 'agent', 'id' => $reviewerAgent->id],
333 ['type' => 'agent', 'id' => $testWriterAgent->id],
334 ],
232335 ],
233336 ],
234337 );
235338 ```
236339 
237340 ```ruby Ruby
238 coordinator = client.beta.agents.create(
341 lead_agent = client.beta.agents.create(
239342 name: "Engineering Lead",
240343 model: "claude-opus-5-5",
241344 system: "You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.",
from line 346
243346 {type: "agent_toolset_20260401"}
244347 ],
245348 multiagent: {
246 type: "coordinator",
247 agents: [
248 {type: "agent", id: reviewer_agent.id},
249 {type: "agent", id: test_writer_agent.id}
250 ]
349 type: "multiagent_20261001",
350 subagents: {
351 type: "enabled",
352 predefined_agents: [
353 {type: "agent", id: reviewer_agent.id},
354 {type: "agent", id: test_writer_agent.id}
355 ]
356 }
251357 }
252358 )
253359 ```
254360</CodeGroup>
255361 
256`multiagent.agents` can accept any of the following:
257 
258* `{"type": "agent", "id": agent.id}` references a previously created `agent` by ID. If no `version` is specified, the reference is pinned to the latest version of that agent at the time the coordinator is created.
259* `{"type": "agent", "id": agent.id, "version": agent.version}` pins a specific agent version.
260* `{"type": "self"}` allows the coordinator to spawn copies of itself. If the session was created with [agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session), those overrides also apply to these copies; roster entries referenced by ID are unaffected.
261* `{"type": "advisor", "model": "<model id>"}` gives the session's primary thread an advisor it can consult mid-turn. At most one advisor entry per roster. See [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor).
262 
263In an [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) agent file (the CLI tab), a roster entry can also be the path to another agent's file, such as `./reviewer.md`. Apply creates that agent first and replaces the path with a pinned `{"type": "agent", "id": ..., "version": ...}` reference.
264 
265The coordinator's configuration, including its `multiagent.agents` roster, is snapshotted when the coordinator is created or updated. Referenced agents stay pinned to the versions resolved at that time and do not automatically pick up later updates to their definitions. To delegate to a newer version of a referenced agent, [update the coordinator](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent) so its roster references that version.
266 
267The coordinator can only delegate to one level of agents; referencing an agent that has its own `multiagent.agents` roster fails the create or update request with a validation error. A maximum of 20 unique agents can be listed in `multiagent.agents`, but the coordinator can call multiple copies of each agent.
268 
269When agents pin an [inference geography](https://platform.claude.com/docs/en/manage-claude/data-residency) (`model.inference_geo` in the [agent definition](https://platform.claude.com/docs/en/managed-agents/agent-setup)), the coordinator's pin and every roster member's pin must either all be set to the same value or all be unset. A mismatched roster is rejected with a 400 validation error, both when the agent is saved and when a [session-create override](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) changes any of the pins.
270 
271### Give the session an advisor
272 
273An advisor entry in `multiagent.agents` gives the session's primary thread an **advisor**: a model it can consult mid-turn for strategic guidance, such as planning an approach, getting unstuck, or reviewing work before finishing. The entry has exactly two fields, `type` and `model`:
274 
275```bash cURL
276curl -fsS https://api.anthropic.com/v1/agents \
277 -H "x-api-key: $ANTHROPIC_API_KEY" \
278 -H "anthropic-version: 2023-06-01" \
279 -H "anthropic-beta: managed-agents-2026-04-01" \
280 -H "content-type: application/json" \
281 -d '{
282 "name": "Backend engineer",
283 "model": "claude-sonnet-5",
284 "system": "You implement backend features end to end. Consult the advisor before major backend design decisions.",
285 "multiagent": {
286 "type": "coordinator",
287 "agents": [
288 {"type": "advisor", "model": "claude-opus-5-5"}
289 ]
290 }
291 }'
292```
293 
294A roster can contain at most one advisor entry, alongside any of the other roster forms. The entry occupies the reserved roster name `anthropic.advisor`: a roster that lists both an advisor entry and a member literally named `anthropic.advisor` is rejected with a 400 validation error. In responses, the advisor entry is echoed last in the roster regardless of the position it was submitted in.
295 
296The advisor model must meet a minimum capability bar, and the agent's own model must not be more capable than its advisor; models of equal capability can pair. An invalid pairing is rejected with a 400 validation error when the agent is saved. Valid pairings follow the advisor tool's [model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#model-compatibility) table.
297 
298The advisor is also available as a [server tool on the Messages API](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool). The Managed Agents surface differs in configuration and delivery: the roster entry has no `max_uses`, `max_tokens`, or `caching` fields, and advice arrives through thread events rather than `advisor_tool_result` blocks.
299 
300#### How consultations work
301 
302Each consultation runs as a platform-spawned thread named `anthropic.advisor` that terminates itself when the consultation completes, and the advice is delivered to the primary thread as an `agent.thread_message_received` event. A consultation emits the standard thread events, identified by the reserved name `anthropic.advisor` (the thread lifecycle events carry it as `agent_name`, and the advice delivery carries it as `from_agent_name`), typically in this order:
303 
3041. `session.thread_created`
3052. `session.thread_status_running`
3063. `agent.thread_message_received` (the advice)
3074. `session.thread_status_idle` (`stop_reason: end_turn`)
3085. `session.thread_status_terminated`
309 
310No `agent.tool_use` events are emitted for a consultation, and no `agent.thread_message_sent` event appears on the session's event stream, because the consultation input is composed by the platform rather than sent by the agent. If you list the advisor thread's own events, the advice also appears there as an `agent.thread_message_sent` event. The advice delivery (event 3) is not guaranteed to arrive before the advisor thread's idle and terminated events, so don't treat those as a signal that the advice has already been delivered.
311 
312Whether your client can read the advice is the advisor model's policy, and it mirrors the [result variants](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#result-variants) split on the Messages API advisor tool. Advisor models that return plaintext results there deliver the advice as readable text content here; advisor models that return redacted results there deliver a `[{"type": "redacted"}]` placeholder as the message content on every client surface, while the agent itself still reads the full advice server-side. In the preceding example, Claude Opus 5 is a redacted-result advisor, so your client sees the placeholder while the agent reads the full advice; choose Claude Opus 4.8 as the advisor instead if you want the advice readable on the event stream. Advisor thinking is never surfaced. Clients cannot send `redacted` blocks themselves; an event containing one is rejected with a 400 validation error.
313 
314A failed or interrupted consultation never fails the agent's turn: the agent continues after a generic notice that the consultation failed. A session-level `user.interrupt` during a consultation terminates the advisor thread with no advice delivered; a `user.interrupt` with the advisor thread's `session_thread_id` abandons only that consultation.
315 
316#### Advisor threads
317 
318The advisor is not a roster agent: it is invisible to the coordinator's `list_agents` tool, it cannot be messaged with `send_to_agent`, and only the session's primary thread can consult it. Roster agents cannot.
319 
320Advisor threads are exempt from the concurrent-thread limit. They appear in the session's [thread list](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#threads) with `agent` set to the advisor form exactly as configured (`{"type": "advisor", "model": ...}`) and `parent_thread_id` set to the primary thread.
321 
322Prompt caching on the advisor's side is automatic; there is nothing to configure. Consultations are billed at the advisor model's rates, and their tokens appear in the advisor thread's usage and in the session's usage totals.
323 
324#### Removing the advisor
325 
326To remove the advisor, [update the agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent) with a roster that no longer includes the advisor entry. If the advisor is the roster's only entry, clear the roster entirely by setting `"multiagent": null`.
327 
328## Create the session
329 
330Create a session referencing the coordinator. The coordinator delegates to the agents in its roster as needed.
362The agent can also delegate to inline agents unless you turn them off. For that setting, and for the forms that an entry of `subagents.predefined_agents` takes, see [Predefined and inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents).
363 
364`"advisor": {"type": "enabled", "model": "<model id>"}` gives the session's primary thread an advisor it can consult mid-turn. The advisor is a setting in the `multiagent` block, not an entry in this list. See [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor).
365 
366Dynamic workflows are also enabled by default with this type, so this agent can plan large work that runs many agents in the background. To turn them off, or to list agents that a workflow can use, see [Turn on dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#turn-on-dynamic-workflows).
367 
368The following rules apply to the agents you list in `subagents.predefined_agents`, and also to the agents you list in `workflows.predefined_agents`:
369 
370* **Pinning:** The agent's configuration, including its `subagents.predefined_agents` list, is snapshotted when the agent is created or updated. Referenced agents stay pinned to the versions resolved then and don't pick up later updates to their definitions. An update that doesn't send the list keeps the versions that are already pinned. To delegate to a newer version of a referenced agent, [update the agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent) so its `subagents.predefined_agents` list references that version.
371* **One level:** The agent can delegate to only one level of agents. Referencing another agent that has `multiagent` set fails the create or update request with a 400 validation error.
372* **Up to 20 agents:** `subagents.predefined_agents` can list up to 20 unique agents. The limit is per list: `workflows.predefined_agents` can also list up to 20. The agent can call multiple copies of each agent, within the session's [thread limit](https://platform.claude.com/docs/en/managed-agents/session-threads).
373* **Inference geography:** The agent and every agent that you list, in `subagents.predefined_agents` or in `workflows.predefined_agents`, must pin the same [inference geography](https://platform.claude.com/docs/en/manage-claude/data-residency) (`model.inference_geo` in the [agent definition](https://platform.claude.com/docs/en/managed-agents/agent-setup)), or none of them can pin one. A mismatch in either list is rejected with a 400 validation error. That check runs both when the agent is saved and when a [session-create override](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) changes any of the pins.
374 
375### Create the session
376 
377Create a session referencing the agent. The agent delegates to the agents you list in `subagents.predefined_agents` as needed. It can also delegate to [inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents) unless you turn them off.
331378 
332379<CodeGroup>
333380 ```bash cURL
from line 385
338385 -H "content-type: application/json" \
339386 -d @- <<EOF
340387 {
341 "agent": "$COORDINATOR_ID",
388 "agent": "$LEAD_AGENT_ID",
342389 "environment_id": "$ENVIRONMENT_ID"
343390 }
344391 EOF
from line 395
348395 
349396 ```bash CLI
350397 ant beta:sessions create \
351 --agent "$COORDINATOR_ID" \
398 --agent "$LEAD_AGENT_ID" \
352399 --environment-id "$ENVIRONMENT_ID"
353400 ```
354401 
355402 ```python Python
356403 session = client.beta.sessions.create(
357 agent=coordinator.id,
404 agent=lead_agent.id,
358405 environment_id=environment.id,
359406 )
360407 ```
361408 
362409 ```typescript TypeScript
363410 const session = await client.beta.sessions.create({
364 agent: coordinator.id,
411 agent: leadAgent.id,
365412 environment_id: environment.id,
366413 });
367414 ```
from line 416
369416 ```csharp C#
370417 var session = await client.Beta.Sessions.Create(new()
371418 {
372 Agent = coordinator.ID,
419 Agent = leadAgent.ID,
373420 EnvironmentID = environment.ID,
374421 });
375422 ```
from line 424
377424 ```go Go
378425 session, err := client.Beta.Sessions.New(ctx, anthropic.BetaSessionNewParams{
379426 Agent: anthropic.BetaSessionNewParamsAgentUnion{
380 OfString: anthropic.String(coordinator.ID),
427 OfString: anthropic.String(leadAgent.ID),
381428 },
382429 EnvironmentID: environment.ID,
383430 })
from line 435
388435 
389436 ```java Java
390437 var session = client.beta().sessions().create(SessionCreateParams.builder()
391 .agent(coordinator.id())
438 .agent(leadAgent.id())
392439 .environmentId(environment.id())
393440 .build());
394441 ```
395442 
396443 ```php PHP
397444 $session = $client->beta->sessions->create(
398 agent: $coordinator->id,
445 agent: $leadAgent->id,
399446 environmentID: $environment->id,
400447 );
401448 ```
402449 
403450 ```ruby Ruby
404451 session = client.beta.sessions.create(
405 agent: coordinator.id,
452 agent: lead_agent.id,
406453 environment_id: environment.id
407454 )
408455 ```
409456</CodeGroup>
410457 
411## Connect agents to MCP servers
412 
413MCP servers are agent-scoped (each agent definition declares its own servers and tools), while vault credentials are session-scoped (`vault_ids` passed at session creation apply to every thread). Two implications for your integration:
458### Connect agents to MCP servers
459 
460MCP servers are agent-scoped: each agent definition declares its own servers and tools. An inline agent has no agent definition, so it uses the MCP servers and tools of the agent that the session runs. Vault credentials are session-scoped: `vault_ids` passed at session creation apply to every thread. Two implications for your integration:
414461 
415462* To authenticate MCP servers, include a vault credential for every MCP server used across all agents.
416* To limit an agent's access, declare only the servers it needs in its agent definition.
417 
418[Agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) at session creation can replace the coordinator's MCP servers and those of its `self` copies.
419 
420With a `limited` [environment](https://platform.claude.com/docs/en/managed-agents/environments#networking), session creation fails with a 400 error when the coordinator, or an agent it can delegate to, declares an MCP server whose host is not in `allowed_hosts`. Setting `allow_mcp_servers: true` in the environment's networking turns this check off.
421 
422Create the researcher, which declares the GitHub MCP server, and the coordinator that delegates to the researcher:
463* To limit an agent's access, declare only the servers it needs in its agent definition. You can't limit an inline agent this way. To allow only the agents you list, disable `inline_agents` in both `subagents` and `workflows`, and list at least one agent in each. See [Predefined and inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents).
464 
465[Agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) at session creation can replace the MCP servers of the agent that the session runs and those of its `self` copies.
466 
467With a `limited` [environment](https://platform.claude.com/docs/en/managed-agents/environments#networking), session creation fails with a 400 error when the agent, or an agent you list in `subagents.predefined_agents` or `workflows.predefined_agents`, declares an MCP server whose host is not in `allowed_hosts`. Setting `allow_mcp_servers: true` in the environment's networking turns this check off.
468 
469Create the researcher, which declares the GitHub MCP server, and the agent that delegates to the researcher:
423470 
424471<CodeGroup defaultLanguage="CLI">
425472 ```bash cURL
from line 480
433480 EOF
434481 )
435482 
436 coordinator_id=$(curl --fail-with-body -sS "$BASE/v1/agents" "${H[@]}" --data @- <<EOF | jq -er '.id'
483 lead_agent_id=$(curl --fail-with-body -sS "$BASE/v1/agents" "${H[@]}" --data @- <<EOF | jq -er '.id'
437484 {
438 "name": "coordinator",
485 "name": "lead",
439486 "model": "claude-opus-5-5",
440487 "tools": [{"type": "agent_toolset_20260401"}],
441488 "multiagent": {
442 "type": "coordinator",
443 "agents": [{"type": "agent", "id": "$research_agent_id"}]
489 "type": "multiagent_20261001",
490 "subagents": {
491 "type": "enabled",
492 "predefined_agents": [{"type": "agent", "id": "$research_agent_id"}]
493 }
444494 }
445495 }
446496 EOF
from line 499
449499 
450500 <CodeGroupItem>
451501 ```bash CLI
452 ant apply coordinator.md researcher.md
502 # Create the researcher, then read its ID from the lockfile.
503 ant apply researcher.md
504 research_agent_id=$(jq -er '.resources["./researcher.md"].id' claude-lock.json)
505 
506 # Write the agent's definition, listing the researcher by ID.
507 cat > lead.md <<EOF
508 ---
509 name: lead
510 model: claude-opus-5-5
511 tools:
512 - type: agent_toolset_20260401
513 multiagent:
514 type: multiagent_20261001
515 subagents:
516 type: enabled
517 predefined_agents:
518 - type: agent
519 id: $research_agent_id
520 ---
521 EOF
522 
523 # Create the agent.
524 ant apply lead.md researcher.md
453525 ```
454 
455 <File filename="coordinator.md">
456 ```markdown
457 ---
458 name: coordinator
459 model: claude-opus-5-5
460 tools:
461 - type: agent_toolset_20260401
462 multiagent:
463 type: coordinator
464 agents: # path: ant apply substitutes {type: agent, id, version}
465 - ./researcher.md
466 ---
467 ```
468 </File>
469526 
470527 <File filename="researcher.md">
471528 ```markdown
from line 551
494551 tools=[{"type": "mcp_toolset", "mcp_server_name": "github"}],
495552 )
496553 
497 coordinator = client.beta.agents.create(
498 name="coordinator",
554 lead_agent = client.beta.agents.create(
555 name="lead",
499556 model="claude-opus-5-5",
500557 tools=[{"type": "agent_toolset_20260401"}],
501558 multiagent={
502 "type": "coordinator",
503 "agents": [{"type": "agent", "id": research_agent.id}],
559 "type": "multiagent_20261001",
560 "subagents": {
561 "type": "enabled",
562 "predefined_agents": [{"type": "agent", "id": research_agent.id}],
563 },
504564 },
505565 )
506566 ```
from line 575
515575 tools: [{ type: "mcp_toolset", mcp_server_name: "github" }],
516576 });
517577 
518 const coordinator = await client.beta.agents.create({
519 name: "coordinator",
578 const leadAgent = await client.beta.agents.create({
579 name: "lead",
520580 model: "claude-opus-5-5",
521581 tools: [{ type: "agent_toolset_20260401" }],
522582 multiagent: {
523 type: "coordinator",
524 agents: [{ type: "agent", id: researchAgent.id }],
583 type: "multiagent_20261001",
584 subagents: {
585 type: "enabled",
586 predefined_agents: [{ type: "agent", id: researchAgent.id }],
587 },
525588 },
526589 });
527590 ```
from line 613
550613 ],
551614 });
552615 
553 var coordinator = await client.Beta.Agents.Create(new()
616 var leadAgent = await client.Beta.Agents.Create(new()
554617 {
555 Name = "coordinator",
618 Name = "lead",
556619 Model = BetaManagedAgentsModel.ClaudeOpus5_5,
557620 Tools =
558621 [
from line 624
561624 Type = BetaManagedAgentsAgentToolset20260401ParamsType.AgentToolset20260401,
562625 },
563626 ],
564 Multiagent = new()
627 Multiagent = new BetaManagedAgentsMultiagent20261001Params
565628 {
566 Type = BetaManagedAgentsMultiagentParamsType.Coordinator,
567 Agents =
568 [
569 new BetaManagedAgentsAgentParams
570 {
571 Type = BetaManagedAgentsAgentParamsType.Agent,
572 ID = researchAgent.ID,
573 },
574 ],
629 Subagents = new BetaManagedAgentsMultiagentSubagentsEnabledParams
630 {
631 PredefinedAgents =
632 [
633 new BetaManagedAgentsAgentParams
634 {
635 Type = BetaManagedAgentsAgentParamsType.Agent,
636 ID = researchAgent.ID,
637 },
638 ],
639 },
575640 },
576641 });
577642 ```
from line 661
596661 panic(err)
597662 }
598663 
599 coordinator, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
600 Name: "coordinator",
664 leadAgent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
665 Name: "lead",
601666 Model: anthropic.BetaManagedAgentsModelConfigParams{ID: anthropic.BetaManagedAgentsModelClaudeOpus5_5},
602667 Tools: []anthropic.BetaAgentNewParamsToolUnion{{
603668 OfAgentToolset20260401: &anthropic.BetaManagedAgentsAgentToolset20260401Params{
604669 Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
605670 },
606671 }},
607 Multiagent: anthropic.BetaManagedAgentsMultiagentParams{
608 Type: anthropic.BetaManagedAgentsMultiagentParamsTypeCoordinator,
609 Agents: []anthropic.BetaManagedAgentsMultiagentRosterEntryParamsUnion{{
610 OfBetaManagedAgentsAgents: &anthropic.BetaManagedAgentsAgentParams{
611 Type: anthropic.BetaManagedAgentsAgentParamsTypeAgent,
612 ID: researcher.ID,
672 Multiagent: anthropic.BetaManagedAgentsMultiagentParamsUnion{
673 OfMultiagent20261001: &anthropic.BetaManagedAgentsMultiagent20261001Params{
674 Subagents: anthropic.BetaManagedAgentsMultiagentSubagentsParamsUnion{
675 OfEnabled: &anthropic.BetaManagedAgentsMultiagentSubagentsEnabledParams{
676 PredefinedAgents: []anthropic.BetaManagedAgentsMultiagentPredefinedAgentParamsUnion{{
677 OfBetaManagedAgentsAgents: &anthropic.BetaManagedAgentsAgentParams{
678 Type: anthropic.BetaManagedAgentsAgentParamsTypeAgent,
679 ID: researcher.ID,
680 },
681 }},
682 },
613683 },
614 }},
684 },
615685 },
616686 })
617687 if err != nil {
from line 706
636706 .build()
637707 );
638708 
639 var coordinator = client.beta().agents().create(
709 var leadAgent = client.beta().agents().create(
640710 AgentCreateParams.builder()
641 .name("coordinator")
711 .name("lead")
642712 .model(BetaManagedAgentsModel.CLAUDE_OPUS_5_5)
643713 .addTool(BetaManagedAgentsAgentToolset20260401Params.builder()
644714 .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
645715 .build())
646 .multiagent(BetaManagedAgentsMultiagentParams.builder()
647 .type(BetaManagedAgentsMultiagentParams.Type.COORDINATOR)
648 .addAgent(BetaManagedAgentsAgentParams.builder()
649 .type(BetaManagedAgentsAgentParams.Type.AGENT)
650 .id(researcher.id())
716 .multiagent(BetaManagedAgentsMultiagent20261001Params.builder()
717 .subagents(BetaManagedAgentsMultiagentSubagentsEnabledParams.builder()
718 .addPredefinedAgent(BetaManagedAgentsAgentParams.builder()
719 .type(BetaManagedAgentsAgentParams.Type.AGENT)
720 .id(researcher.id())
721 .build())
651722 .build())
652723 .build())
653724 .build()
from line 737
666737 ],
667738 );
668739 
669 $coordinator = $client->beta->agents->create(
670 name: 'coordinator',
740 $leadAgent = $client->beta->agents->create(
741 name: 'lead',
671742 model: 'claude-opus-5-5',
672743 tools: [
673744 ['type' => 'agent_toolset_20260401'],
674745 ],
675746 multiagent: [
676 'type' => 'coordinator',
677 'agents' => [
678 ['type' => 'agent', 'id' => $researchAgent->id],
747 'type' => 'multiagent_20261001',
748 'subagents' => [
749 'type' => 'enabled',
750 'predefined_agents' => [
751 ['type' => 'agent', 'id' => $researchAgent->id],
752 ],
679753 ],
680754 ],
681755 );
from line 767
693767 ]
694768 )
695769 
696 coordinator = client.beta.agents.create(
697 name: "coordinator",
770 lead_agent = client.beta.agents.create(
771 name: "lead",
698772 model: "claude-opus-5-5",
699773 tools: [
700774 {type: "agent_toolset_20260401"}
701775 ],
702776 multiagent: {
703 type: "coordinator",
704 agents: [
705 {type: "agent", id: research_agent.id}
706 ]
777 type: "multiagent_20261001",
778 subagents: {
779 type: "enabled",
780 predefined_agents: [
781 {type: "agent", id: research_agent.id}
782 ]
783 }
707784 }
708785 )
709786 ```
from line 792
715792 ```bash cURL
716793 session_id=$(curl --fail-with-body -sS "$BASE/v1/sessions" "${H[@]}" --data @- <<EOF | jq -er '.id'
717794 {
718 "agent": "$coordinator_id",
795 "agent": "$lead_agent_id",
719796 "environment_id": "$environment_id",
720797 "vault_ids": ["$vault_id"]
721798 }
from line 803
726803 
727804 ```bash CLI
728805 session_id=$(ant beta:sessions create \
729 --agent "$coordinator_id" \
806 --agent "$lead_agent_id" \
730807 --environment-id "$environment_id" \
731808 --vault-id "$vault_id" \
732809 --transform id --raw-output)
from line 812
735812 
736813 ```python Python
737814 session = client.beta.sessions.create(
738 agent=coordinator.id,
815 agent=lead_agent.id,
739816 environment_id=environment.id,
740817 vault_ids=[vault.id],
741818 )
from line 821
744821 
745822 ```typescript TypeScript
746823 const session = await client.beta.sessions.create({
747 agent: coordinator.id,
824 agent: leadAgent.id,
748825 environment_id: environment.id,
749826 vault_ids: [vault.id],
750827 });
from line 831
754831 ```csharp C#
755832 var session = await client.Beta.Sessions.Create(new()
756833 {
757 Agent = coordinator.ID,
834 Agent = leadAgent.ID,
758835 EnvironmentID = environment.ID,
759836 VaultIds = [vault.ID],
760837 });
from line 841
764841 ```go Go
765842 session, err := client.Beta.Sessions.New(ctx, anthropic.BetaSessionNewParams{
766843 Agent: anthropic.BetaSessionNewParamsAgentUnion{
767 OfString: anthropic.String(coordinator.ID),
844 OfString: anthropic.String(leadAgent.ID),
768845 },
769846 EnvironmentID: environment.ID,
770847 VaultIDs: []string{vault.ID},
from line 854
777854 
778855 ```java Java
779856 var session = client.beta().sessions().create(SessionCreateParams.builder()
780 .agent(coordinator.id())
857 .agent(leadAgent.id())
781858 .environmentId(environment.id())
782859 .vaultIds(List.of(vault.id()))
783860 .build());
from line 863
786863 
787864 ```php PHP
788865 $session = $client->beta->sessions->create(
789 agent: $coordinator->id,
866 agent: $leadAgent->id,
790867 environmentID: $environment->id,
791868 vaultIDs: [$vault->id],
792869 );
from line 872
795872 
796873 ```ruby Ruby
797874 session = client.beta.sessions.create(
798 agent: coordinator.id,
875 agent: lead_agent.id,
799876 environment_id: environment.id,
800877 vault_ids: [vault.id]
801878 )
from line 880
803880 ```
804881</CodeGroup>
805882 
806In this example, only the researcher declares the GitHub MCP server, so the coordinator does not have access. The session's `vault_ids` supply the GitHub credential to the researcher's thread.
883In this example, only the researcher declares the GitHub MCP server, so the agent that the session runs does not have access. The session's `vault_ids` supply the GitHub credential to the researcher's thread.
807884 
808885<Tip>
809886 If an agent's MCP calls fail to authenticate after you declare the server, confirm the credential's `mcp_server_url` refers to the same server as the agent's `mcp_servers[].url`. Both URLs are normalized before matching (scheme and host lowercased, default ports and trailing slashes stripped), so differences in host casing, a default port, or a trailing slash don't prevent a match; a different path, subdomain, or non-default port does.
810887</Tip>
811888 
812## Threads
813 
814The **session-level event stream** (`/v1/sessions/{session_id}/events/stream`) is considered the **primary thread**, containing a condensed view of all activity across all threads. You don't see the full activity from subagents, but you do see the start and end of their work, and blocking events such as tool permission requests.
815 
816**Session threads** are where you drill into a specific agent's activity.
817 
818The session `status` is an aggregation of all agent activity; if at least one thread is `running`, then the overall session status is `running` as well.
819 
820A [session budget](https://platform.claude.com/docs/en/managed-agents/budgets) is a single shared cap across all of a session's threads. As the cap is reached, threads pause independently, and each thread's cost is priced at the thread's own served model.
821 
822<Note>
823 A maximum of 25 concurrent threads is supported. The coordinator can call multiple copies of a single agent in the roster, creating multiple threads associated with one `agent`. [Advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) consultation threads are exempt from this limit.
824</Note>
825 
826<Tabs>
827 <Tab title="List threads">
828 List all threads associated with a session as follows:
829 
830 <CodeGroup>
831 ```bash cURL
832 curl -fsS "https://api.anthropic.com/v1/sessions/$SESSION_ID/threads" \
833 -H "x-api-key: $ANTHROPIC_API_KEY" \
834 -H "anthropic-version: 2023-06-01" \
835 -H "anthropic-beta: managed-agents-2026-04-01"
889### Threads
890 
891Each agent's session thread has its own event stream. To list, interrupt, or archive threads, read their events, and handle tool permissions across them, see [Session threads](https://platform.claude.com/docs/en/managed-agents/session-threads).
892 
893## Dynamic workflows
894 
895With dynamic workflows, an agent can take on work with many pieces, such as reviewing hundreds of documents or cross-checking many sources. The agent writes a **workflow**: a program that runs many agents in phases and combines what they return. The server runs it in the background as a **workflow run**, while the agent keeps working or ends its turn. You turn dynamic workflows on or off with the `workflows` setting in the agent's `multiagent` block. A run's agents can work at the same time, so a long task can finish sooner than if one agent did each piece in turn.
896 
897* **How a run starts:** You describe the work in a `user.message`. From that, the agent determines whether and when to start a run, so there's no additional API call. Instead, you influence the agent's determination by describing when to use a run in `user.message` or in the agent's system prompt. (Permission policies apply to the tools that a run's agents call, not to starting the run.)
898* **Which agents it uses:** [Inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents) that the workflow defines, predefined agents that you list in `workflows.predefined_agents`, or both. If you list none, the workflow defines them all. An inline agent uses the model of the agent that the session runs. To let a run use another model for some of its agents, create them as agents and list them in `workflows.predefined_agents`.
899* **How you follow it:** Run events arrive on the session's event stream, and each agent in the run works in a [session thread](https://platform.claude.com/docs/en/managed-agents/session-threads) that you can list, read, and stream. See [Workflow runs](https://platform.claude.com/docs/en/managed-agents/workflow-runs) for the events, interrupts, limits, and [what a run's threads show](https://platform.claude.com/docs/en/managed-agents/workflow-runs#a-runs-threads).
900 
901### Turn on dynamic workflows
902 
903When [defining your agent](https://platform.claude.com/docs/en/managed-agents/agent-setup), set `multiagent.type` to `"multiagent_20261001"` and enable `workflows`. Dynamic workflows and delegating (`subagents`) are both on by default with this type. For dynamic workflows only, add `"subagents": {"type": "disabled"}`.
904 
905Before you change an existing agent's `multiagent.type`, see [how to move an agent to this type](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#move-from-the-coordinator-type).
906 
907<CodeGroup defaultLanguage="CLI">
908 ```bash cURL
909 curl -fsS https://api.anthropic.com/v1/agents \
910 -H "x-api-key: $ANTHROPIC_API_KEY" \
911 -H "anthropic-version: 2023-06-01" \
912 -H "anthropic-beta: managed-agents-2026-04-01" \
913 -H "content-type: application/json" \
914 -d @- <<'EOF'
915 {
916 "name": "Contract Reviewer",
917 "model": "claude-opus-5-5",
918 "system": "You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.",
919 "tools": [{"type": "agent_toolset_20260401"}],
920 "multiagent": {"type": "multiagent_20261001", "workflows": {"type": "enabled"}}
921 }
922 EOF
923 ```
924 
925 <CodeGroupItem>
926 ```bash CLI
927 ant apply contract-reviewer.md
928 ```
929 
930 <File filename="contract-reviewer.md">
931 ```markdown
932 ---
933 name: Contract Reviewer
934 model: claude-opus-5-5
935 tools:
936 - type: agent_toolset_20260401
937 multiagent:
938 type: multiagent_20261001
939 workflows:
940 type: enabled
941 ---
942 
943 You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.
836944 ```
837 
838 ```bash CLI
839 ant beta:sessions:threads list --session-id "$SESSION_ID"
840 ```
841 
842 ```python Python
843 for thread in client.beta.sessions.threads.list(session.id):
844 agent = thread.agent
845 label = agent.type if agent.type == "advisor" else agent.name
846 print(f"[{label}] {thread.status}")
847 ```
848 
849 ```typescript TypeScript
850 for await (const thread of client.beta.sessions.threads.list(session.id)) {
851 const label = thread.agent.type === "advisor" ? thread.agent.type : thread.agent.name;
852 console.log(`[${label}] ${thread.status}`);
853 }
854 ```
855 
856 ```csharp C#
857 await foreach (var thread in (await client.Beta.Sessions.Threads.List(session.ID)).Paginate())
945 </File>
946 </CodeGroupItem>
947 
948 ```python Python
949 agent = client.beta.agents.create(
950 name="Contract Reviewer",
951 model="claude-opus-5-5",
952 system="You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.",
953 tools=[{"type": "agent_toolset_20260401"}],
954 multiagent={"type": "multiagent_20261001", "workflows": {"type": "enabled"}},
955 )
956 ```
957 
958 ```typescript TypeScript
959 const agent = await client.beta.agents.create({
960 name: "Contract Reviewer",
961 model: "claude-opus-5-5",
962 system:
963 "You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.",
964 tools: [{ type: "agent_toolset_20260401" }],
965 multiagent: { type: "multiagent_20261001", workflows: { type: "enabled" } },
966 });
967 ```
968 
969 ```csharp C#
970 var agent = await client.Beta.Agents.Create(new()
971 {
972 Name = "Contract Reviewer",
973 Model = BetaManagedAgentsModel.ClaudeOpus5_5,
974 System = "You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.",
975 Tools =
976 [
977 new BetaManagedAgentsAgentToolset20260401Params
978 {
979 Type = BetaManagedAgentsAgentToolset20260401ParamsType.AgentToolset20260401,
980 },
981 ],
982 // The configuration class sets the type for you.
983 Multiagent = new BetaManagedAgentsMultiagent20261001Params
858984 {
859 var label = thread.Agent.TryPickBetaManagedAgentsSessionThread(out var agent)
860 ? agent.Name
861 : thread.Agent.Json.GetProperty("type").GetString();
862 Console.WriteLine($"[{label}] {thread.Status.Raw()}");
863 }
864 ```
865 
866 ```go Go
867 threads := client.Beta.Sessions.Threads.ListAutoPaging(ctx, session.ID, anthropic.BetaSessionThreadListParams{})
868 for threads.Next() {
869 thread := threads.Current()
870 label := cmp.Or(thread.Agent.Name, thread.Agent.Type)
871 fmt.Printf("[%s] %s\n", label, thread.Status)
872 }
873 if err := threads.Err(); err != nil {
874 panic(err)
875 }
876 ```
877 
878 ```java Java
879 for (var thread : client.beta().sessions().threads().list(session.id()).autoPager()) {
880 var agent = thread.agent();
881 var label = agent.isAgent() ? agent.asAgent().name() : agent.type().asString();
882 IO.println("[" + label + "] " + thread.status());
883 }
884 ```
885 
886 ```php PHP
887 foreach ($client->beta->sessions->threads->list($session->id)->pagingEachItem() as $thread) {
888 $label = $thread->agent instanceof \Anthropic\Beta\Agents\BetaManagedAgentsAdvisor
889 ? $thread->agent->type
890 : $thread->agent->name;
891 echo "[{$label}] {$thread->status}\n";
892 }
893 ```
894 
895 ```ruby Ruby
896 client.beta.sessions.threads.list(session.id).auto_paging_each do |thread|
897 agent = thread.agent
898 label = agent.type == :advisor ? agent.type : agent.name
899 puts "[#{label}] #{thread.status}"
900 end
901 ```
902 </CodeGroup>
903 
904 The full list includes the primary thread. `parent_thread_id` is null for the primary thread.
905 </Tab>
906 
907 <Tab title="Interrupt a session thread">
908 Send `user.interrupt` with `session_thread_id` to stop a specific thread. Omitting `session_thread_id` interrupts every non-archived thread in the session, including the primary.
909 
910 <CodeGroup>
911 ```bash cURL
912 curl -fsS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
913 -H "x-api-key: $ANTHROPIC_API_KEY" \
914 -H "anthropic-version: 2023-06-01" \
915 -H "anthropic-beta: managed-agents-2026-04-01" \
916 -H "content-type: application/json" \
917 -d "{\"events\": [{\"type\": \"user.interrupt\", \"session_thread_id\": \"$THREAD_ID\"}]}"
918 ```
919 
920 ```bash CLI
921 ant beta:sessions:events send \
922 --session-id "$SESSION_ID" \
923 --event "{type: user.interrupt, session_thread_id: $THREAD_ID}"
924 ```
925 
926 ```python Python
927 client.beta.sessions.events.send(
928 session.id,
929 events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
930 )
931 ```
932 
933 ```typescript TypeScript
934 await client.beta.sessions.events.send(session.id, {
935 events: [{ type: "user.interrupt", session_thread_id: thread.id }],
936 });
937 ```
938 
939 ```csharp C#
940 await client.Beta.Sessions.Events.Send(session.ID, new()
941 {
942 Events =
943 [
944 new BetaManagedAgentsUserInterruptEventParams
945 {
946 Type = BetaManagedAgentsUserInterruptEventParamsType.UserInterrupt,
947 SessionThreadID = thread.ID,
948 },
949 ],
950 });
951 ```
952 
953 ```go Go
954 if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
955 Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
956 OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{
957 Type: anthropic.BetaManagedAgentsUserInterruptEventParamsTypeUserInterrupt,
958 SessionThreadID: anthropic.String(thread.ID),
959 },
960 }},
961 }); err != nil {
962 panic(err)
963 }
964 ```
965 
966 ```java Java
967 client.beta().sessions().events().send(
968 session.id(),
969 EventSendParams.builder()
970 .addEvent(BetaManagedAgentsUserInterruptEventParams.builder()
971 .type(BetaManagedAgentsUserInterruptEventParams.Type.USER_INTERRUPT)
972 .sessionThreadId(thread.id())
973 .build())
974 .build());
975 ```
976 
977 ```php PHP
978 $client->beta->sessions->events->send(
979 $session->id,
980 events: [
981 ['type' => 'user.interrupt', 'session_thread_id' => $thread->id],
982 ],
983 );
984 ```
985 
986 ```ruby Ruby
987 client.beta.sessions.events.send_(
988 session.id,
989 events: [{type: "user.interrupt", session_thread_id: thread.id}]
990 )
991 ```
992 </CodeGroup>
993 
994 Against a child thread blocked on `requires_action`, the interrupt closes each pending tool call with an error tool result ("Tool execution was interrupted before completion. Please retry.") and re-emits `session.thread_status_idle` with `stop_reason: end_turn` directly; the model is not sampled. Against a thread already at `idle`, the interrupt is a no-op.
995 </Tab>
996 
997 <Tab title="Archive a session thread">
998 Optionally archive a session thread when it has completed its work. This frees up a thread against the 25-thread limit.
999 
1000 <CodeGroup>
1001 ```bash cURL
1002 curl -fsS -X POST "https://api.anthropic.com/v1/sessions/$SESSION_ID/threads/$THREAD_ID/archive" \
1003 -H "x-api-key: $ANTHROPIC_API_KEY" \
1004 -H "anthropic-version: 2023-06-01" \
1005 -H "anthropic-beta: managed-agents-2026-04-01"
1006 ```
1007 
1008 ```bash CLI
1009 ant beta:sessions:threads archive \
1010 --session-id "$SESSION_ID" \
1011 --thread-id "$THREAD_ID"
1012 ```
1013 
1014 ```python Python
1015 archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
1016 print(archived.status, archived.archived_at)
1017 ```
1018 
1019 ```typescript TypeScript
1020 const archived = await client.beta.sessions.threads.archive(thread.id, {
1021 session_id: session.id,
1022 });
1023 console.log(archived.status, archived.archived_at);
1024 ```
1025 
1026 ```csharp C#
1027 var archived = await client.Beta.Sessions.Threads.Archive(thread.ID, new() { SessionID = session.ID });
1028 Console.WriteLine($"{archived.Status} {archived.ArchivedAt}");
1029 ```
1030 
1031 ```go Go
1032 archived, err := client.Beta.Sessions.Threads.Archive(ctx, thread.ID, anthropic.BetaSessionThreadArchiveParams{
1033 SessionID: session.ID,
1034 })
1035 if err != nil {
1036 panic(err)
1037 }
1038 fmt.Println(archived.Status, archived.ArchivedAt)
1039 ```
1040 
1041 ```java Java
1042 var archived = client.beta().sessions().threads().archive(
1043 thread.id(),
1044 ThreadArchiveParams.builder()
1045 .sessionId(session.id())
1046 .build());
1047 IO.println(archived.status() + " " + archived.archivedAt().orElseThrow());
1048 ```
1049 
1050 ```php PHP
1051 $archived = $client->beta->sessions->threads->archive($thread->id, sessionID: $session->id);
1052 echo "{$archived->status} {$archived->archivedAt->format(DATE_ATOM)}\n";
1053 ```
1054 
1055 ```ruby Ruby
1056 archived = client.beta.sessions.threads.archive(thread.id, session_id: session.id)
1057 puts "#{archived.status} #{archived.archived_at}"
1058 ```
1059 </CodeGroup>
1060 
1061 Archive only succeeds if the thread is `idle`. A thread parked on `requires_action` counts as idle and can be archived directly; only a running thread must be interrupted first:
1062 
1063 <CodeGroup>
1064 ```bash cURL
1065 # Interrupt the thread, then archive it
1066 curl -fsS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
1067 -H "x-api-key: $ANTHROPIC_API_KEY" \
1068 -H "anthropic-version: 2023-06-01" \
1069 -H "anthropic-beta: managed-agents-2026-04-01" \
1070 -H "content-type: application/json" \
1071 -d "{\"events\": [{\"type\": \"user.interrupt\", \"session_thread_id\": \"$THREAD_ID\"}]}"
1072 
1073 curl -fsS -X POST "https://api.anthropic.com/v1/sessions/$SESSION_ID/threads/$THREAD_ID/archive" \
1074 -H "x-api-key: $ANTHROPIC_API_KEY" \
1075 -H "anthropic-version: 2023-06-01" \
1076 -H "anthropic-beta: managed-agents-2026-04-01"
1077 ```
1078 
1079 ```bash CLI
1080 ant beta:sessions:events send \
1081 --session-id "$SESSION_ID" \
1082 --event "{type: user.interrupt, session_thread_id: $THREAD_ID}"
1083 
1084 ant beta:sessions:threads archive \
1085 --session-id "$SESSION_ID" \
1086 --thread-id "$THREAD_ID"
1087 ```
1088 
1089 ```python Python
1090 client.beta.sessions.events.send(
1091 session.id,
1092 events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
1093 )
1094 archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
1095 print(archived.status, archived.archived_at)
1096 ```
1097 
1098 ```typescript TypeScript
1099 await client.beta.sessions.events.send(session.id, {
1100 events: [{ type: "user.interrupt", session_thread_id: thread.id }],
1101 });
1102 const archived = await client.beta.sessions.threads.archive(thread.id, {
1103 session_id: session.id,
1104 });
1105 console.log(archived.status, archived.archived_at);
1106 ```
1107 
1108 ```csharp C#
1109 await client.Beta.Sessions.Events.Send(session.ID, new()
1110 {
1111 Events =
1112 [
1113 new BetaManagedAgentsUserInterruptEventParams
1114 {
1115 Type = BetaManagedAgentsUserInterruptEventParamsType.UserInterrupt,
1116 SessionThreadID = thread.ID,
1117 },
1118 ],
1119 });
1120 archived = await client.Beta.Sessions.Threads.Archive(thread.ID, new() { SessionID = session.ID });
1121 Console.WriteLine($"{archived.Status} {archived.ArchivedAt}");
1122 ```
1123 
1124 ```go Go
1125 if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
1126 Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
1127 OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{
1128 Type: anthropic.BetaManagedAgentsUserInterruptEventParamsTypeUserInterrupt,
1129 SessionThreadID: anthropic.String(thread.ID),
1130 },
1131 }},
1132 }); err != nil {
1133 panic(err)
1134 }
1135 
1136 archived, err := client.Beta.Sessions.Threads.Archive(ctx, thread.ID, anthropic.BetaSessionThreadArchiveParams{
1137 SessionID: session.ID,
1138 })
1139 if err != nil {
1140 panic(err)
1141 }
1142 fmt.Println(archived.Status, archived.ArchivedAt)
1143 ```
1144 
1145 ```java Java
1146 client.beta().sessions().events().send(
1147 session.id(),
1148 EventSendParams.builder()
1149 .addEvent(BetaManagedAgentsUserInterruptEventParams.builder()
1150 .type(BetaManagedAgentsUserInterruptEventParams.Type.USER_INTERRUPT)
1151 .sessionThreadId(thread.id())
1152 .build())
1153 .build());
1154 
1155 archived = client.beta().sessions().threads().archive(
1156 thread.id(),
1157 ThreadArchiveParams.builder()
1158 .sessionId(session.id())
1159 .build());
1160 IO.println(archived.status() + " " + archived.archivedAt().orElseThrow());
1161 ```
1162 
1163 ```php PHP
1164 $client->beta->sessions->events->send(
1165 $session->id,
1166 events: [['type' => 'user.interrupt', 'session_thread_id' => $thread->id]],
1167 );
1168 $archived = $client->beta->sessions->threads->archive($thread->id, sessionID: $session->id);
1169 echo "{$archived->status} {$archived->archivedAt->format(DATE_ATOM)}\n";
1170 ```
1171 
1172 ```ruby Ruby
1173 client.beta.sessions.events.send_(
1174 session.id,
1175 events: [{type: "user.interrupt", session_thread_id: thread.id}]
1176 )
1177 archived = client.beta.sessions.threads.archive(thread.id, session_id: session.id)
1178 puts "#{archived.status} #{archived.archived_at}"
1179 ```
1180 </CodeGroup>
1181 </Tab>
1182</Tabs>
1183 
1184### Primary thread events
1185 
1186These events surface multiagent activity on the primary thread at `/v1/sessions/{session_id}/events/stream`. Message-direction events are named relative to the thread whose stream they appear on: `agent.thread_message_received` means a message arrived on this thread from another thread, and `agent.thread_message_sent` means this thread sent one. The task the coordinator delegates, for example, arrives on the child's own stream as an `agent.thread_message_received` event.
1187 
1188| Type | Description |
1189| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
1190| `session.thread_created` | A thread was created. Includes `session_thread_id` and `agent_name`. |
1191| `session.thread_status_running` | A thread started activity. |
1192| `session.thread_status_idle` | The agent associated with the thread is awaiting input. Includes a `stop_reason` indicating why the agent stopped. |
1193| `session.thread_status_terminated` | A thread was archived or encountered a terminal error. |
1194| `agent.thread_message_received` | On the primary thread, an agent sent a report or question to the coordinator. Includes `from_session_thread_id`, `from_agent_name`, and `content`. |
1195| `agent.thread_message_sent` | On the primary thread, the coordinator sent a task or follow-up message to another agent. Includes `to_session_thread_id`, `to_agent_name`, and `content`. |
1196 
1197Advisor consultations emit these same thread events under the reserved name `anthropic.advisor` (as `agent_name` on the thread lifecycle events and `from_agent_name` on the advice delivery); see [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) for the sequence.
1198 
1199### Session thread events
1200 
1201Critical events are proxied to the primary thread. However, you might still want to investigate a specific agent's reasoning and tool calls. To do so, stream or list the events from the associated session thread.
1202 
1203Each session thread has its own event stream at `/v1/sessions/{session_id}/threads/{thread_id}/stream`, and it accepts the same `event_deltas[]` parameter as the session-level stream, so you can preview a subagent's text as the model generates it. A connection previews only the thread it's reading: a child thread's previews never appear on the session-level stream, so to watch a subagent live, open its own thread stream. See [Preview session thread events](https://platform.claude.com/docs/en/managed-agents/event-deltas#preview-session-thread-events) for opting in, accumulating, and reconciling previews.
1204 
1205<Tabs>
1206 <Tab title="Stream session thread events">
1207 <CodeGroup>
1208 ```bash cURL
1209 curl -fsSN "https://api.anthropic.com/v1/sessions/$SESSION_ID/threads/$THREAD_ID/stream?beta=true" \
1210 -H "x-api-key: $ANTHROPIC_API_KEY" \
1211 -H "anthropic-version: 2023-06-01" \
1212 -H "anthropic-beta: managed-agents-2026-04-01" |
1213 while IFS= read -r line; do
1214 [[ $line == data:* ]] || continue
1215 json=${line#data: }
1216 case $(jq -r '.type' <<<"$json") in
1217 agent.message)
1218 printf '%s' "$(jq -j '.content[] | select(.type == "text") | .text' <<<"$json")"
1219 ;;
1220 session.thread_status_idle)
1221 break
1222 ;;
1223 esac
1224 done
1225 ```
1226 
1227 ```bash CLI
1228 ant beta:sessions:threads:events stream \
1229 --session-id "$SESSION_ID" \
1230 --thread-id "$THREAD_ID"
1231 ```
1232 
1233 ```python Python
1234 with client.beta.sessions.threads.events.stream(
1235 thread.id,
1236 session_id=session.id,
1237 ) as stream:
1238 for event in stream:
1239 match event.type:
1240 case "agent.message":
1241 for block in event.content:
1242 if block.type == "text":
1243 print(block.text, end="")
1244 case "session.thread_status_idle":
1245 break
1246 ```
1247 
1248 ```typescript TypeScript
1249 const stream = await client.beta.sessions.threads.events.stream(thread.id, {
1250 session_id: session.id,
1251 });
1252 
1253 loop: for await (const event of stream) {
1254 switch (event.type) {
1255 case "agent.message":
1256 for (const block of event.content) {
1257 if (block.type === "text") {
1258 process.stdout.write(block.text);
1259 }
1260 }
1261 break;
1262 case "session.thread_status_idle":
1263 break loop;
1264 }
1265 }
1266 ```
1267 
1268 ```csharp C#
1269 await foreach (var evt in client.Beta.Sessions.Threads.Events.StreamStreaming(thread.ID, new() { SessionID = session.ID }))
1270 {
1271 if (evt.Value is BetaManagedAgentsAgentMessageEvent message)
1272 {
1273 foreach (var block in message.Content)
1274 {
1275 if (block.Type == "text")
1276 {
1277 Console.Write(block.Text);
1278 }
1279 }
1280 }
1281 else if (evt.Value is BetaManagedAgentsSessionThreadStatusIdleEvent)
1282 {
1283 break;
1284 }
1285 }
1286 ```
1287 
1288 ```go Go
1289 stream := client.Beta.Sessions.Threads.Events.StreamEvents(ctx, thread.ID, anthropic.BetaSessionThreadEventStreamParams{
1290 SessionID: session.ID,
1291 })
1292 defer stream.Close()
1293 
1294 loop:
1295 for stream.Next() {
1296 event := stream.Current()
1297 switch event.Type {
1298 case "agent.message":
1299 for _, block := range event.AsAgentMessage().Content {
1300 if block.Type == "text" {
1301 fmt.Print(block.Text)
1302 }
1303 }
1304 case "session.thread_status_idle":
1305 break loop
1306 }
1307 }
1308 if err := stream.Err(); err != nil {
1309 panic(err)
1310 }
1311 ```
1312 
1313 ```java Java
1314 try (var streamResponse = client.beta().sessions().threads().events().streamStreaming(
1315 thread.id(),
1316 EventStreamParams.builder().sessionId(session.id()).build()
1317 )) {
1318 loop:
1319 for (var event : (Iterable<BetaManagedAgentsStreamSessionThreadEvents>) streamResponse.stream()::iterator) {
1320 switch (event.type().value()) {
1321 case AGENT_MESSAGE -> {
1322 for (var block : event.asAgentMessage().content()) {
1323 block.text().ifPresent(textBlock -> IO.print(textBlock.text()));
1324 }
1325 }
1326 case SESSION_THREAD_STATUS_IDLE -> {
1327 break loop;
1328 }
1329 }
1330 }
1331 }
1332 ```
1333 
1334 ```php PHP
1335 $stream = $client->beta->sessions->threads->events->streamStream(
1336 $thread->id,
1337 sessionID: $session->id,
1338 );
1339 
1340 foreach ($stream as $event) {
1341 switch (true) {
1342 case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsAgentMessageEvent:
1343 foreach ($event->content as $block) {
1344 if ($block instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock) {
1345 echo $block->text;
1346 }
1347 }
1348 break;
1349 case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionThreadStatusIdleEvent:
1350 break 2;
1351 }
1352 }
1353 ```
1354 
1355 ```ruby Ruby
1356 client.beta.sessions.threads.events.stream_events(thread.id, session_id: session.id).each do |event|
1357 case event
1358 when Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent
1359 event.content.each do |block|
1360 print block.text if block.is_a?(Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock)
1361 end
1362 when Anthropic::Beta::Sessions::BetaManagedAgentsSessionThreadStatusIdleEvent
1363 break
1364 end
1365 end
1366 ```
1367 </CodeGroup>
1368 </Tab>
1369 
1370 <Tab title="List session thread events">
1371 List all past session thread events to pull a complete history.
1372 
1373 <CodeGroup>
1374 ```bash cURL
1375 curl -fsS "https://api.anthropic.com/v1/sessions/$SESSION_ID/threads/$THREAD_ID/events" \
1376 -H "x-api-key: $ANTHROPIC_API_KEY" \
1377 -H "anthropic-version: 2023-06-01" \
1378 -H "anthropic-beta: managed-agents-2026-04-01" \
1379 | jq -r '.data[] | "[\(.type)] \(.processed_at)"'
1380 ```
1381 
1382 ```bash CLI
1383 ant beta:sessions:threads:events list \
1384 --session-id "$SESSION_ID" \
1385 --thread-id "$THREAD_ID"
1386 ```
1387 
1388 ```python Python
1389 for event in client.beta.sessions.threads.events.list(
1390 thread.id,
1391 session_id=session.id,
1392 ):
1393 print(f"[{event.type}] {event.processed_at}")
1394 ```
1395 
1396 ```typescript TypeScript
1397 for await (const event of client.beta.sessions.threads.events.list(thread.id, {
1398 session_id: session.id,
1399 })) {
1400 console.log(`[${event.type}] ${event.processed_at}`);
1401 }
1402 ```
1403 
1404 ```csharp C#
1405 var page = await client.Beta.Sessions.Threads.Events.List(thread.ID, new() { SessionID = session.ID });
1406 await foreach (var evt in page.Paginate())
1407 {
1408 Console.WriteLine($"[{evt.Type}] {evt.ProcessedAt}");
1409 }
1410 ```
1411 
1412 ```go Go
1413 pager := client.Beta.Sessions.Threads.Events.ListAutoPaging(ctx, thread.ID, anthropic.BetaSessionThreadEventListParams{
1414 SessionID: session.ID,
1415 })
1416 for pager.Next() {
1417 event := pager.Current()
1418 fmt.Printf("[%s] %s\n", event.Type, event.ProcessedAt)
1419 }
1420 if err := pager.Err(); err != nil {
1421 panic(err)
1422 }
1423 ```
1424 
1425 ```java Java
1426 for (var event : client.beta().sessions().threads().events().list(
1427 thread.id(),
1428 EventListParams.builder().sessionId(session.id()).build()
1429 ).autoPager()) {
1430 var type = event._json().orElseThrow() instanceof JsonObject json
1431 ? json.values().get("type").asStringOrThrow()
1432 : "unknown";
1433 var processedAt = event.processedAt().map(OffsetDateTime::toString).orElse("pending");
1434 IO.println("[" + type + "] " + processedAt);
1435 }
1436 ```
1437 
1438 ```php PHP
1439 foreach (
1440 $client->beta->sessions->threads->events->list(
1441 $thread->id,
1442 sessionID: $session->id,
1443 )->pagingEachItem() as $event
1444 ) {
1445 echo "[{$event->type}] {$event->processedAt->format(DATE_RFC3339)}\n";
1446 }
1447 ```
1448 
1449 ```ruby Ruby
1450 client.beta.sessions.threads.events.list(
1451 thread.id,
1452 session_id: session.id
1453 ).auto_paging_each do |event|
1454 puts "[#{event.type}] #{event.processed_at}"
1455 end
1456 ```
1457 </CodeGroup>
1458 </Tab>
1459</Tabs>
1460 
1461### Tool permissions and custom tools
1462 
1463If a subagent needs something from your client, such as [permission](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#tool-confirmation) to run a tool call or the [result of a custom tool](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#handling-custom-tool-calls), the event is cross-posted to the **primary thread** with `session_thread_id` identifying the originating session thread. A tool call needs your permission under `always_ask`, or under [`auto`](https://platform.claude.com/docs/en/managed-agents/permission-policies#let-the-server-evaluate-each-call-with-auto) when the server reaches no determination.
985 Workflows = new BetaManagedAgentsMultiagentWorkflowsEnabledParams(),
986 },
987 });
988 ```
989 
990 ```go Go
991 agent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
992 Name: "Contract Reviewer",
993 Model: anthropic.BetaManagedAgentsModelConfigParams{ID: anthropic.BetaManagedAgentsModelClaudeOpus5_5},
994 System: anthropic.String("You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run."),
995 Tools: []anthropic.BetaAgentNewParamsToolUnion{{
996 OfAgentToolset20260401: &anthropic.BetaManagedAgentsAgentToolset20260401Params{
997 Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
998 },
999 }},
1000 Multiagent: anthropic.BetaManagedAgentsMultiagentParamsUnion{
1001 OfMultiagent20261001: &anthropic.BetaManagedAgentsMultiagent20261001Params{
1002 Workflows: anthropic.BetaManagedAgentsMultiagentWorkflowsParamsUnion{
1003 OfEnabled: &anthropic.BetaManagedAgentsMultiagentWorkflowsEnabledParams{},
1004 },
1005 },
1006 },
1007 })
1008 if err != nil {
1009 panic(err)
1010 }
1011 ```
1012 
1013 ```java Java
1014 var agent = client.beta().agents().create(
1015 AgentCreateParams.builder()
1016 .name("Contract Reviewer")
1017 .model(BetaManagedAgentsModel.CLAUDE_OPUS_5_5)
1018 .system("You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.")
1019 .addTool(
1020 BetaManagedAgentsAgentToolset20260401Params.builder()
1021 .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
1022 .build()
1023 )
1024 // The configuration class sets the type for you.
1025 .multiagent(BetaManagedAgentsMultiagent20261001Params.builder()
1026 .workflows(BetaManagedAgentsMultiagentWorkflowsEnabledParams.builder().build())
1027 .build())
1028 .build()
1029 );
1030 ```
1031 
1032 ```php PHP
1033 $agent = $client->beta->agents->create(
1034 name: 'Contract Reviewer',
1035 model: 'claude-opus-5-5',
1036 system: "You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.",
1037 tools: [
1038 ['type' => 'agent_toolset_20260401'],
1039 ],
1040 multiagent: ['type' => 'multiagent_20261001', 'workflows' => ['type' => 'enabled']],
1041 );
1042 ```
1043 
1044 ```ruby Ruby
1045 agent = client.beta.agents.create(
1046 name: "Contract Reviewer",
1047 model: "claude-opus-5-5",
1048 system_: "You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.",
1049 tools: [
1050 {type: "agent_toolset_20260401"}
1051 ],
1052 multiagent: {type: "multiagent_20261001", workflows: {type: "enabled"}}
1053 )
1054 ```
1055</CodeGroup>
1056 
1057To let a workflow use agents you've already created, list them in `workflows.predefined_agents`. The `subagents` and `advisor` settings go in the same `multiagent` block. To list subagents, see [Delegate to subagents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#delegate-to-subagents). To set an advisor, see [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor). This agent lets a workflow use one agent you created, lists two subagents, and has an advisor:
14641058 
14651059```json
14661060{
1467 "type": "session.thread_status_idle",
1468 "id": "sevt_01ABC...",
1469 "session_thread_id": "sth_01DEF...",
1470 "agent_name": "code-reviewer",
1471 "stop_reason": {
1472 "type": "requires_action",
1473 "event_ids": ["sevt_01XYZ..."]
1061 "multiagent": {
1062 "type": "multiagent_20261001",
1063 "workflows": {
1064 "type": "enabled",
1065 "predefined_agents": [{ "type": "agent", "id": "agent_01Lm4cV8yQ2tNs7XbKdR5h" }]
1066 },
1067 "subagents": {
1068 "type": "enabled",
1069 "predefined_agents": [
1070 { "type": "agent", "id": "agent_01J8XkN5uT3vHpLqRfWdY2" },
1071 { "type": "agent", "id": "agent_01HqR2k7vXbZ9mNpL3wYcT" }
1072 ]
1073 },
1074 "advisor": { "type": "enabled", "model": "claude-opus-5-5" }
14741075 }
14751076}
14761077```
14771078 
1478Post `user.tool_confirmation` (with `tool_use_id`) or `user.custom_tool_result` (with `custom_tool_use_id`); the server routes the response to the correct thread automatically.
1479 
1480The session goes `idle` only when no thread is `running`, so `session.status_idle` can arrive long after a subagent's call. You don't have to wait for it: send the `user.custom_tool_result` as soon as the cross-posted `agent.custom_tool_use` event arrives.
1481 
1482Under `auto`, your `user.message` events can lead the server to allow a call it would otherwise deny. Nothing in a subagent's thread counts as your intent: your client posts no messages there, and the coordinator's messages to the subagent do not count. When the server denies a call under `auto`, nothing is cross-posted: the event and the error tool result appear only on the subagent's own [thread stream](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#session-thread-events), and the subagent keeps running.
1483 
1484The following example extends the [tool confirmation handler](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#tool-confirmation) to route replies. The same pattern applies to `user.custom_tool_result`.
1485 
1486<CodeGroup>
1079Each setting is enabled or disabled on its own:
1080 
1081| Setting | What it turns on | Agents go in | Default |
1082| ----------- | --------------------------------------------------------------------------------- | --------------------------------------- | -------- |
1083| `workflows` | Dynamic workflows | `workflows.predefined_agents`, up to 20 | Enabled |
1084| `subagents` | Delegating to subagents: the agents you list, and agents the agent defines itself | `subagents.predefined_agents`, up to 20 | Enabled |
1085| `advisor` | An advisor model | None. Set `model`. | Disabled |
1086 
1087For what goes in each list, and for how to allow only the agents that you list, see [Predefined and inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents).
1088 
1089Keep the following in mind:
1090 
1091* **Updating:** An update that keeps the `multiagent_20261001` type changes only what it sends:
1092 
1093 * A setting or field you leave out keeps its stored value.
1094 * A setting or field you send as `null` takes its default, and so does everything inside it, whatever you had stored.
1095 * A `predefined_agents` list you send replaces the stored list.
1096 * A setting you send with a different `type` replaces the stored setting, and the fields you leave out of it take their defaults.
1097 * Every object you send needs its `type`, and an enabled `advisor` needs its `model`.
1098 
1099* **Turning it off:** Set `workflows` to `{"type": "disabled"}`. It stays off until an update turns it on again. Sending `null` turns it on, because its default is enabled. The same applies to `subagents`.
1100 
1101* **Existing sessions:** A session copies the setting when it is created, so changing the agent later doesn't change a session that already exists.
1102 
1103* **Agents you can list:** An agent that has `multiagent` set can't be listed as a subagent of another agent, or in another agent's `workflows.predefined_agents`. An agent can list itself in either list with `{"type": "self"}`, which reads back as its own `id` and `version`.
1104 
1105* **Tool names:** The `ant__` prefix is reserved. If your agent already has a custom tool whose name starts with `ant__`, every update fails with a 400 error until you send `tools` without that name. A new session is refused with a 400 error too if its agent, or an agent in either list, has such a tool. Rename or remove the tool in the same update that turns dynamic workflows on. See [Custom tools](https://platform.claude.com/docs/en/managed-agents/tools#custom-tools).
1106 
1107* **Budget:** Set a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets) when you create the session to cap the session's spend, runs included; you can't add one to an existing session. Runs pause when the session reaches the budget, and runs that the budget paused resume when you raise or remove it. See [Budgets and limits](https://platform.claude.com/docs/en/managed-agents/workflow-runs#budgets-and-limits).
1108 
1109### Tell the agent when to use a run
1110 
1111Turning dynamic workflows on gives the agent the ability to start workflow runs. The agent determines when to start one. To guide that choice, add an instruction like the following to the agent's system prompt. The contract-review agent in [Turn on dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#turn-on-dynamic-workflows) uses this system prompt:
1112 
1113```text wrap
1114You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.
1115```
1116 
1117To adapt it, name the tasks in your agent's domain that call for a run, and the small tasks the agent should do itself. You can also guide how a run does the work, as in these examples:
1118 
1119* **How to split the work:** "In a run, use one agent per contract. Then have a second agent review every contract, not only the ones where the first agent found something, and look for what the first agent missed. Anything that fails the review gets redone and reviewed again."
1120* **What to do when an agent fails:** "One agent failing must not fail the run. If an agent fails to read a contract, list that contract as not covered."
1121* **A time limit:** "Give the run a one-hour time limit."
1122 
1123Keep runs to the tasks that need them, because every agent in a run uses tokens.
1124 
1125Then [create a session](https://platform.claude.com/docs/en/managed-agents/sessions) with the agent, as you would with any agent, and describe the work in a `user.message`. You can also ask for a run in that message.
1126 
1127For a run's events, interrupting a session with runs open, what changes while a run is open, and budgets and limits, see [Workflow runs](https://platform.claude.com/docs/en/managed-agents/workflow-runs).
1128 
1129## Give the session an advisor
1130 
1131An enabled `advisor` setting in the agent's `multiagent` block gives the session's primary thread an **advisor**: a model it can consult mid-turn for strategic guidance, such as planning an approach, getting unstuck, or reviewing work before finishing. The setting is disabled by default. To enable it, set `advisor` to `{"type": "enabled", "model": "..."}`, which has exactly two fields, `type` and `model`:
1132 
1133<CodeGroup defaultLanguage="CLI">
14871134 ```bash cURL
1488 while IFS= read -r event_id; do
1489 jq -n --arg id "$event_id" \
1490 '{events: [{type: "user.tool_confirmation", tool_use_id: $id, result: "allow"}]}' |
1491 curl -fsS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
1492 -H "x-api-key: $ANTHROPIC_API_KEY" \
1493 -H "anthropic-version: 2023-06-01" \
1494 -H "anthropic-beta: managed-agents-2026-04-01" \
1495 -H "content-type: application/json" \
1496 -d @-
1497 done < <(jq -r '.stop_reason.event_ids[]' <<<"$data")
1498 ```
1499 
1500 ```bash CLI
1501 # This workflow does not translate well to a one-off shell command.
1502 # Use one of the SDK examples in this code group instead.
1503 ```
1135 curl -fsS https://api.anthropic.com/v1/agents \
1136 -H "x-api-key: $ANTHROPIC_API_KEY" \
1137 -H "anthropic-version: 2023-06-01" \
1138 -H "anthropic-beta: managed-agents-2026-04-01" \
1139 -H "content-type: application/json" \
1140 -d '{
1141 "name": "Backend engineer",
1142 "model": "claude-sonnet-5",
1143 "system": "You implement backend features end to end. Consult the advisor before major backend design decisions.",
1144 "multiagent": {
1145 "type": "multiagent_20261001",
1146 "advisor": {"type": "enabled", "model": "claude-opus-5-5"}
1147 }
1148 }'
1149 ```
1150 
1151 <CodeGroupItem>
1152 ```bash CLI
1153 ant apply backend-engineer.md
1154 ```
1155 
1156 <File filename="backend-engineer.md">
1157 ```markdown
1158 ---
1159 name: Backend engineer
1160 model: claude-sonnet-5
1161 multiagent:
1162 type: multiagent_20261001
1163 advisor:
1164 type: enabled
1165 model: claude-opus-5-5
1166 ---
1167 
1168 You implement backend features end to end. Consult the advisor before major backend design decisions.
1169 ```
1170 </File>
1171 </CodeGroupItem>
15041172 
15051173 ```python Python
1506 for event_id in stop.event_ids:
1507 client.beta.sessions.events.send(
1508 session.id,
1509 events=[
1510 {
1511 "type": "user.tool_confirmation",
1512 "tool_use_id": event_id,
1513 "result": "allow",
1514 }
1515 ],
1516 )
1174 agent = client.beta.agents.create(
1175 name="Backend engineer",
1176 model="claude-sonnet-5",
1177 system="You implement backend features end to end. Consult the advisor before major backend design decisions.",
1178 multiagent={
1179 "type": "multiagent_20261001",
1180 "advisor": {"type": "enabled", "model": "claude-opus-5-5"},
1181 },
1182 )
1183 print(agent.id)
15171184 ```
15181185 
15191186 ```typescript TypeScript
1520 for (const eventId of stop.event_ids) {
1521 await client.beta.sessions.events.send(session.id, {
1522 events: [
1523 {
1524 type: "user.tool_confirmation",
1525 tool_use_id: eventId,
1526 result: "allow",
1527 },
1528 ],
1529 });
1530 }
1187 const agent = await client.beta.agents.create({
1188 name: "Backend engineer",
1189 model: "claude-sonnet-5",
1190 system:
1191 "You implement backend features end to end. Consult the advisor before major backend design decisions.",
1192 multiagent: {
1193 type: "multiagent_20261001",
1194 advisor: { type: "enabled", model: "claude-opus-5-5" },
1195 },
1196 });
1197 console.log(agent.id);
15311198 ```
15321199 
15331200 ```csharp C#
1534 foreach (var eventId in requiresAction.EventIds)
1201 var agent = await client.Beta.Agents.Create(new()
15351202 {
1536 await client.Beta.Sessions.Events.Send(session.ID, new()
1203 Name = "Backend engineer",
1204 Model = BetaManagedAgentsModel.ClaudeSonnet5,
1205 System = "You implement backend features end to end. Consult the advisor before major backend design decisions.",
1206 Multiagent = new BetaManagedAgentsMultiagent20261001Params
15371207 {
1538 Events =
1539 [
1540 new BetaManagedAgentsUserToolConfirmationEventParams
1541 {
1542 Type = BetaManagedAgentsUserToolConfirmationEventParamsType.UserToolConfirmation,
1543 ToolUseID = eventId,
1544 Result = BetaManagedAgentsUserToolConfirmationEventParamsResult.Allow,
1545 },
1546 ],
1547 });
1548 }
1208 Advisor = new BetaManagedAgentsMultiagentAdvisorEnabledParams { Model = "claude-opus-5-5" },
1209 },
1210 });
1211 Console.WriteLine(agent.ID);
15491212 ```
15501213 
15511214 ```go Go
1552 for _, eventID := range stopReason.EventIDs {
1553 params := anthropic.BetaManagedAgentsUserToolConfirmationEventParams{
1554 Type: anthropic.BetaManagedAgentsUserToolConfirmationEventParamsTypeUserToolConfirmation,
1555 ToolUseID: eventID,
1556 Result: anthropic.BetaManagedAgentsUserToolConfirmationEventParamsResultAllow,
1557 }
1558 if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
1559 Events: []anthropic.BetaManagedAgentsEventParamsUnion{{OfUserToolConfirmation: &params}},
1560 }); err != nil {
1561 panic(err)
1562 }
1563 }
1215 agent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
1216 Name: "Backend engineer",
1217 Model: anthropic.BetaManagedAgentsModelConfigParams{ID: anthropic.BetaManagedAgentsModelClaudeSonnet5},
1218 System: anthropic.String("You implement backend features end to end. Consult the advisor before major backend design decisions."),
1219 Multiagent: anthropic.BetaManagedAgentsMultiagentParamsUnion{
1220 OfMultiagent20261001: &anthropic.BetaManagedAgentsMultiagent20261001Params{
1221 Advisor: anthropic.BetaManagedAgentsMultiagentAdvisorParamsUnion{
1222 OfEnabled: &anthropic.BetaManagedAgentsMultiagentAdvisorEnabledParams{
1223 Model: "claude-opus-5-5",
1224 },
1225 },
1226 },
1227 },
1228 })
1229 if err != nil {
1230 panic(err)
1231 }
1232 fmt.Println(agent.ID)
15641233 ```
15651234 
15661235 ```java Java
1567 for (var eventId : pendingToolUseIds) {
1568 client.beta().sessions().events().send(
1569 session.id(),
1570 EventSendParams.builder()
1571 .addEvent(BetaManagedAgentsUserToolConfirmationEventParams.builder()
1572 .toolUseId(eventId)
1573 .result(BetaManagedAgentsUserToolConfirmationEventParams.Result.ALLOW)
1236 var agent = client.beta().agents().create(
1237 AgentCreateParams.builder()
1238 .name("Backend engineer")
1239 .model(BetaManagedAgentsModel.CLAUDE_SONNET_5)
1240 .system("You implement backend features end to end. Consult the advisor before major backend design decisions.")
1241 .multiagent(BetaManagedAgentsMultiagent20261001Params.builder()
1242 .advisor(BetaManagedAgentsMultiagentAdvisorEnabledParams.builder()
1243 .model("claude-opus-5-5")
15741244 .build())
1575 .build()
1576 );
1577 }
1245 .build())
1246 .build()
1247 );
1248 IO.println(agent.id());
15781249 ```
15791250 
15801251 ```php PHP
1581 foreach ($event->stopReason->eventIDs as $eventId) {
1582 $client->beta->sessions->events->send($session->id, events: [[
1583 'type' => 'user.tool_confirmation',
1584 'tool_use_id' => $eventId,
1585 'result' => 'allow',
1586 ]]);
1587 }
1252 $agent = $client->beta->agents->create(
1253 name: 'Backend engineer',
1254 model: 'claude-sonnet-5',
1255 system: 'You implement backend features end to end. Consult the advisor before major backend design decisions.',
1256 multiagent: [
1257 'type' => 'multiagent_20261001',
1258 'advisor' => ['type' => 'enabled', 'model' => 'claude-opus-5-5'],
1259 ],
1260 );
1261 echo $agent->id, PHP_EOL;
15881262 ```
15891263 
15901264 ```ruby Ruby
1591 event_ids.each do |event_id|
1592 client.beta.sessions.events.send_(session.id, events: [{
1593 type: "user.tool_confirmation",
1594 tool_use_id: event_id,
1595 result: "allow"
1596 }])
1597 end
1265 agent = client.beta.agents.create(
1266 name: "Backend engineer",
1267 model: "claude-sonnet-5",
1268 system_: "You implement backend features end to end. Consult the advisor before major backend design decisions.",
1269 multiagent: {
1270 type: "multiagent_20261001",
1271 advisor: {type: "enabled", model: "claude-opus-5-5"}
1272 }
1273 )
1274 puts agent.id
15981275 ```
15991276</CodeGroup>
1277 
1278This example sets only `advisor`. The other two settings, `subagents` and `workflows`, keep their defaults, so both are enabled, and the agent can also delegate to inline agents and start workflow runs. For an agent that consults an advisor and does all the work itself, set both to `{"type": "disabled"}`.
1279 
1280You can't list the advisor in `subagents.predefined_agents` or `workflows.predefined_agents`. An enabled `advisor` reserves the name `anthropic.advisor`. While it is enabled, neither list can hold an agent literally named `anthropic.advisor`: the request is rejected with a 400 validation error.
1281 
1282The advisor model must meet a minimum capability bar, and the agent's own model must not be more capable than its advisor; models of equal capability can pair. An invalid pairing is rejected with a 400 validation error when the agent is saved, and again when a session is created. The pairing is also checked when each consultation starts: if it's no longer valid, that consultation fails and the session continues. Valid pairings follow the advisor tool's [model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#model-compatibility) table.
1283 
1284The advisor is also available as a [server tool on the Messages API](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool). The Managed Agents surface differs in configuration and delivery: the `advisor` setting has no `max_uses`, `max_tokens`, or `caching` fields, and advice arrives through thread events rather than `advisor_tool_result` blocks.
1285 
1286### How consultations work
1287 
1288Each consultation runs as a platform-spawned thread named `anthropic.advisor` that terminates itself when the consultation completes, and the advice is delivered to the primary thread as an `agent.thread_message_received` event. A consultation emits the standard thread events, identified by the reserved name `anthropic.advisor` (the thread lifecycle events carry it as `agent_name`, and the advice delivery carries it as `from_agent_name`), typically in this order:
1289 
12901. `session.thread_created`
12912. `session.thread_status_running`
12923. `agent.thread_message_received` (the advice)
12934. `session.thread_status_idle` (`stop_reason: end_turn`)
12945. `session.thread_status_terminated`
1295 
1296No `agent.tool_use` events are emitted for a consultation, and no `agent.thread_message_sent` event appears on the session's event stream, because the consultation input is composed by the platform rather than sent by the agent. If you list the advisor thread's own events, the advice also appears there as an `agent.thread_message_sent` event. The advice delivery (event 3) is not guaranteed to arrive before the advisor thread's idle and terminated events, so don't treat those as a signal that the advice has already been delivered.
1297 
1298Whether your client can read the advice is the advisor model's policy. It mirrors the [result variants](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#result-variants) split on the Messages API advisor tool. An advisor model that returns plaintext results there delivers readable text here. One that returns redacted results delivers a `[{"type": "redacted"}]` placeholder on every client surface, while the agent still reads the full advice server-side. The preceding example uses the newest Opus model available to you as the advisor. Claude Opus 5 and Claude Opus 5.5 return redacted results, so with either one your client sees only the placeholder. To read the advice on the event stream, use an advisor that returns plaintext, such as Claude Opus 4.8. A model's policy can change with no change to the API, so handle both `text` and `redacted` blocks. Some agent models pair only with redacted-result advisors; see the advisor tool's [compatibility table](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#model-compatibility). Advisor thinking is never surfaced. Clients cannot send `redacted` blocks themselves; an event containing one is rejected with a 400 validation error.
1299 
1300A failed or interrupted consultation never fails the agent's turn: the agent continues after a generic notice that the consultation failed. A session-level `user.interrupt` during a consultation terminates the advisor thread with no advice delivered; a `user.interrupt` with the advisor thread's `session_thread_id` abandons only that consultation.
1301 
1302### Advisor threads
1303 
1304The advisor is not a subagent. The agent's `list_agents` tool doesn't show it, and `send_to_agent`, which sends a subagent a follow-up message, can't reach it. Only the session's primary thread can consult it; subagents can't.
1305 
1306Advisor threads are exempt from the 25-child-thread limit. They appear in the session's [thread list](https://platform.claude.com/docs/en/managed-agents/session-threads). Their `agent` is the advisor form, `{"type": "advisor", "model": ...}`, with the model you configured, and their `parent_thread_id` is the primary thread.
1307 
1308Prompt caching on the advisor's side is automatic; there is nothing to configure. Consultations are billed at the advisor model's rates, and their tokens appear in the advisor thread's usage and in the session's usage totals. They also count against a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets), at the advisor model's list price. Each consultation sends the advisor the primary thread's conversation so far, so consultations late in a long session use more input tokens.
1309 
1310### Removing the advisor
1311 
1312To remove the advisor, [update the agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent) with `advisor` set to `{"type": "disabled"}`. On an agent that already has the `multiagent_20261001` type, a setting that the update leaves out keeps its stored value, so you don't need to send `subagents` or `workflows` again. For the same reason, an update that leaves `advisor` out keeps the advisor. Before you change an existing agent's `multiagent.type`, see [how to move an agent to this type](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#move-from-the-coordinator-type).
1313 
1314## Move from the `coordinator` type
1315 
1316Like `multiagent_20261001`, the `coordinator` type lets an agent delegate to subagents that you list and consult an advisor model. With the `coordinator` type, the agent can't start workflow runs or define subagents itself. The API accepts both types.
1317 
1318To move an agent to `multiagent_20261001`, [update the agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent) with a `multiagent` block of that type:
1319 
13201. Set `type` to `"multiagent_20261001"`.
13212. List the agents that the agent can call in `subagents.predefined_agents`. The entries keep the form that they have now.
13223. If the agent has an advisor, set `advisor` to `{"type": "enabled", "model": "..."}` with the advisor's model.
13234. Send the whole block in one update.
1324 
1325For example, this block gives an agent two subagents and an advisor:
1326 
1327```json
1328{
1329 "multiagent": {
1330 "type": "multiagent_20261001",
1331 "subagents": {
1332 "type": "enabled",
1333 "predefined_agents": [
1334 { "type": "agent", "id": "agent_01J8XkN5uT3vHpLqRfWdY2" },
1335 { "type": "agent", "id": "agent_01HqR2k7vXbZ9mNpL3wYcT" }
1336 ]
1337 },
1338 "advisor": { "type": "enabled", "model": "claude-opus-5-5" }
1339 }
1340}
1341```
1342 
1343That block leaves out `workflows` and `subagents.inline_agents`, so both take their default and are enabled. The moved agent can also start workflow runs and define subagents itself. To keep either one off, set it to `{"type": "disabled"}` in the same update. See [Turn on dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#turn-on-dynamic-workflows) and [Predefined and inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents).
1344 
1345If the agent has an advisor and no subagents, set `subagents` to `{"type": "disabled"}` to keep delegation off. A request that disables `subagents.inline_agents` and lists no agents fails with a 400 error.
1346 
1347The update replaces the whole `multiagent` block, so send the list of agents and the advisor again, as the example does. What you leave out takes its default:
1348 
1349* **`subagents.predefined_agents`:** The list is empty, so the agent loses the subagents that you listed.
1350* **`advisor`:** The advisor is disabled.
1351 
1352Once the agent has the `multiagent_20261001` type, a setting that a later update leaves out keeps its stored value.
1353 
1354The update doesn't change sessions that already exist. To use the new block, create a session after the update.
16001355 
Feedback