# Claude Managed Agents Events
Communication with a [[Claude Managed Agents|managed agent]] session is event-based, not request-response. You send **user events** to drive the agent; you receive **agent, session, and span events** back over a server-sent-event (SSE) stream. Every event type is `{domain}.{action}`.
## User events (what you send)
| Type | Purpose |
|---|---|
| `user.message` | Text (or mixed content) prompt to the agent |
| `user.interrupt` | Stop the agent mid-execution |
| `user.custom_tool_result` | Respond to a `agent.custom_tool_use` call |
| `user.tool_confirmation` | Approve/deny an `always_ask` tool call |
| `user.define_outcome` | Set a rubric-graded goal (research preview) |
## Agent events (what you receive)
| Type | Meaning |
|---|---|
| `agent.message` | Text content blocks (stream as they arrive) |
| `agent.thinking` | Extended thinking content, emitted separately |
| `agent.tool_use` / `agent.tool_result` | Built-in toolset calls and their results |
| `agent.mcp_tool_use` / `agent.mcp_tool_result` | MCP server tool calls |
| `agent.custom_tool_use` | Claude wants your client-side tool; reply with `user.custom_tool_result` |
## Session and span events
| Type | Meaning |
|---|---|
| `session.status_running` / `session.status_idle` | Transitions between running and idle |
| `session.error` | Non-fatal errors (e.g., MCP auth failure) |
| `session.thread_created` / `session.thread_idle` | [[Claude Managed Agents Multi-Agent\|Multi-agent]] threads |
| `span.outcome_evaluation_*` | [[Claude Managed Agents Outcomes\|Outcome]] grader progress |
## The send-then-stream pattern
The API buffers events until you attach a stream, so the usual flow is:
1. Create the session
2. Open the SSE stream
3. Send a `user.message`
4. Iterate events until `session.status_idle`
```python
with client.beta.sessions.events.stream(session.id) as stream:
client.beta.sessions.events.send(session.id, events=[
{"type": "user.message", "content": [{"type": "text", "text": "..."}]},
])
for event in stream:
match event.type:
case "agent.message":
for block in event.content:
print(block.text, end="")
case "agent.tool_use":
print(f"[tool: {event.name}]")
case "session.status_idle":
break
```
## Steering mid-execution
You can send more `user.message` events while the agent is running to add instructions without interrupting it; the agent folds them into its next turn. Use `user.interrupt` when you need to hard-stop and redirect.
## Tool confirmation flow
When a tool's permission policy is `always_ask`, the stream pauses with a stop_reason carrying `event_ids`. For each one, reply with `user.tool_confirmation` (`allow` or `deny`) before the agent resumes. Match by `tool_use_id`. In [[Claude Managed Agents Multi-Agent|multi-agent]] sessions, echo the `session_thread_id` so the reply reaches the right subagent.
## Resuming streams
Event history is persisted server-side. If your SSE connection drops, you can fetch historical events via the list endpoint and re-attach the stream — no events are lost.
## References
- https://platform.claude.com/docs/en/managed-agents/events-and-streaming
## Related
- [[Claude Managed Agents]]
- [[Claude Managed Agents Sessions]]
- [[Claude Managed Agents Tools]]
- [[Claude Managed Agents Multi-Agent]]
- [[Claude Managed Agents Outcomes]]