TypeScript Claude API Multi-Turn Conversation Types — Managed Agents Session Guide

Table of Contents


title: "TypeScript Claude API Multi-Turn Conversation Types — From Managed Agents 4-Layer Architecture to Billing" slug: "typescript-claude-api-multiturn-managed-agents" description: "A step-by-step breakdown of Claude Managed Agents’ Agent, Environment, Session, and Events 4-layer type architecture from a TypeScript perspective. Covers agent creation, session-based multi-turn execution, event streaming, billing structure, and rate limits with practical code."

Managing TypeScript Claude API multi-turn conversation types starts with understanding Anthropic’s Managed Agents architecture. Multi-turn conversation in the Claude API isn’t simply passing message arrays back and forth — it’s a structured conversation model operating on a 4-layer type system of Agent, Environment, Session, and Events.

The traditional Messages API approach involved alternating role: "user" and role: "assistant" entries in a messages array to maintain conversation flow. Simple enough, but as conversations grow longer, token management, tool call state tracking, and system prompt versioning become increasingly complex. Managed Agents delegates this entire state to server-side sessions, and all endpoints require the managed-agents-2026-04-01 beta header. When using the SDK, this header is set automatically, so there’s no need to specify it manually.

This article walks through the 4 core type layers, agent creation, session-based multi-turn execution, event streaming, billing structure, and rate limits step by step, based on the Managed Agents architecture overview.

Four Core Type Layers of Managed Agents

Claude Managed Agents consists of four core concepts: Agent, Environment, Session, and Events. Each exists as an independent API resource type, and their combination is what makes multi-turn conversation possible. Supported tools include Bash, file operations, web search/fetch, and MCP servers.

Agent Type

An Agent is a resource that defines the model, system prompt, and available tools. Once created, it can be reused across multiple sessions — essentially serving as the “blueprint” for conversations. The model field takes a model identifier like claude-opus-4-7, and the system field holds the full system prompt text. Since model and tool configuration are determined at the agent level, separating agents by purpose naturally achieves separation of concerns.

Environment Type

An Environment is a resource that defines the container environment where the agent runs. Setting networking to unrestricted allows free external network access, while restricted settings enable a sandbox configuration that only permits specific domains. The key design point is that Agents and Environments are created independently — this makes it possible to run the same agent in a development environment with open networking and a production environment with restricted access.

Session Type and Events Type

A Session is the execution instance where actual conversation takes place. It’s created by referencing an Agent ID and Environment ID, and the essence of multi-turn conversation is that multiple message exchanges occur within a single session. Events are the message exchange units within a session — event types like user.message, agent.message, agent.tool_use, and session.status_idle are delivered in real-time through an SSE (Server-Sent Events) stream.

Practical implications of the 4-layer separation
Because Agent and Environment are separated, the same coding assistant agent can be run in a development environment (unrestricted networking) and a code-review-only environment (restricted networking). Sessions manage state server-side, so the client doesn’t need to transmit the entire conversation history with every request.

TypeScript Claude API Multi-Turn Conversation Types — Agent Creation

Agent creation is performed via the POST /v1/agents endpoint. It takes name, model, system, and tools fields, and specifying {"type": "agent_toolset_20260401"} in the tools array activates all built-in tools at once — bash execution, file read/write, web search, and web page fetch.

The following is the agent creation code from the Managed Agents quickstart guide.

from anthropic import Anthropic

client = Anthropic()

agent = client.beta.agents.create(
    name="Coding Assistant",
    model="claude-opus-4-7",
    system="You are a helpful coding assistant. Write clean, well-documented code.",
    tools=[
        {"type": "agent_toolset_20260401"},
    ],
)

print(f"Agent ID: {agent.id}, version: {agent.version}")

The notable part of this code is the tools array. Specifying a single type identifier agent_toolset_20260401 activates all built-in tools — bash, file operations, web search, and web fetch. While not having to enumerate tools individually keeps configuration concise, there’s a trade-off: unnecessary tools may also be activated. For agents that don’t need web search, specifying only individual tools is worth considering from a cost perspective.

Version meaning of the agent_toolset_20260401 identifier
The date portion (20260401) of the tool type identifier represents the API version. Even if new toolset versions are added in the future, existing identifiers are expected to maintain backward compatibility, so managing this identifier as a constant in production code is the safe approach.

The agent creation response includes id and version fields. id is the required reference value for subsequent session creation, and version is an immutable identifier that increments whenever the agent configuration changes. Updating agent settings generates a new version, making it possible to pin session execution to a specific version’s configuration.

Environment creation is performed separately via the POST /v1/environments endpoint. Setting the networking field to unrestricted allows the agent to freely call external APIs, while production environments with higher security requirements should use explicit domain restriction settings.

Session Creation and Multi-Turn Conversation Execution

A session is created by passing an agent ID and environment_id to the POST /v1/sessions endpoint. Once a session is created, a multi-turn conversation context is maintained that supports multiple message exchanges. Unlike the traditional Messages API approach, there’s no need to retransmit the entire conversation history each time — the server manages session state, significantly simplifying client-side code.

Message sending works by posting a user.message type event to POST /v1/sessions/{id}/events. Responses are received by opening an SSE stream via GET /v1/sessions/{id}/stream, which delivers agent.message, agent.tool_use, and session.status_idle events sequentially.

Here’s the complete flow from session creation to event streaming.

session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    title="Quickstart session",
)

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": "Create a Python script..."}],
        }],
    )
    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    print(block.text, end="")
            case "session.status_idle":
                break

The key part of this code is the match event.type pattern matching. It branches based on event type strings — the same concept as TypeScript’s discriminated union pattern. It iterates through event.content blocks only when event.type is "agent.message", and terminates the loop on "session.status_idle".

To continue multi-turn conversation, send a new user.message to the same session after receiving a session.status_idle event. Since session state is maintained on the server, previous conversation context carries over automatically. The client no longer needs to manage message history arrays directly.

Stream connection order matters
The code must open the stream first and then send the message — this order is mandatory. If reversed, agent response events may be missed. SSE streams only receive events that occur after the connection is established.

Event Type System and Branching Patterns

The most critical point for type safety in multi-turn conversation is event type branching. Claude Managed Agents events are divided into 4 types, each with different transmission directions and processing responsibilities.

Event TypeDirectionDescriptionHandling
user.messageClient → ServerUser message transmissionSent via send endpoint
agent.messageServer → ClientAgent text responseIterate content block array
agent.tool_useServer → ClientBuilt-in tool call executionAutomatic server-side processing
session.status_idleServer → ClientTurn completion signalEnd loop or start next turn

The event’s content field is composed of block arrays. In user.message, content takes the form [{"type": "text", "text": "..."}], and agent.message follows the same block structure. This consistent block type structure allows client-side parsing logic to be unified.

The role of the session.status_idle event is to clearly signal the end of a turn. This event only fires after the agent has made multiple tool calls and completed its final response. Using this event as a turn boundary in multi-turn conversation loops prevents the mistake of sending the next message while the agent is still processing.

Server-Side Handling of Tool Use Events

The agent.tool_use event handling approach differs fundamentally between the traditional Messages API and Managed Agents. In the Messages API, receiving a tool_use response required the client to execute the tool directly and send back a tool_result — a round-trip loop. This loop was a major source of complexity in multi-turn conversations.

In Managed Agents, tool execution happens automatically in the server-side container (Environment). Bash command execution, file read/write, and web search result collection are all processed on the server, with results delivered through the event stream. The client only needs to monitor tool execution results, significantly simplifying multi-turn conversation logic.

This difference also impacts TypeScript type design. A Messages API-based approach requires circular types like ToolUseRequest → ToolResult → AssistantMessage, while a Managed Agents-based approach only needs unidirectional event stream reception types.

MCP server integration status
MCP servers are included in the Managed Agents supported tools list. However, detailed configuration examples for MCP server integration aren’t sufficiently covered in the official documentation yet, so starting with basic built-in tools like bash, file operations, and web search is the practical approach.

Billing Structure for Claude API Multi-Turn Conversation Types

Managed Agents billing consists of two components: session runtime costs and token costs. Without understanding the cost structure when designing multi-turn conversations, unexpected charges can occur — making billing just as important a consideration as type architecture.

Session Runtime Billing

Session runtime is billed at $0.08/session-hour. Only time in the running state is measured with millisecond precision; idle, rescheduling, and terminated states are not billed. The fact that idle periods waiting for user input aren’t charged is a favorable structure for cost management. However, the agent remains in the running state while executing tools, so agents running complex tool chains will incur higher runtime costs.

Token Billing and Additional Costs

Standard model pricing applies to tokens. As multi-turn conversations grow longer, cumulative tokens within the context window increase, so designing appropriate per-session turn limits is cost-effective.

Billing ItemUnit PriceBilling Condition
Session runtime$0.08/hourRunning state only, millisecond precision
Opus 4.7 input tokens$5/MTokStandard model pricing
Opus 4.7 output tokens$25/MTokStandard model pricing
Web search tool$10/1,000 callsCharged only on search invocation
Batch API discounts do not apply
Batch API discounts, Fast mode, and Data residency multipliers are not applied to Managed Agents. Switching from Messages API with Batch discounts to Managed Agents for high-volume processing scenarios may increase costs, so upfront cost estimation is essential.

Cost Optimization Patterns

Three patterns are worth considering to optimize multi-turn conversation costs.

First, session reuse. For conversations within the same context, adding messages to an existing session rather than creating a new one is more token-efficient. Since maintaining a session in idle state incurs no runtime cost, keeping sessions open and executing the next turn as needed is a viable pattern.

Second, model selection separation. Not every multi-turn conversation needs Opus 4.7. Simple Q&A sessions can use agents configured with lightweight models, reserving higher-tier models for complex code generation sessions. Because agents and sessions are separated, creating agents per model in advance and spinning up sessions with different agents based on the use case is straightforward.

Third, selective web search tool activation. With additional billing of $10 per 1,000 calls, specifying only needed tools individually rather than enabling the full agent_toolset_20260401 for agents that don’t require web search contributes to cost savings.

Rate Limits and Operational Constraints

Managed Agents endpoint rate limits are applied at the Organization level. Limits differ by endpoint type, so these numbers should be understood before designing a multi-turn conversation system.

Endpoint TypeLimitTarget APIs
Create60 req/minagents, sessions, environments creation
Read (retrieve/list/stream)600 req/minretrieve, list, stream queries

The create endpoint is limited to 60 requests per minute, which can become a bottleneck when creating large numbers of sessions simultaneously. The read endpoint at 600 requests per minute provides relatively more headroom for subscribing to event streams from multiple sessions concurrently.

The practically important pattern is agent reuse. Creating an agent once and referencing it across multiple sessions significantly reduces create endpoint call counts. Storing agent IDs in environment variables or config files and only sending new requests for session creation keeps operations within the 60 requests per minute limit.

Research Preview Features

The outcomes, multiagent, and memory features are currently in research preview and require separate access requests. Detailed API specs for these features are not documented even in official documentation. Depending on these features in production design is premature.

Once the multi-agent feature reaches general availability, a structure where multiple agents collaborate within a single session will become possible. The memory feature is expected to provide persistent context retention across sessions, but the specific API shape cannot be confirmed at this time.

Multi-Turn Conversation Type Strategies for TypeScript Projects

The most important consideration when applying TypeScript Claude API multi-turn conversation types to real projects is the discriminated union pattern for event types. The match event.type syntax from the Python code shown earlier can be implemented identically in TypeScript using switch statements and type guards.

The Anthropic SDK is available in two languages: Python and TypeScript (@anthropic-ai/sdk). Using the TypeScript SDK automatically sets the managed-agents-2026-04-01 beta header, and type definitions for event types are included in the SDK package.

Three areas where type safety is particularly important in multi-turn conversation systems can be summarized as follows.

First, event type branching. Guaranteeing accurate payload types for each of user.message, agent.message, agent.tool_use, and session.status_idle prevents runtime errors. When the event.type field is narrowed to a literal type, the content structure of that event is automatically inferred — this is the core of discriminated unions.

Second, content block types. Since the event’s content field is a block array in {"type": "text", "text": "..."} format, branching based on block type is necessary. Because text blocks and tool use blocks have different structures, applying the discriminated union pattern at the block level is also needed to ensure type safety.

Third, ID reference chaining between agents and sessions. The id from the Agent creation response is a required parameter for Session creation, and the Session’s id is a path parameter for Event send/receive. Expressing this chaining through generic types or branded types can catch invalid ID references at compile time.

에이전트 생성 → 환경 생성 → 세션 생성 → 메시지 전송 → 이벤트 수신
   Agent          Env         Session      Event(send)    Event(stream)
   (id,ver)      (id,net)    (id,agent)   user.message   agent.message
                                                          agent.tool_use
                                                          session.status_idle

In this flow, the output type of each step directly connects to the input type of the next. Leveraging TypeScript’s generics and conditional types makes it possible to verify this entire pipeline at the type level.

Production Deployment and Error Handling

The first challenge when deploying Managed Agents to production is error handling. The official documentation currently doesn’t provide guidance on error handling and retry patterns, so defensive logic must be built independently.

Reconnection logic for SSE stream disconnections is essential. Streams can be interrupted by network instability or server-side timeouts, so an exponential backoff reconnection strategy should be implemented. After reconnecting, logic to verify session state and recover data after the last received event may also be needed.

Session state management is another important area. Client behavior should vary depending on whether the session is in running, idle, rescheduling, or terminated state. Sending a message to a terminated session will produce an error, so placing a guard that validates session state before message transmission is the safe approach.

The absence of official documentation in languages other than English is also a practical constraint. Since all documentation is provided only in English, creating separate team onboarding materials or adding JSDoc comments in the team’s native language to API type definitions can reduce onboarding costs.

Once the TypeScript Claude API multi-turn conversation type design is reasonably established, the next step is fine-grained control over agent tool usage patterns. How to set security boundaries for agents that autonomously use bash and the file system is a core production challenge. When multi-agent collaboration reaches general availability, session-to-session message routing and inter-agent type contract design will also become areas to address.

Scroll to Top