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: ¶ms}},
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