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

session-threads changedmanaged-agents/session-threads

Recorded here
Lines+19added
Lines−19removed
From line 18 where the diff opens
First seen 9 Oct 2026 this site's first read of the page
Recorded edits11to this page, all time

The whole hunk

from line 18, old and new numbered
/
lines
from line 18
1818 
1919**Session threads** are where you drill into a specific agent's activity.
2020 
21The 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. A [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs) that's running can keep the session `running` too, even while none of its threads is working. When no thread is working and a thread waits on your client, the session is `idle`; see [Know when the work is done](https://platform.claude.com/docs/en/managed-agents/workflow-runs#know-when-the-work-is-done).
21The session `status` (java, php; csharp, go: `Status`) is an aggregation of all agent activity; if at least one thread is `running`, then the overall session status is `running` as well. A [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs) that's running can keep the session `running` too, even while none of its threads is working. When no thread is working and a thread waits on your client, the session is `idle`; see [Know when the work is done](https://platform.claude.com/docs/en/managed-agents/workflow-runs#know-when-the-work-is-done).
2222 
2323A [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.
2424 
from line 102
102102 ```
103103</CodeGroup>
104104 
105The full list includes the primary thread. `parent_thread_id` is `null` for the primary thread. Every other thread is a child thread. `workflow_run_id` is `null` except on [a run's threads](https://platform.claude.com/docs/en/managed-agents/workflow-runs#a-runs-threads).
105The full list includes the primary thread. `parent_thread_id` (java: `parentThreadId`; php: `parentThreadID`; csharp, go: `ParentThreadID`) is `null` for the primary thread. Every other thread is a child thread. `workflow_run_id` (java: `workflowRunId`; php: `workflowRunID`; csharp, go: `WorkflowRunID`) is `null` except on [a run's threads](https://platform.claude.com/docs/en/managed-agents/workflow-runs#a-runs-threads).
106106 
107107To list only threads that have certain statuses, add `statuses[]` to the request, and repeat it to give more than one status, as in `?statuses[]=running&statuses[]=idle`. Leave it out to return threads of every status.
108108 
109109## Interrupt a session thread
110110 
111Send `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. In a session with dynamic workflows, an interrupt ends no run, and one that names a run's thread stops nothing. An interrupt closes other child threads' pending tool calls, but don't rely on it to close a run thread's. See [Interrupt a session with runs open](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open).
111Send `user.interrupt` with `session_thread_id` (java: `sessionThreadId`; php: `sessionThreadID`; csharp, go: `SessionThreadID`) to stop a specific thread. Omitting `session_thread_id` (java: `sessionThreadId`; php: `sessionThreadID`; csharp, go: `SessionThreadID`) interrupts every non-archived thread in the session, including the primary. In a session with dynamic workflows, an interrupt ends no run, and one that names a run's thread stops nothing. An interrupt closes other child threads' pending tool calls, but don't rely on it to close a run thread's. See [Interrupt a session with runs open](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open).
112112 
113113<CodeGroup>
114114 ```bash cURL
from line 386
386386 
387387These 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 that the primary thread's agent delegates, for example, arrives on the child's own stream as an `agent.thread_message_received` event.
388388 
389| Type | Description |
390| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
391| `session.thread_created` | A thread was created. Includes `session_thread_id` and `agent_name`. |
392| `session.thread_status_running` | A thread started activity. |
393| `session.thread_status_idle` | The agent associated with the thread is awaiting input. Includes a `stop_reason` indicating why the agent stopped. |
394| `session.thread_status_terminated` | A thread terminated and accepts no further input, for example because it was archived or encountered an unrecoverable error. An advisor thread also terminates when its consultation ends. |
395| `agent.thread_message_received` | On the primary thread, a subagent sent the primary thread's agent a report or question. Includes `from_session_thread_id`, `from_agent_name`, and `content`. |
396| `agent.thread_message_sent` | On the primary thread, the primary thread's agent sent a subagent a task or follow-up message. Includes `to_session_thread_id`, `to_agent_name`, and `content`. |
389| Type | Description |
390| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
391| `session.thread_created` | A thread was created. Includes `session_thread_id` (java: `sessionThreadId`; php: `sessionThreadID`; csharp, go: `SessionThreadID`) and `agent_name` (java, php: `agentName`; csharp, go: `AgentName`). |
392| `session.thread_status_running` | A thread started activity. |
393| `session.thread_status_idle` | The agent associated with the thread is awaiting input. Includes a `stop_reason` (java, php: `stopReason`; csharp, go: `StopReason`) indicating why the agent stopped. |
394| `session.thread_status_terminated` | A thread terminated and accepts no further input, for example because it was archived or encountered an unrecoverable error. An advisor thread also terminates when its consultation ends. |
395| `agent.thread_message_received` | On the primary thread, a subagent sent the primary thread's agent a report or question. Includes `from_session_thread_id` (java: `fromSessionThreadId`; php: `fromSessionThreadID`; csharp, go: `FromSessionThreadID`), `from_agent_name` (java, php: `fromAgentName`; csharp, go: `FromAgentName`), and `content` (java, php; csharp, go: `Content`). |
396| `agent.thread_message_sent` | On the primary thread, the primary thread's agent sent a subagent a task or follow-up message. Includes `to_session_thread_id` (java: `toSessionThreadId`; php: `toSessionThreadID`; csharp, go: `ToSessionThreadID`), `to_agent_name` (java, php: `toAgentName`; csharp, go: `ToAgentName`), and `content` (java, php; csharp, go: `Content`). |
397397 
398Advisor 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.
398Advisor consultations emit these same thread events under the reserved name `anthropic.advisor` (as `agent_name` (java, php: `agentName`; csharp, go: `AgentName`) on the thread lifecycle events and `from_agent_name` (java, php: `fromAgentName`; csharp, go: `FromAgentName`) 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.
399399 
400400A [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs)'s threads show on the primary stream as follows:
401401 
402* **Lifecycle events:** Each run thread sends `session.thread_created`, with the run's `workflow_run_id`, and its `session.thread_status_running`, `session.thread_status_idle`, and `session.thread_status_terminated` events.
402* **Lifecycle events:** Each run thread sends `session.thread_created`, with the run's `workflow_run_id` (java: `workflowRunId`; php: `workflowRunID`; csharp, go: `WorkflowRunID`), and its `session.thread_status_running`, `session.thread_status_idle`, and `session.thread_status_terminated` events.
403403* **Message events:** A run thread's prompt, an `agent.thread_message_received` event, stays on its own stream.
404404* **Run events:** `workflow_run.*` events also arrive on this stream; see [Run events](https://platform.claude.com/docs/en/managed-agents/workflow-runs#run-events).
405405* **Tool calls that wait on you:** A run thread's tool calls that need your client are cross-posted to this stream, as for any child thread. See [Tool permissions and custom tools](https://platform.claude.com/docs/en/managed-agents/session-threads#tool-permissions-and-custom-tools).
from line 410
410410 
411411Each 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.
412412 
413In a workflow run, the server runs a workflow: a program that the primary thread's agent writes. On each of the run's threads, the first `agent.thread_message_received` is the prompt that the workflow wrote. Its `from_session_thread_id` is the primary thread's ID, and it has no `from_agent_name`. The API doesn't guarantee the prompt's text, so don't parse it. The thread's `session.thread_status_terminated` event, on the primary thread's stream, tells you the thread is done. No event records the result it returned to the workflow.
413In a workflow run, the server runs a workflow: a program that the primary thread's agent writes. On each of the run's threads, the first `agent.thread_message_received` is the prompt that the workflow wrote. Its `from_session_thread_id` (java: `fromSessionThreadId`; php: `fromSessionThreadID`; csharp, go: `FromSessionThreadID`) is the primary thread's ID, and it has no `from_agent_name` (java, php: `fromAgentName`; csharp, go: `FromAgentName`). The API doesn't guarantee the prompt's text, so don't parse it. The thread's `session.thread_status_terminated` event, on the primary thread's stream, tells you the thread is done. No event records the result it returned to the workflow.
414414 
415A thread's stream doesn't replay earlier events. Right after `session.thread_created`, the event list of a run's thread can be empty, because the server writes the thread's first event after it. So open the thread's stream first, then list the thread's events, and skip each streamed event whose `id` the list returned.
415A thread's stream doesn't replay earlier events. Right after `session.thread_created`, the event list of a run's thread can be empty, because the server writes the thread's first event after it. So open the thread's stream first, then list the thread's events, and skip each streamed event whose `id` (java, php; csharp, go: `ID`) the list returned.
416416 
417417<Tabs>
418418 <Tab title="Stream session thread events">
from line 687
687687}
688688```
689689 
690Post `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. The response can appear on the primary thread and on the subagent's thread with different `id` values. To match the two copies, compare `type` and `tool_use_id` (or `custom_tool_use_id`), not `id`.
690Post `user.tool_confirmation` (with `tool_use_id` (java: `toolUseId`; php: `toolUseID`; csharp, go: `ToolUseID`)) or `user.custom_tool_result` (with `custom_tool_use_id` (java: `customToolUseId`; php: `customToolUseID`; csharp, go: `CustomToolUseID`)); the server routes the response to the correct thread automatically. The response can appear on the primary thread and on the subagent's thread with different `id` (java, php; csharp, go: `ID`) values. To match the two copies, compare `type` (java, php; csharp, go: `Type`) and `tool_use_id` (java: `toolUseId`; php: `toolUseID`; csharp, go: `ToolUseID`) (or `custom_tool_use_id` (java: `customToolUseId`; php: `customToolUseID`; csharp, go: `CustomToolUseID`)), not `id` (java, php; csharp, go: `ID`).
691691 
692692The 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.
693693 
from line 810
810810 ```
811811</CodeGroup>
812812 
813The previous pattern answers the calls that an idle event lists. On the primary stream, a subagent's `session.thread_status_idle` event can arrive before the `agent.tool_use` or `agent.mcp_tool_use` events that its `stop_reason.event_ids` lists. A `user.tool_confirmation` for a call whose event hasn't arrived yet can return 400. To avoid that, answer each call whose [`evaluated_permission`](https://platform.claude.com/docs/en/managed-agents/permission-policies#see-how-each-call-was-evaluated) is `ask` when its own event arrives on the primary stream.
813The previous pattern answers the calls that an idle event lists. On the primary stream, a subagent's `session.thread_status_idle` event can arrive before the `agent.tool_use` or `agent.mcp_tool_use` events that its `stop_reason.event_ids` lists. A `user.tool_confirmation` for a call whose event hasn't arrived yet can return 400. To avoid that, answer each call whose [`evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`)](https://platform.claude.com/docs/en/managed-agents/permission-policies#see-how-each-call-was-evaluated) is `ask` when its own event arrives on the primary stream.
814814 
Feedback