Loading...
    • Build
    • Admin
    • Models & pricing
    • Client SDKs
    • API Reference
    Search...
    ⌘K
    First steps
    Intro to ClaudeQuickstart
    Building with Claude
    Features overviewUsing the Messages APIClaude API skillHandling stop reasons
    Model capabilities
    Extended thinkingAdaptive thinkingEffortTask budgets (beta)Fast mode (beta: research preview)Structured outputsCitationsStreaming MessagesBatch processingSearch resultsStreaming refusalsMultilingual supportEmbeddings
    Tools
    OverviewHow tool use worksWeb search toolWeb fetch toolCode execution toolAdvisor toolMemory toolBash toolComputer use toolText editor tool
    Tool infrastructure
    Tool referenceTool searchProgrammatic tool callingFine-grained tool streaming
    Context management
    Context windowsCompactionContext editingPrompt cachingToken counting
    Working with files
    Files APIPDF supportImages and vision
    Skills
    OverviewQuickstartBest practicesSkills for enterpriseSkills in the API
    MCP
    Remote MCP serversMCP connector
    Prompt engineering
    OverviewPrompting best practicesConsole prompting tools
    Test and evaluate
    Define success and build evaluationsUsing the Evaluation Tool in ConsoleReducing latency
    Strengthen guardrails
    Reduce hallucinationsIncrease output consistencyMitigate jailbreaksReduce prompt leak
    Resources
    Glossary
    Release notes
    Claude Platform
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    Delegate work to your agent

    Session event stream

    Send events, stream responses, and interrupt or redirect your session mid-execution.

    Communication with Claude Managed Agents is event-based. You send user events to the agent, and receive agent and session events back to track status.

    All Managed Agents API requests require the managed-agents-2026-04-01 beta header. The SDK sets the beta header automatically.

    Event types

    Events flow in two directions.

    • User events are what you send to the agent to kick off a session and steer it as it progresses.
    • Session events, span events, and agent events are sent to you for observability into your session state and agent progress.

    Event type strings follow a {domain}.{action} naming convention.

    Every event includes a processed_at timestamp indicating when the event was recorded server-side. If processed_at is null, it means the event has been queued by the harness and will be handled after preceding events finish processing.

    Integrating events

    Additional scenarios

    Handling custom tool calls

    When the agent invokes a custom tool:

    1. The session emits an agent.custom_tool_use event containing the tool name and input.
    2. The session pauses with a session.status_idle event containing stop_reason: requires_action. The blocking event IDs are in the stop_reason.requires_action.event_ids array.
    3. Execute the tool in your system and send a user.custom_tool_result event for each, passing the event ID in the custom_tool_use_id param along with the result content.
    4. Once all blocking events are resolved, the session transitions back to running.

    Tool confirmation

    When a permission policy requires confirmation before a tool executes:

    1. The session emits an agent.tool_use or agent.mcp_tool_use event.
    2. The session pauses with a session.status_idle event containing stop_reason: requires_action. The blocking event IDs are in the stop_reason.requires_action.event_ids array.
    3. Send a user.tool_confirmation event for each, passing the event ID in the tool_use_id param. Set result to "allow" or "deny". Use deny_message to explain a denial.
    4. Once all blocking events are resolved, the session transitions back to running.

    Tracking usage

    The session object includes a usage field with cumulative token statistics. Fetch the session after it goes idle to read the latest totals, and use them to track costs, enforce budgets, or monitor consumption.

    {
      "id": "sesn_01...",
      "status": "idle",
      "usage": {
        "input_tokens": 5000,
        "output_tokens": 3200,
        "cache_creation_input_tokens": 2000,
        "cache_read_input_tokens": 20000
      }
    }

    input_tokens reports uncached input tokens and output_tokens reports total output tokens across all model calls in the session. The cache_creation_input_tokens and cache_read_input_tokens fields reflect prompt caching activity. Cache entries use a 5-minute TTL, so back-to-back turns within that window benefit from cache reads, which reduce per-token cost.

    Was this page helpful?

    • Event types
    • Integrating events
    • Additional scenarios
    • Handling custom tool calls
    • Tool confirmation
    • Tracking usage
    with client.beta.sessions.events.stream(session.id) as stream:
        for event in stream:
            if event.type == "session.status_idle" and (stop := event.stop_reason):
                match stop.type:
                    case "requires_action":
                        for event_id in stop.event_ids:
                            # Look up the custom tool use event and execute it
                            tool_event = events_by_id[event_id]
                            result = call_tool(tool_event.name, tool_event.input)
    
                            # Send the result back
                            client.beta.sessions.events.send(
                                session.id,
                                events=[
                                    {
                                        "type": "user.custom_tool_result",
                                        "custom_tool_use_id": event_id,
                                        "content": [{"type": "text", "text": result}],
                                    },
                                ],
                            )
                    case "end_turn":
                        break
    with client.beta.sessions.events.stream(session.id) as stream:
        for event in stream:
            if event.type == "session.status_idle" and (stop := event.stop_reason):
                match stop.type:
                    case "requires_action":
                        for event_id in stop.event_ids:
                            # Approve the pending tool call
                            client.beta.sessions.events.send(
                                session.id,
                                events=[
                                    {
                                        "type": "user.tool_confirmation",
                                        "tool_use_id": event_id,
                                        "result": "allow",
                                    },
                                ],
                            )
                    case "end_turn":
                        break