Example workflow
Here's how a complete programmatic tool calling flow works:
Step 1: Initial request
Send a request with code execution and a tool that allows programmatic calling. To enable programmatic calling, add the allowed_callers field to your tool definition.
Provide detailed descriptions of your tool's output format in the tool description. If you specify that the tool returns JSON, Claude attempts to deserialize and process the result in code. The more detail you provide about the output schema, the better Claude can handle the response programmatically.
The request shape is identical to the Quick start example: include code_execution in your tools list, add allowed_callers: ["code_execution_20260120"] to any tool you want Claude to invoke from code, and send your user message. The remaining steps in this workflow use the user message "Query customer purchase history from the last quarter and identify our top 5 customers by revenue".
Step 2: API response with tool call
Claude writes code that calls your tool. The API pauses and returns:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "import json\n\nrows = json.loads(await query_database({'sql': '<sql>'}))\ntop_customers = sorted(rows, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2026-01-20T14:30:00Z"
},
"stop_reason": "tool_use"
}Step 3: Provide tool result
Send the full conversation history plus your tool result. Three details matter on this request:
The user message that carries your result can contain only
tool_resultblocks. See Message formatting restrictions.Pass the
containerID from the paused response. The API rejects a continuation that has pending programmatic tool calls but no container ID.Send the same
toolsarray as the original request. The code execution tool must still be present for the paused code to resume, and the tools you send on this request are the definitions Claude and the running code can use for the rest of the turn.bashcurl https://api.anthropic.com/v1/messages \ --header "x-api-key: $ANTHROPIC_API_KEY" \ --header "anthropic-version: 2023-06-01" \ --header "content-type: application/json" \ --data '{ "model": "claude-opus-5", "max_tokens": 4096, "container": "container_xyz789", "messages": [ { "role": "user", "content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue" }, { "role": "assistant", "content": [ { "type": "text", "text": "I'\''ll query the purchase history and analyze the results." }, { "type": "server_tool_use", "id": "srvtoolu_abc123", "name": "code_execution", "input": {"code": "..."} }, { "type": "tool_use", "id": "toolu_def456", "name": "query_database", "input": {"sql": "<sql>"}, "caller": { "type": "code_execution_20260120", "tool_id": "srvtoolu_abc123" } } ] }, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": "toolu_def456", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}]" } ] } ], "tools": [ { "type": "code_execution_20260120", "name": "code_execution" }, { "name": "query_database", "description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.", "input_schema": { "type": "object", "properties": { "sql": { "type": "string", "description": "SQL query to execute" } }, "required": ["sql"] }, "allowed_callers": ["code_execution_20260120"] } ] }'bashant messages create <<'YAML' model: claude-opus-5 max_tokens: 4096 container: container_xyz789 messages: - role: user content: >- Query customer purchase history from the last quarter and identify our top 5 customers by revenue - role: assistant content: - type: text text: I'll query the purchase history and analyze the results. - type: server_tool_use id: srvtoolu_abc123 name: code_execution input: code: "..." - type: tool_use id: toolu_def456 name: query_database input: sql: "<sql>" caller: type: code_execution_20260120 tool_id: srvtoolu_abc123 - role: user content: - type: tool_result tool_use_id: toolu_def456 content: >- [{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...] # Same tools array as the original request tools: - type: code_execution_20260120 name: code_execution - name: query_database description: >- Execute a SQL query against the sales database. Returns a list of rows as JSON objects. input_schema: type: object properties: sql: type: string description: SQL query to execute required: - sql allowed_callers: - code_execution_20260120 YAMLpythonresponse = client.messages.create( model="claude-opus-5", max_tokens=4096, container="container_xyz789", # Reuse the container messages=[ { "role": "user", "content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue", }, { "role": "assistant", "content": [ { "type": "text", "text": "I'll query the purchase history and analyze the results.", }, { "type": "server_tool_use", "id": "srvtoolu_abc123", "name": "code_execution", "input": {"code": "..."}, }, { "type": "tool_use", "id": "toolu_def456", "name": "query_database", "input": {"sql": "<sql>"}, "caller": { "type": "code_execution_20260120", "tool_id": "srvtoolu_abc123", }, }, ], }, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": "toolu_def456", "content": '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]', } ], }, ], # Same tools array as the original request tools=[ {"type": "code_execution_20260120", "name": "code_execution"}, { "name": "query_database", "description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.", "input_schema": { "type": "object", "properties": { "sql": {"type": "string", "description": "SQL query to execute"} }, "required": ["sql"], }, "allowed_callers": ["code_execution_20260120"], }, ], ) print(response)typescriptconst response = await client.messages.create({ model: "claude-opus-5", max_tokens: 4096, container: "container_xyz789", // Reuse the container messages: [ { role: "user", content: "Query customer purchase history from the last quarter and identify our top 5 customers by revenue" }, { role: "assistant", content: [ { type: "text", text: "I'll query the purchase history and analyze the results." }, { type: "server_tool_use", id: "srvtoolu_abc123", name: "code_execution", input: { code: "..." } }, { type: "tool_use", id: "toolu_def456", name: "query_database", input: { sql: "<sql>" }, caller: { type: "code_execution_20260120", tool_id: "srvtoolu_abc123" } } ] }, { role: "user", content: [ { type: "tool_result", tool_use_id: "toolu_def456", content: '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]' } ] } ], // Same tools array as the original request tools: [ { type: "code_execution_20260120", name: "code_execution" }, { name: "query_database", description: "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.", input_schema: { type: "object" as const, properties: { sql: { type: "string", description: "SQL query to execute" } }, required: ["sql"] }, allowed_callers: ["code_execution_20260120"] } ] }); console.log(response);csharpAnthropicClient client = new(); var parameters = new MessageCreateParams { Model = Model.ClaudeOpus5, MaxTokens = 4096, Container = "container_xyz789", Messages = [ new() { Role = Role.User, Content = "Query customer purchase history from the last quarter and identify our top 5 customers by revenue" }, new() { Role = Role.Assistant, Content = new ContentBlock[] { new TextBlock { Text = "I'll query the purchase history and analyze the results." }, new ServerToolUseBlock { Id = "srvtoolu_abc123", Name = "code_execution", Input = new { code = "..." } }, new ToolUseBlock { Id = "toolu_def456", Name = "query_database", Input = new { sql = "<sql>" }, Caller = new ToolCaller { Type = "code_execution_20260120", ToolId = "srvtoolu_abc123" } } } }, new() { Role = Role.User, Content = new ContentBlockParam[] { new ToolResultBlockParam { ToolUseID = "toolu_def456", Content = "[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}, ...]" } } } ], // Same tools array as the original request Tools = [ new CodeExecutionTool20260120(), new ToolUnion(new Tool() { Name = "query_database", Description = "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.", InputSchema = new InputSchema() { Properties = new Dictionary<string, JsonElement> { ["sql"] = JsonSerializer.SerializeToElement(new { type = "string", description = "SQL query to execute" }), }, Required = ["sql"], }, AllowedCallers = ["code_execution_20260120"] }), ] }; var message = await client.Messages.Create(parameters); Console.WriteLine(message);goclient := anthropic.NewClient() response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ Model: anthropic.ModelClaudeOpus5, MaxTokens: 4096, Container: anthropic.MessageCreateParamsContainerUnion{ OfString: anthropic.String("container_xyz789"), }, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock("Query customer purchase history from the last quarter and identify our top 5 customers by revenue")), { Role: anthropic.MessageParamRoleAssistant, Content: []anthropic.ContentBlockParamUnion{ anthropic.NewTextBlock("I'll query the purchase history and analyze the results."), {OfServerToolUse: &anthropic.ServerToolUseBlockParam{ ID: "srvtoolu_abc123", Name: anthropic.ServerToolUseBlockParamNameCodeExecution, Input: map[string]any{"code": "..."}, }}, {OfToolUse: &anthropic.ToolUseBlockParam{ ID: "toolu_def456", Name: "query_database", Input: map[string]any{"sql": "<sql>"}, Caller: anthropic.ServerToolUseBlockParamCallerUnion{ OfCodeExecution20260120: &anthropic.ServerToolCaller20260120Param{ ToolID: "srvtoolu_abc123", }, }, }}, }, }, { Role: anthropic.MessageParamRoleUser, Content: []anthropic.ContentBlockParamUnion{ {OfToolResult: &anthropic.ToolResultBlockParam{ ToolUseID: "toolu_def456", Content: []anthropic.ToolResultBlockParamContentUnion{ {OfText: &anthropic.TextBlockParam{ Text: `[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]`, }}, }, }}, }, }, }, // Same tools array as the original request Tools: []anthropic.ToolUnionParam{ {OfCodeExecutionTool20260120: &anthropic.CodeExecutionTool20260120Param{}}, {OfTool: &anthropic.ToolParam{ Name: "query_database", Description: anthropic.String("Execute a SQL query against the sales database. Returns a list of rows as JSON objects."), InputSchema: anthropic.ToolInputSchemaParam{ Properties: map[string]any{ "sql": map[string]any{ "type": "string", "description": "SQL query to execute", }, }, Required: []string{"sql"}, }, AllowedCallers: []string{"code_execution_20260120"}, }}, }, }) if err != nil { log.Fatal(err) } fmt.Println(response.RawJSON())javaimport com.anthropic.models.messages.CodeExecutionTool20260120; // ... void main() { AnthropicClient client = AnthropicOkHttpClient.fromEnv(); MessageCreateParams params = MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_5) .maxTokens(4096L) .container("container_xyz789") .addUserMessage("Query customer purchase history from the last quarter and identify our top 5 customers by revenue") .addAssistantMessageOfBlockParams(List.of( ContentBlockParam.ofText( TextBlockParam.builder() .text("I'll query the purchase history and analyze the results.") .build()), ContentBlockParam.ofServerToolUse( ServerToolUseBlockParam.builder() .id("srvtoolu_abc123") .name("code_execution") .input(JsonValue.from(Map.of("code", "..."))) .build()), ContentBlockParam.ofToolUse( ToolUseBlockParam.builder() .id("toolu_def456") .name("query_database") .input(JsonValue.from(Map.of("sql", "<sql>"))) .codeExecution20260120Caller("srvtoolu_abc123") .build()) )) .addUserMessageOfBlockParams(List.of( ContentBlockParam.ofToolResult( ToolResultBlockParam.builder() .toolUseId("toolu_def456") .content("[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}, ...]") .build()) )) // Same tools array as the original request .addTool(CodeExecutionTool20260120.builder().build()) .addTool(Tool.builder() .name("query_database") .description("Execute a SQL query against the sales database. Returns a list of rows as JSON objects.") .inputSchema(InputSchema.builder() .properties(JsonValue.from(Map.of( "sql", Map.of( "type", "string", "description", "SQL query to execute" ) ))) .putAdditionalProperty("required", JsonValue.from(List.of("sql"))) .build()) .allowedCallers(List.of(Tool.AllowedCaller.of("code_execution_20260120"))) .build()) .build(); Message response = client.messages().create(params); IO.println(response); }php$client = new Client(); $message = $client->messages->create( maxTokens: 4096, messages: [ [ 'role' => 'user', 'content' => 'Query customer purchase history from the last quarter and identify our top 5 customers by revenue', ], [ 'role' => 'assistant', 'content' => [ [ 'type' => 'text', 'text' => "I'll query the purchase history and analyze the results.", ], [ 'type' => 'server_tool_use', 'id' => 'srvtoolu_abc123', 'name' => 'code_execution', 'input' => ['code' => '...'], ], [ 'type' => 'tool_use', 'id' => 'toolu_def456', 'name' => 'query_database', 'input' => ['sql' => '<sql>'], 'caller' => [ 'type' => 'code_execution_20260120', 'tool_id' => 'srvtoolu_abc123', ], ], ], ], [ 'role' => 'user', 'content' => [ [ 'type' => 'tool_result', 'tool_use_id' => 'toolu_def456', 'content' => '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]', ], ], ], ], model: 'claude-opus-5', container: 'container_xyz789', // Same tools array as the original request tools: [ [ 'type' => 'code_execution_20260120', 'name' => 'code_execution', ], [ 'name' => 'query_database', 'description' => 'Execute a SQL query against the sales database. Returns a list of rows as JSON objects.', 'input_schema' => [ 'type' => 'object', 'properties' => [ 'sql' => [ 'type' => 'string', 'description' => 'SQL query to execute', ], ], 'required' => ['sql'], ], 'allowed_callers' => ['code_execution_20260120'], ], ], ); echo $message;rubyrequire "anthropic" client = Anthropic::Client.new message = client.messages.create( model: "claude-opus-5", max_tokens: 4096, container: "container_xyz789", messages: [ { role: "user", content: "Query customer purchase history from the last quarter and identify our top 5 customers by revenue" }, { role: "assistant", content: [ { type: "text", text: "I'll query the purchase history and analyze the results." }, { type: "server_tool_use", id: "srvtoolu_abc123", name: "code_execution", input: { code: "..." } }, { type: "tool_use", id: "toolu_def456", name: "query_database", input: { sql: "<sql>" }, caller: { type: "code_execution_20260120", tool_id: "srvtoolu_abc123" } } ] }, { role: "user", content: [ { type: "tool_result", tool_use_id: "toolu_def456", content: '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]' } ] } ], # Same tools array as the original request tools: [ { type: "code_execution_20260120", name: "code_execution" }, { name: "query_database", description: "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.", input_schema: { type: "object", properties: { sql: { type: "string", description: "SQL query to execute" } }, required: ["sql"] }, allowed_callers: ["code_execution_20260120"] } ] ) puts message
Step 4: Next tool call or completion
The code picks up where it paused and processes your result. Each continuation response either pauses again with more programmatic tool_use blocks, or completes the code execution and lets Claude continue the turn (Step 5). Check stop_reason and each tool_use block's caller to tell the two apart: a response that pauses for you has stop_reason: "tool_use" and a tool_use block whose caller names a code execution version, and you repeat Step 3 with a tool_result for every pending programmatic call in one user message.
Step 5: Final response
Once the code execution completes, Claude provides the final response:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers: [{'customer_id': 'C1', 'revenue': 45000}, {'customer_id': 'C2', 'revenue': 38000}, {'customer_id': 'C5', 'revenue': 32000}, {'customer_id': 'C8', 'revenue': 28500}, {'customer_id': 'C3', 'revenue': 24000}]",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}