Repository Public
1---2title: Code execution tool3url: https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool4description: Run Python and bash code in a sandboxed container to analyze data, generate files, and iterate on solutions.5---67## Compatibility8- [ZDR](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention): not eligible9- Supported models: `claude-fable-5-1`, `claude-mythos-5-1`, `claude-fable-5`, `claude-mythos-5`, `claude-opus-5`, `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6`, `claude-opus-4-5-20251101`, `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-sonnet-4-5-20250929`, `claude-haiku-4-5-20251001`10- Platforms: Claude API, Claude Platform on AWS, Microsoft Foundry [1]; not available on Amazon Bedrock, Google Cloud11- Every supported model accepts all three [tool versions](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#tool-versions). On Claude Haiku 4.5, programmatic tool calling and REPL state persistence aren't available, so the newer versions behave like `code_execution_20250825` there.12- For [Claude Mythos Preview](https://anthropic.com/glasswing), code execution is supported on the Claude API and Microsoft Foundry.131. On [Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry), code execution requires a [Hosted on Anthropic deployment](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry#additional-features-not-supported-when-hosted-on-azure).1415Claude can analyze data, create visualizations, perform complex calculations, run system commands, create and edit files, and process uploaded files directly within the API conversation. The code execution tool allows Claude to run Bash commands and manipulate files, including writing code, in a secure, sandboxed environment.1617**Code execution is free when used with web search or web fetch (`web_search_20260209`, `web_fetch_20260209`, or later).** When one of those tools is in your request, there are no additional charges for code execution in that request beyond standard token costs. This covers both the code execution behind dynamic filtering and any code Claude runs directly. Standard code execution pricing applies when they are not included.1819Code execution also powers dynamic filtering in the [web search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) and [web fetch](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) tools: Claude filters results inside the code execution environment before they reach the context window. When dynamic filtering runs, the API provisions the code execution it needs for the request automatically, so you don't add the code execution tool to your request for it.2021<Note>22 Reach out through the [feedback form](https://forms.gle/LTAU6Xn2puCJMi1n6) to share your feedback on this feature.23</Note>2425## Tool versions2627The code execution tool has three current versions, and every [supported model](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#compatibility) accepts all three. Each version builds on the previous one:2829* `code_execution_20250825` supports Bash commands and file operations.30* `code_execution_20260120` adds REPL state persistence and [programmatic tool calling](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling) from within the sandbox. Claude Haiku 4.5 accepts the `code_execution_20260120` and `code_execution_20260521` tool types, but programmatic tool calling and the REPL state persistence that depends on it aren't available on it, so the newer versions behave like `code_execution_20250825` there.31* `code_execution_20260521` is the same runtime as `code_execution_20260120`. The difference is that the tool description tells Claude about the 90-second wall-clock limit on each Python cell in programmatic tool calling, so Claude can budget long-running cells. A cell that exceeds the limit returns a normal code execution result with a non-zero `return_code` and a `detection_timeout` status message in its output. This is separate from the `execution_time_exceeded` [error code](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#errors), which the API returns when a whole tool invocation exceeds the maximum execution time.3233None of the three tool versions requires an `anthropic-beta` header. The legacy code execution beta headers remain valid opt-ins.3435The examples on this page use `code_execution_20250825`, which covers the Bash and file operations they demonstrate and behaves the same way on every supported model; use `code_execution_20260120` or later when you need programmatic tool calling or REPL state persistence. The current [web search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) and [web fetch](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) tools (`web_search_20260209`, `web_fetch_20260209`, and later) require `code_execution_20260120` or later as their code execution version.3637Older tool versions aren't guaranteed to stay compatible with newer models. When you adopt a new model, check [Tool versions](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#tool-versions) and [Compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#compatibility), and prefer the newest tool version your integration supports.3839<Note>40 If you're still using the legacy `code_execution_20250522` (Python only), see [Upgrade to latest tool version](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#upgrade-to-latest-tool-version) to migrate from it.41</Note>4243## Quick start4445Here's an example that asks Claude to perform a calculation:4647<CodeGroup>48 ```bash cURL49 curl --fail-with-body -sS https://api.anthropic.com/v1/messages \50 -H "x-api-key: $ANTHROPIC_API_KEY" \51 -H "anthropic-version: 2023-06-01" \52 -H "content-type: application/json" \53 -d '{54 "model": "claude-opus-5",55 "max_tokens": 4096,56 "messages": [57 {58 "role": "user",59 "content": "Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"60 }61 ],62 "tools": [63 {64 "type": "code_execution_20250825",65 "name": "code_execution"66 }67 ]68 }'69 ```7071 ```bash CLI72 ant messages create \73 --model claude-opus-5 \74 --max-tokens 4096 \75 --message '{76 role: user,77 content: "Use the code execution tool to calculate the mean and standard78 deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"79 }' \80 --tool '{type: code_execution_20250825, name: code_execution}'81 ```8283 ```python Python84 client = anthropic.Anthropic()8586 response = client.messages.create(87 model="claude-opus-5",88 max_tokens=4096,89 messages=[90 {91 "role": "user",92 "content": "Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]",93 }94 ],95 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],96 )9798 print(response.to_json())99 ```100101 ```typescript TypeScript102 const client = new Anthropic();103104 const response = await client.messages.create({105 model: "claude-opus-5",106 max_tokens: 4096,107 messages: [108 {109 role: "user",110 content:111 "Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"112 }113 ],114 tools: [{ type: "code_execution_20250825", name: "code_execution" }]115 });116117 console.log(JSON.stringify(response));118 ```119120 ```csharp C#121 AnthropicClient client = new();122123 var message = await client.Messages.Create(new()124 {125 Model = Model.ClaudeOpus5,126 MaxTokens = 4096,127 Messages = [new() { Role = Role.User, Content = "Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" }],128 Tools = [new CodeExecutionTool20250825()]129 });130131 Console.WriteLine(message);132 ```133134 ```go Go135 client := anthropic.NewClient()136137 response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{138 Model: anthropic.ModelClaudeOpus5,139 MaxTokens: 4096,140 Messages: []anthropic.MessageParam{141 anthropic.NewUserMessage(anthropic.NewTextBlock("Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")),142 },143 Tools: []anthropic.ToolUnionParam{144 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},145 },146 })147 if err != nil {148 log.Fatal(err)149 }150 fmt.Println(response.RawJSON())151 ```152153 ```java Java154 AnthropicClient client = AnthropicOkHttpClient.fromEnv();155156 MessageCreateParams params = MessageCreateParams.builder()157 .model(Model.CLAUDE_OPUS_5)158 .maxTokens(4096L)159 .addUserMessage("Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")160 .addTool(CodeExecutionTool20250825.builder().build())161 .build();162163 Message response = client.messages().create(params);164 IO.println(ObjectMappers.jsonMapper().valueToTree(response));165 ```166167 ```php PHP168 $client = new Client();169170 $message = $client->messages->create(171 maxTokens: 4096,172 messages: [173 [174 'role' => 'user',175 'content' => 'Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]',176 ],177 ],178 model: Model::CLAUDE_OPUS_5,179 tools: [new CodeExecutionTool20250825()],180 );181182 echo json_encode($message, JSON_PRETTY_PRINT), PHP_EOL;183 ```184185 ```ruby Ruby186 client = Anthropic::Client.new187188 message = client.messages.create(189 model: Anthropic::Model::CLAUDE_OPUS_5,190 max_tokens: 4096,191 messages: [192 {193 role: "user",194 content: "Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"195 }196 ],197 tools: [Anthropic::CodeExecutionTool20250825.new]198 )199200 puts message.to_json201 ```202</CodeGroup>203204The response interleaves `server_tool_use` blocks (the commands Claude ran) with their tool result blocks, followed by Claude's text. The top level also includes a `container` object whose `id` you can [reuse across requests](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#container-reuse). See [Response format](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#response-format) for the block shapes.205206## How code execution works207208When you add the code execution tool to your API request:2092101. Claude evaluates whether code execution would help answer your question2112122. The tool automatically provides Claude with the following capabilities:213214 * **Bash commands:** Run shell commands for system operations215 * **File operations:** Create, view, and edit files directly, including writing code2162173. Claude can use any combination of these capabilities in a single request2182194. All operations run in a secure, sandboxed container. The container has no internet access, so Claude can't download packages at runtime: only the [pre-installed libraries](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#pre-installed-libraries) are available2202215. The API runs every command server-side and returns the results to Claude within the same request, so you never execute code or send back `tool_result` blocks yourself. One exception is when Claude calls one of your client tools alongside code execution: the API returns the code execution call without its result. The result arrives in a later response, after you send back the `tool_result` blocks for your client tools2222236. Each request runs in a new container unless you pass an earlier response's container ID back (see [Container reuse](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#container-reuse))2242257. Claude provides results with any generated charts, calculations, or analysis226227The container has Python pre-installed. Claude writes Python with the file operations sub-tool and runs it with a Bash command. With `code_execution_20260120` or later and [programmatic tool calling](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling), the Python interpreter state (such as variable bindings) also persists across requests that reuse the container.228229### When Claude runs code230231Claude runs code when the request benefits from computation or file handling:232233* Non-trivial math (large numbers, many steps, precision-sensitive results)234* Data analysis, file parsing, or visualization235* Algorithm execution or simulation236* Explicit requests to "run", "compute", or "execute"237238Claude answers directly without running code for:239240* Simple arithmetic and well-known math facts241* Factual, conversational, or creative requests242* Simple unit conversions or translations243244If you want Claude to run code for a borderline request, ask explicitly (for example, "run code to verify this").245246## Work with files247248### Upload and analyze your own files249250To analyze your own data files (such as CSV, Excel, or images), upload them through the Files API and reference them in your request.251252The Python environment can process various file types uploaded through the Files API, including:253254* CSV255* Excel (.xlsx, .xls)256* JSON257* XML258* Images (JPEG, PNG, GIF, WebP)259* Text files (.txt, .md, .py, and others)260261#### Upload and analyze files2622631. **Upload your file** using the [Files API](https://platform.claude.com/docs/en/build-with-claude/files)2642. **Reference the file** in your message using a `container_upload` content block2653. **Include the code execution tool** in your API request266267<CodeGroup>268 ```bash cURL269 # First, upload a file and capture the file ID (using jq)270 FILE_ID=$(curl --fail-with-body -sS https://api.anthropic.com/v1/files \271 -H "x-api-key: $ANTHROPIC_API_KEY" \272 -H "anthropic-version: 2023-06-01" \273 -F "file=@data.csv" | jq -r '.id')274275 # Then use the file_id with code execution276 curl --fail-with-body -sS https://api.anthropic.com/v1/messages \277 -H "x-api-key: $ANTHROPIC_API_KEY" \278 -H "anthropic-version: 2023-06-01" \279 -H "content-type: application/json" \280 -d '{281 "model": "claude-opus-5",282 "max_tokens": 4096,283 "messages": [{284 "role": "user",285 "content": [286 {"type": "text", "text": "Analyze this CSV data"},287 {"type": "container_upload", "file_id": "'"$FILE_ID"'"}288 ]289 }],290 "tools": [{291 "type": "code_execution_20250825",292 "name": "code_execution"293 }]294 }'295 ```296297 ```bash CLI298 # First, upload a file and capture the file ID299 FILE_ID=$(ant files upload --file ./data.csv --transform id --raw-output)300301 # Then use the file_id with code execution302 ant messages create <<YAML303 model: claude-opus-5304 max_tokens: 4096305 messages:306 - role: user307 content:308 - type: text309 text: Analyze this CSV data310 - type: container_upload311 file_id: $FILE_ID312 tools:313 - type: code_execution_20250825314 name: code_execution315 YAML316 ```317318 ```python Python319 client = anthropic.Anthropic()320321 # Upload a file322 file_object = client.files.upload(file=Path("data.csv"))323324 # Use the file_id with code execution325 response = client.messages.create(326 model="claude-opus-5",327 max_tokens=4096,328 messages=[329 {330 "role": "user",331 "content": [332 {"type": "text", "text": "Analyze this CSV data"},333 {"type": "container_upload", "file_id": file_object.id},334 ],335 }336 ],337 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],338 )339340 print(response.to_json())341 ```342343 ```typescript TypeScript344 import { createReadStream } from "node:fs";345 // ...346 const client = new Anthropic();347348 // Upload a file349 const fileObject = await client.files.upload({350 file: createReadStream("data.csv")351 });352353 // Use the file_id with code execution354 const response = await client.messages.create({355 model: "claude-opus-5",356 max_tokens: 4096,357 messages: [358 {359 role: "user",360 content: [361 { type: "text", text: "Analyze this CSV data" },362 { type: "container_upload", file_id: fileObject.id }363 ]364 }365 ],366 tools: [367 {368 type: "code_execution_20250825",369 name: "code_execution"370 }371 ]372 });373374 console.log(JSON.stringify(response));375 ```376377 ```csharp C#378 AnthropicClient client = new();379380 // Upload a file381 var fileObject = await client.Files.Upload(new FileUploadParams382 {383 File = File.OpenRead("data.csv")384 });385386 // Use the file_id with code execution387 var parameters = new MessageCreateParams388 {389 Model = Model.ClaudeOpus5,390 MaxTokens = 4096,391 Messages = [392 new()393 {394 Role = Role.User,395 Content = new([396 new TextBlockParam { Text = "Analyze this CSV data" },397 new ContainerUploadBlockParam { FileID = fileObject.ID }398 ])399 }400 ],401 Tools = [new CodeExecutionTool20250825()]402 };403404 var response = await client.Messages.Create(parameters);405 Console.WriteLine(response);406 ```407408 ```go Go409 ctx := context.Background()410 client := anthropic.NewClient()411412 // Upload a file413 file, err := os.Open("data.csv")414 if err != nil {415 log.Fatal(err)416 }417 defer file.Close()418419 fileObject, err := client.Files.Upload(ctx, anthropic.FileUploadParams{420 File: file,421 })422 if err != nil {423 log.Fatal(err)424 }425426 // Use the file_id with code execution427 response, err := client.Messages.New(ctx, anthropic.MessageNewParams{428 Model: anthropic.ModelClaudeOpus5,429 MaxTokens: 4096,430 Messages: []anthropic.MessageParam{431 anthropic.NewUserMessage(432 anthropic.NewTextBlock("Analyze this CSV data"),433 anthropic.NewContainerUploadBlock(fileObject.ID),434 ),435 },436 Tools: []anthropic.ToolUnionParam{437 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},438 },439 })440 if err != nil {441 log.Fatal(err)442 }443444 fmt.Println(response.RawJSON())445 ```446447 ```java Java448 AnthropicClient client = AnthropicOkHttpClient.fromEnv();449450 // Upload a file451 FileMetadata fileObject = client.files().upload(452 FileUploadParams.builder()453 .file(Path.of("data.csv"))454 .build()455 );456457 // Use the file_id with code execution458 Message response = client.messages().create(459 MessageCreateParams.builder()460 .model(Model.CLAUDE_OPUS_5)461 .maxTokens(4096L)462 .addUserMessageOfBlockParams(List.of(463 ContentBlockParam.ofText(TextBlockParam.builder()464 .text("Analyze this CSV data")465 .build()),466 ContentBlockParam.ofContainerUpload(ContainerUploadBlockParam.builder()467 .fileId(fileObject.id())468 .build())469 ))470 .addTool(CodeExecutionTool20250825.builder().build())471 .build()472 );473474 IO.println(ObjectMappers.jsonMapper().valueToTree(response));475 ```476477 ```php PHP478 $client = new Client();479480 // Upload a file481 $fileObject = $client->files->upload(482 file: FileParam::fromResource(fopen('data.csv', 'r')),483 );484485 // Use the file_id with code execution486 $response = $client->messages->create(487 model: Model::CLAUDE_OPUS_5,488 maxTokens: 4096,489 messages: [490 [491 'role' => 'user',492 'content' => [493 TextBlockParam::with(text: 'Analyze this CSV data'),494 ContainerUploadBlockParam::with(fileID: $fileObject->id),495 ],496 ],497 ],498 tools: [new CodeExecutionTool20250825()],499 );500501 echo json_encode($response), PHP_EOL;502 ```503504 ```ruby Ruby505 client = Anthropic::Client.new506507 # Upload a file508 file_object = client.files.upload(509 file: Pathname("data.csv")510 )511512 # Use the file_id with code execution513 response = client.messages.create(514 model: Anthropic::Model::CLAUDE_OPUS_5,515 max_tokens: 4096,516 messages: [517 {518 role: "user",519 content: [520 { type: "text", text: "Analyze this CSV data" },521 { type: "container_upload", file_id: file_object.id }522 ]523 }524 ],525 tools: [526 Anthropic::CodeExecutionTool20250825.new527 ]528 )529530 puts response.to_json531 ```532</CodeGroup>533534### Retrieve generated files535536When Claude saves files to its output directory during code execution (see [How generated files are captured](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#how-generated-files-are-captured)), each file's ID appears in the code execution tool result, and you can download it with the [Files API](https://platform.claude.com/docs/en/build-with-claude/files):537538<CodeGroup>539 ```bash cURL540 # Downloading every generated file means looping over the file IDs in the tool541 # result, which doesn't translate to a one-off shell command. Use one of the542 # SDK examples instead.543 ```544545 ```bash CLI546 # Extracting every file ID from the tool results and downloading each one547 # requires a loop, which doesn't translate well to a one-off CLI command.548 # Use one of the SDK examples instead.549 ```550551 ```python Python552 client = Anthropic()553554 # Request code execution that creates files555 response = client.messages.create(556 model="claude-opus-5",557 max_tokens=4096,558 messages=[559 {560 "role": "user",561 "content": "Create a matplotlib visualization and save it as output.png",562 }563 ],564 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],565 )566567568 # Extract file IDs from the response569 def extract_file_ids(response: Message) -> list[str]:570 file_ids: list[str] = []571 for item in response.content:572 if item.type == "bash_code_execution_tool_result":573 content_item = item.content574 if content_item.type == "bash_code_execution_result":575 for output_block in content_item.content:576 file_ids.append(output_block.file_id)577 return file_ids578579580 # Download the created files581 for file_id in extract_file_ids(response):582 file_metadata = client.files.retrieve_metadata(file_id)583 file_content = client.files.download(file_id)584 file_content.write_to_file(file_metadata.filename)585 print(f"Downloaded: {file_metadata.filename}")586 ```587588 ```typescript TypeScript589 import { writeFile } from "node:fs/promises";590591 const client = new Anthropic();592593 // Request code execution that creates files594 const response = await client.messages.create({595 model: "claude-opus-5",596 max_tokens: 4096,597 messages: [598 {599 role: "user",600 content: "Create a matplotlib visualization and save it as output.png"601 }602 ],603 tools: [604 {605 type: "code_execution_20250825",606 name: "code_execution"607 }608 ]609 });610611 // Extract the file IDs from the response and download each created file612 for (const block of response.content) {613 if (block.type === "bash_code_execution_tool_result") {614 const result = block.content;615 if (result.type === "bash_code_execution_result") {616 for (const outputBlock of result.content) {617 const [fileMetadata, fileResponse] = await Promise.all([618 client.files.retrieveMetadata(outputBlock.file_id),619 client.files.download(outputBlock.file_id)620 ]);621 await writeFile(fileMetadata.filename, await fileResponse.bytes());622 console.log(`Downloaded: ${fileMetadata.filename}`);623 }624 }625 }626 }627 ```628629 ```csharp C#630 AnthropicClient client = new();631632 var parameters = new MessageCreateParams633 {634 Model = Model.ClaudeOpus5,635 MaxTokens = 4096,636 Messages = [new() { Role = Role.User, Content = "Create a matplotlib visualization and save it as output.png" }],637 Tools = [new CodeExecutionTool20250825()]638 };639640 var response = await client.Messages.Create(parameters);641642 // Collect the file IDs from the tool results643 List<string> fileIds = [];644 foreach (var block in response.Content)645 {646 if (!block.TryPickBashCodeExecutionToolResult(out var toolResult))647 continue;648 if (!toolResult.Content.TryPickBashCodeExecutionResultBlock(out var result))649 continue;650 foreach (var output in result.Content)651 {652 fileIds.Add(output.FileID);653 }654 }655656 // Download each created file657 foreach (var fileId in fileIds)658 {659 var fileMetadata = await client.Files.RetrieveMetadata(fileId);660 using var download = await client.Files.Download(fileId);661 var downloadStream = await download.ReadAsStream();662 await using var target = File.Create(fileMetadata.Filename);663 await downloadStream.CopyToAsync(target);664 Console.WriteLine($"Downloaded: {fileMetadata.Filename}");665 }666 ```667668 ```go Go669 client := anthropic.NewClient()670 ctx := context.Background()671672 response, err := client.Messages.New(ctx, anthropic.MessageNewParams{673 Model: anthropic.ModelClaudeOpus5,674 MaxTokens: 4096,675 Messages: []anthropic.MessageParam{676 anthropic.NewUserMessage(anthropic.NewTextBlock("Create a matplotlib visualization and save it as output.png")),677 },678 Tools: []anthropic.ToolUnionParam{679 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},680 },681 })682 if err != nil {683 log.Fatal(err)684 }685686 fileIDs := extractFileIDs(response)687688 for _, fileID := range fileIDs {689 fileMetadata, err := client.Files.GetMetadata(ctx, fileID, anthropic.FileGetMetadataParams{})690 if err != nil {691 log.Fatal(err)692 }693694 fileContent, err := client.Files.Download(ctx, fileID, anthropic.FileDownloadParams{})695 if err != nil {696 log.Fatal(err)697 }698699 outFile, err := os.Create(fileMetadata.Filename)700 if err != nil {701 log.Fatal(err)702 }703704 _, err = io.Copy(outFile, fileContent.Body)705 if err != nil {706 log.Fatal(err)707 }708 outFile.Close()709 fileContent.Body.Close()710711 fmt.Printf("Downloaded: %s\n", fileMetadata.Filename)712 }713 // ...714715 func extractFileIDs(response *anthropic.Message) []string {716 var fileIDs []string717 for _, item := range response.Content {718 switch variant := item.AsAny().(type) {719 case anthropic.BashCodeExecutionToolResultBlock:720 // Collect the file IDs from the tool result721 for _, file := range variant.Content.Content {722 if file.FileID != "" {723 fileIDs = append(fileIDs, file.FileID)724 }725 }726 }727 }728 return fileIDs729 }730 ```731732 ```java Java733 void main() throws Exception {734 AnthropicClient client = AnthropicOkHttpClient.fromEnv();735736 MessageCreateParams params = MessageCreateParams.builder()737 .model(Model.CLAUDE_OPUS_5)738 .maxTokens(4096L)739 .addUserMessage("Create a matplotlib visualization and save it as output.png")740 .addTool(CodeExecutionTool20250825.builder().build())741 .build();742743 Message response = client.messages().create(params);744745 List<String> fileIds = extractFileIds(response);746747 for (String fileId : fileIds) {748 FileMetadata fileMetadata = client.files().retrieveMetadata(fileId);749 try (HttpResponse fileContent = client.files().download(fileId)) {750 Files.copy(751 fileContent.body(),752 Path.of(fileMetadata.filename()),753 StandardCopyOption.REPLACE_EXISTING);754 }755 IO.println("Downloaded: " + fileMetadata.filename());756 }757 }758759 List<String> extractFileIds(Message response) {760 List<String> fileIds = new ArrayList<>();761 // Collect the file IDs from the tool results762 for (ContentBlock item : response.content()) {763 item.bashCodeExecutionToolResult().ifPresent(toolResult -> {764 if (toolResult.content().isBashCodeExecutionResultBlock()) {765 BashCodeExecutionResultBlock result =766 toolResult.content().asBashCodeExecutionResultBlock();767 for (BashCodeExecutionOutputBlock output : result.content()) {768 fileIds.add(output.fileId());769 }770 }771 });772 }773 return fileIds;774 }775 ```776777 ```php PHP778 $client = new Client();779780 // Request code execution that creates files781 $response = $client->messages->create(782 maxTokens: 4096,783 messages: [784 [785 'role' => 'user',786 'content' => 'Create a matplotlib visualization and save it as output.png',787 ],788 ],789 model: Model::CLAUDE_OPUS_5,790 tools: [new CodeExecutionTool20250825()],791 );792793 /**794 * Extract file IDs from the response.795 *796 * @return list<string>797 */798 function extractFileIds(Message $response): array799 {800 $fileIds = [];801 foreach ($response->content as $block) {802 if ($block->type !== 'bash_code_execution_tool_result') {803 continue;804 }805 $resultBlock = $block->content;806 if ($resultBlock->type !== 'bash_code_execution_result') {807 continue;808 }809 foreach ($resultBlock->content as $outputBlock) {810 $fileIds[] = $outputBlock->fileID;811 }812 }813 return $fileIds;814 }815816 // Download the created files817 foreach (extractFileIds($response) as $fileId) {818 $fileMetadata = $client->files->retrieveMetadata($fileId);819 $fileContent = $client->files->download($fileId);820821 file_put_contents($fileMetadata->filename, $fileContent);822 echo "Downloaded: {$fileMetadata->filename}\n";823 }824 ```825826 ```ruby Ruby827 client = Anthropic::Client.new828829 response = client.messages.create(830 model: Anthropic::Model::CLAUDE_OPUS_5,831 max_tokens: 4096,832 messages: [833 {834 role: "user",835 content: "Create a matplotlib visualization and save it as output.png"836 }837 ],838 tools: [839 {840 type: "code_execution_20250825",841 name: "code_execution"842 }843 ]844 )845846 def extract_file_ids(response)847 file_ids = []848 response.content.each do |item|849 if item.type == :bash_code_execution_tool_result850 # WORKAROUND for anthropic-sdk-ruby union coercion bug (SDK-636): item.content is a851 # nested content union, so the typed accessors on `item.content` are unreliable.852 # Read the raw response data through the public `BaseModel#[]` API instead.853 content_item = item.content854 if content_item[:type].to_s == "bash_code_execution_result"855 Array(content_item[:content]).each do |output_block|856 file_ids << output_block[:file_id]857 end858 end859 end860 end861 file_ids862 end863864 extract_file_ids(response).each do |file_id|865 file_metadata = client.files.retrieve_metadata(file_id)866 file_content = client.files.download(file_id)867868 File.open(file_metadata.filename, "wb") do |f|869 f.write(file_content.read)870 end871872 puts "Downloaded: #{file_metadata.filename}"873 end874 ```875</CodeGroup>876877#### How generated files are captured878879Each `bash_code_execution` call gets a new, empty directory, available to the command as `$OUTPUT_DIR`. When the command finishes, the files at the top level of that directory are captured and returned as the `file_id` entries in the result's `content` list. Files written anywhere else stay in the container and aren't returned.880881The tool description tells Claude to share files by copying them into `$OUTPUT_DIR`. If your application depends on receiving a file, prompt Claude to copy it into `$OUTPUT_DIR` and list the directory in the same command, so the `ls` output confirms the capture (Claude doesn't see the `content` list):882883```bash884python /tmp/make_report.py && cp /tmp/report.pdf "$OUTPUT_DIR/" && ls "$OUTPUT_DIR"885```886887A file Claude wrote elsewhere is still in the container, so you can [reuse the container](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#container-reuse) and ask Claude to copy it into `$OUTPUT_DIR`.888889### Content Credentials on generated files890891On the Claude API, supported image, video, and audio files that Claude produces in the code execution sandbox carry [C2PA](https://c2pa.org/) Content Credentials when you download them through the [Files API](https://platform.claude.com/docs/en/build-with-claude/files). [Supported formats](https://opensource.contentauthenticity.org/docs/sdk-repos/c2pa-python/docs/supported-formats/) include PNG, JPEG, GIF, WebP, TIFF, HEIC, AVIF, SVG, MP4, MOV, MP3, WAV, FLAC, and M4A. The credential is a cryptographically signed manifest embedded in the file's metadata. It identifies Anthropic as the issuer, carries a timestamp, and records the action description "Claude provided this file at the request of a user and may have created or modified the file contents."892893Signing requires no changes to your requests or response handling, and the manifest records nothing about you, your organization, or your request. The file's visible content is unchanged. The manifest adds a few kilobytes, so the downloaded file's size and checksum differ from the file as it exists inside the container. Text files, PDFs, and office documents are not signed because they are not supported formats for signing. Files you upload are stored as-is, including any Content Credentials they already carry.894895To verify a credential, inspect the file with any C2PA-compatible tool, such as the open-source [c2patool command-line utility](https://github.com/contentauth/c2pa-rs). Re-encoding, format conversion, screenshots, and tools that strip metadata remove the credential, so a missing credential doesn't mean a file wasn't produced with Claude. For more on why a credential can be missing, see [How Claude marks AI-generated content](https://support.claude.com/en/articles/16266773-how-claude-marks-ai-generated-content).896897## Tool definition898899The code execution tool requires no additional parameters:900901```json JSON902{903 "type": "code_execution_20250825",904 "name": "code_execution"905}906```907908Both fields are fixed: `type` selects the tool version, and `name` must be `code_execution`.909910When you provide this tool, Claude automatically gains access to two sub-tools:911912* `bash_code_execution`: Run shell commands913* `text_editor_code_execution`: View, create, and edit files, including writing code914915When Claude runs code, the response also includes a top-level `container` object with the container's `id` and `expires_at` timestamp. Pass that ID back in the top-level `container` request parameter to keep using the same container. See [Container reuse](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#container-reuse).916917## Response format918919The code execution tool can return two types of results depending on the operation:920921### Bash command response922923```json Output924{925 "type": "server_tool_use",926 "id": "srvtoolu_01B3C4D5E6F7G8H9I0J1K2L3",927 "name": "bash_code_execution",928 "input": {929 "command": "ls -la | head -5"930 }931},932{933 "type": "bash_code_execution_tool_result",934 "tool_use_id": "srvtoolu_01B3C4D5E6F7G8H9I0J1K2L3",935 "content": {936 "type": "bash_code_execution_result",937 "stdout": "total 24\ndrwxr-xr-x 2 user user 4096 Jan 1 12:00 .\ndrwxr-xr-x 3 user user 4096 Jan 1 11:00 ..\n-rw-r--r-- 1 user user 220 Jan 1 12:00 data.csv\n-rw-r--r-- 1 user user 180 Jan 1 12:00 config.json",938 "stderr": "",939 "return_code": 0,940 "content": []941 }942}943```944945### File operation responses946947**View file:**948949```json Output950{951 "type": "server_tool_use",952 "id": "srvtoolu_01C4D5E6F7G8H9I0J1K2L3M4",953 "name": "text_editor_code_execution",954 "input": {955 "command": "view",956 "path": "config.json"957 }958},959{960 "type": "text_editor_code_execution_tool_result",961 "tool_use_id": "srvtoolu_01C4D5E6F7G8H9I0J1K2L3M4",962 "content": {963 "type": "text_editor_code_execution_view_result",964 "file_type": "text",965 "content": "{\n \"setting\": \"value\",\n \"debug\": true\n}",966 "num_lines": 4,967 "start_line": 1,968 "total_lines": 4969 }970}971```972973**Create file:**974975```json Output976{977 "type": "server_tool_use",978 "id": "srvtoolu_01D5E6F7G8H9I0J1K2L3M4N5",979 "name": "text_editor_code_execution",980 "input": {981 "command": "create",982 "path": "new_file.txt",983 "file_text": "Hello, World!"984 }985},986{987 "type": "text_editor_code_execution_tool_result",988 "tool_use_id": "srvtoolu_01D5E6F7G8H9I0J1K2L3M4N5",989 "content": {990 "type": "text_editor_code_execution_create_result",991 "is_file_update": false992 }993}994```995996**Edit file (str\_replace):**997998```json Output999{1000 "type": "server_tool_use",1001 "id": "srvtoolu_01E6F7G8H9I0J1K2L3M4N5O6",1002 "name": "text_editor_code_execution",1003 "input": {1004 "command": "str_replace",1005 "path": "config.json",1006 "old_str": "\"debug\": true",1007 "new_str": "\"debug\": false"1008 }1009},1010{1011 "type": "text_editor_code_execution_tool_result",1012 "tool_use_id": "srvtoolu_01E6F7G8H9I0J1K2L3M4N5O6",1013 "content": {1014 "type": "text_editor_code_execution_str_replace_result",1015 "old_start": 3,1016 "old_lines": 1,1017 "new_start": 3,1018 "new_lines": 1,1019 "lines": ["- \"debug\": true", "+ \"debug\": false"]1020 }1021}1022```10231024### Results10251026Bash command results (`bash_code_execution_result`) include:10271028* `stdout`: Output from successful execution1029* `stderr`: Error messages if execution fails1030* `return_code`: 0 for success, non-zero for failure1031* `content`: A list with an entry for each file the command left in `$OUTPUT_DIR` (see [How generated files are captured](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#how-generated-files-are-captured)). Each entry carries the `file_id` to [retrieve the file](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#retrieve-generated-files) with the Files API10321033File operation results have their own fields:10341035* **View** (`text_editor_code_execution_view_result`): `file_type`, `content`, `num_lines`, `start_line`, `total_lines`1036* **Create** (`text_editor_code_execution_create_result`): `is_file_update` (whether the file already existed)1037* **Edit** (`text_editor_code_execution_str_replace_result`): `old_start`, `old_lines`, `new_start`, `new_lines`, `lines` (diff format)10381039### Errors10401041Each tool type can return specific errors:10421043**Common errors (all tools):**10441045```json Output1046{1047 "type": "bash_code_execution_tool_result",1048 "tool_use_id": "srvtoolu_01VfmxgZ46TiHbmXgy928hQR",1049 "content": {1050 "type": "bash_code_execution_tool_result_error",1051 "error_code": "unavailable"1052 }1053}1054```10551056**Error codes by tool type:**10571058| Tool | Error code | Description |1059| ------------ | ------------------------- | ------------------------------------------------------- |1060| All tools | `unavailable` | The tool is temporarily unavailable |1061| All tools | `execution_time_exceeded` | The tool invocation exceeded the maximum execution time |1062| All tools | `invalid_tool_input` | Invalid parameters provided to the tool |1063| All tools | `too_many_requests` | Rate limit exceeded for tool usage |1064| bash | `output_file_too_large` | Command output exceeded the maximum size |1065| text\_editor | `file_not_found` | File doesn't exist (for view/edit operations) |10661067An expired container can't be reused: requests that reference it return an error instead of restoring it. Send the request again without the `container` parameter to get a new container.10681069### `pause_turn` stop reason10701071The response might include a `pause_turn` stop reason, which indicates that the API paused a long-running turn. You may provide the response back as-is in a subsequent request to let Claude continue its turn, or modify the content if you want to interrupt the conversation.10721073## Containers10741075The code execution tool runs in a secure, containerized environment designed specifically for code execution, with a higher focus on Python.10761077### Runtime environment10781079* **Python version:** 3.111080* **Operating system:** Linux-based container1081* **Architecture:** x86\_64 (AMD64)10821083### Resource limits10841085* **Memory:** 5 GiB RAM1086* **Disk space:** 5 GiB workspace storage1087* **CPU:** 1 CPU1088* **Execution time:** A tool invocation that runs past the maximum execution time returns an `execution_time_exceeded` [error](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#errors). With [programmatic tool calling](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling), each REPL cell also has a 90-second wall-clock limit10891090### Networking and security10911092* **Internet access:** Completely disabled for security1093* **External connections:** No outbound network requests permitted1094* **Sandbox isolation:** Full isolation from host system and other containers1095* **File access:** Limited to workspace directory only1096* **Workspace scoping:** Like the [Files API](https://platform.claude.com/docs/en/build-with-claude/files), containers are scoped to the request's workspace1097* **Expiration:** Containers expire 30 days after creation10981099### Pre-installed libraries11001101The sandboxed Python environment includes these commonly used libraries:11021103* **Data science:** pandas, numpy, scipy, scikit-learn, statsmodels1104* **Visualization:** matplotlib, seaborn1105* **File processing:** pyarrow, openpyxl, xlsxwriter, xlrd, pillow, python-pptx, python-docx, pypdf, pdfplumber, pypdfium2, pdf2image, pdfkit, tabula-py, reportlab\[pycairo], Img2pdf1106* **Math and computing:** sympy, mpmath1107* **Utilities:** tqdm, python-dateutil, pytz, joblib11081109The container also includes command-line tools such as unzip, unrar, 7zip, bc, rg (ripgrep), fd, and sqlite.11101111The container has no internet access, so Claude can't download or install additional packages at runtime: only the pre-installed libraries are available.11121113## Container reuse11141115You can reuse an existing container across multiple API requests by providing the container ID from a previous response. This allows you to maintain created files between requests. With `code_execution_20260120` or later and [programmatic tool calling](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling), the Python interpreter state persists as well.11161117Containers expire 30 days after creation. After about 5 minutes of inactivity a container is checkpointed, and sending a request with its ID inside the 30-day window restores it. The `expires_at` timestamp in the response's `container` object is a shorter rolling value and doesn't report the 30-day limit. A container that has expired can't be reused. Send the request again without the `container` parameter to get a new container.11181119### Example11201121<CodeGroup>1122 ```bash cURL1123 # First request: Create a file with a random number, capturing the container ID (using jq)1124 CONTAINER_ID=$(curl -s https://api.anthropic.com/v1/messages \1125 -H "x-api-key: $ANTHROPIC_API_KEY" \1126 -H "anthropic-version: 2023-06-01" \1127 -H "content-type: application/json" \1128 -d '{1129 "model": "claude-opus-5",1130 "max_tokens": 4096,1131 "messages": [{1132 "role": "user",1133 "content": "Write a file with a random number and save it to \"/tmp/number.txt\""1134 }],1135 "tools": [{1136 "type": "code_execution_20250825",1137 "name": "code_execution"1138 }]1139 }' | jq -r '.container.id')11401141 # Second request: Reuse the container to read the file1142 curl https://api.anthropic.com/v1/messages \1143 -H "x-api-key: $ANTHROPIC_API_KEY" \1144 -H "anthropic-version: 2023-06-01" \1145 -H "content-type: application/json" \1146 -d '{1147 "container": "'"$CONTAINER_ID"'",1148 "model": "claude-opus-5",1149 "max_tokens": 4096,1150 "messages": [{1151 "role": "user",1152 "content": "Read the number from \"/tmp/number.txt\" and calculate its square"1153 }],1154 "tools": [{1155 "type": "code_execution_20250825",1156 "name": "code_execution"1157 }]1158 }'1159 ```11601161 ```bash CLI1162 # First request: Create a file with a random number1163 CONTAINER_ID=$(ant messages create \1164 --model claude-opus-5 \1165 --max-tokens 4096 \1166 --message '{role: user, content: Write a file with a random number and save it to "/tmp/number.txt"}' \1167 --tool '{type: code_execution_20250825, name: code_execution}' \1168 --transform container.id --raw-output)11691170 # Second request: Reuse the container to read the file1171 ant messages create \1172 --container "$CONTAINER_ID" \1173 --model claude-opus-5 \1174 --max-tokens 4096 \1175 --message '{role: user, content: Read the number from "/tmp/number.txt" and calculate its square}' \1176 --tool '{type: code_execution_20250825, name: code_execution}'1177 ```11781179 ```python Python1180 client = anthropic.Anthropic()11811182 # First request: create a file with a random number in a new container1183 response1 = client.messages.create(1184 model="claude-opus-5",1185 max_tokens=4096,1186 messages=[1187 {1188 "role": "user",1189 "content": "Write a file with a random number and save it to '/tmp/number.txt'",1190 }1191 ],1192 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],1193 )11941195 # Second request: pass the container ID back so Claude reuses the same container1196 response2 = client.messages.create(1197 container=response1.container.id,1198 model="claude-opus-5",1199 max_tokens=4096,1200 messages=[1201 {1202 "role": "user",1203 "content": "Read the number from '/tmp/number.txt' and calculate its square",1204 }1205 ],1206 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],1207 )12081209 print(response2.to_json())1210 ```12111212 ```typescript TypeScript1213 const client = new Anthropic();12141215 // First request: Claude creates a file inside a fresh code execution container1216 const response1 = await client.messages.create({1217 model: "claude-opus-5",1218 max_tokens: 4096,1219 messages: [1220 {1221 role: "user",1222 content: "Write a file with a random number and save it to '/tmp/number.txt'"1223 }1224 ],1225 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1226 });12271228 // The response includes the container once the code execution tool has run1229 if (!response1.container) {1230 throw new Error("Expected the first response to include a container");1231 }12321233 // Second request: pass the container ID back so it reuses the same container1234 const response2 = await client.messages.create({1235 container: response1.container.id,1236 model: "claude-opus-5",1237 max_tokens: 4096,1238 messages: [1239 { role: "user", content: "Read the number from /tmp/number.txt and calculate its square" }1240 ],1241 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1242 });12431244 console.log(JSON.stringify(response2));1245 ```12461247 ```csharp C#1248 AnthropicClient client = new();12491250 // First request: Claude creates a file inside a fresh code execution container1251 var response1 = await client.Messages.Create(new()1252 {1253 Model = Model.ClaudeOpus5,1254 MaxTokens = 4096,1255 Messages = [new() { Role = Role.User, Content = "Write a file with a random number and save it to '/tmp/number.txt'" }],1256 Tools = [new CodeExecutionTool20250825()]1257 });12581259 // Second request: pass the container ID back so Claude reuses the same container1260 var response2 = await client.Messages.Create(new()1261 {1262 Container = response1.Container!.ID,1263 Model = Model.ClaudeOpus5,1264 MaxTokens = 4096,1265 Messages = [new() { Role = Role.User, Content = "Read the number from '/tmp/number.txt' and calculate its square" }],1266 Tools = [new CodeExecutionTool20250825()]1267 });12681269 Console.WriteLine(response2);1270 ```12711272 ```go Go1273 client := anthropic.NewClient()1274 ctx := context.Background()12751276 codeExecution := []anthropic.ToolUnionParam{1277 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},1278 }12791280 // First request: create a file with a random number in a new container1281 response1, err := client.Messages.New(ctx, anthropic.MessageNewParams{1282 Model: anthropic.ModelClaudeOpus5,1283 MaxTokens: 4096,1284 Messages: []anthropic.MessageParam{1285 anthropic.NewUserMessage(anthropic.NewTextBlock("Write a file with a random number and save it to '/tmp/number.txt'")),1286 },1287 Tools: codeExecution,1288 })1289 if err != nil {1290 log.Fatal(err)1291 }12921293 // Reuse the container from the first request so the file is still there.1294 response2, err := client.Messages.New(ctx, anthropic.MessageNewParams{1295 Container: anthropic.MessageCreateParamsContainerUnion{1296 OfString: anthropic.String(response1.Container.ID),1297 },1298 Model: anthropic.ModelClaudeOpus5,1299 MaxTokens: 4096,1300 Messages: []anthropic.MessageParam{1301 anthropic.NewUserMessage(anthropic.NewTextBlock("Read the number from '/tmp/number.txt' and calculate its square")),1302 },1303 Tools: codeExecution,1304 })1305 if err != nil {1306 log.Fatal(err)1307 }13081309 fmt.Println(response2.RawJSON())1310 ```13111312 ```java Java1313 AnthropicClient client = AnthropicOkHttpClient.fromEnv();13141315 // First request: create a file with a random number in a new container1316 MessageCreateParams params1 = MessageCreateParams.builder()1317 .model(Model.CLAUDE_OPUS_5)1318 .maxTokens(4096L)1319 .addUserMessage("Write a file with a random number and save it to '/tmp/number.txt'")1320 .addTool(CodeExecutionTool20250825.builder().build())1321 .build();13221323 Message response1 = client.messages().create(params1);13241325 // Second request: pass the container ID back so it reuses the same container1326 MessageCreateParams params2 = MessageCreateParams.builder()1327 .container(response1.container().orElseThrow().id())1328 .model(Model.CLAUDE_OPUS_5)1329 .maxTokens(4096L)1330 .addUserMessage("Read the number from '/tmp/number.txt' and calculate its square")1331 .addTool(CodeExecutionTool20250825.builder().build())1332 .build();13331334 Message response2 = client.messages().create(params2);1335 IO.println(ObjectMappers.jsonMapper().valueToTree(response2));1336 ```13371338 ```php PHP1339 $client = new Client();13401341 // First request: Claude writes the file inside a fresh code execution container1342 $response1 = $client->messages->create(1343 maxTokens: 4096,1344 messages: [1345 [1346 'role' => 'user',1347 'content' => "Write a file with a random number and save it to '/tmp/number.txt'",1348 ],1349 ],1350 model: Model::CLAUDE_OPUS_5,1351 tools: [new CodeExecutionTool20250825()],1352 );13531354 // Second request: reuse the container so '/tmp/number.txt' is still there1355 $response2 = $client->messages->create(1356 container: $response1->container->id,1357 maxTokens: 4096,1358 messages: [1359 [1360 'role' => 'user',1361 'content' => "Read the number from '/tmp/number.txt' and calculate its square",1362 ],1363 ],1364 model: Model::CLAUDE_OPUS_5,1365 tools: [new CodeExecutionTool20250825()],1366 );13671368 echo json_encode($response2), PHP_EOL;1369 ```13701371 ```ruby Ruby1372 client = Anthropic::Client.new13731374 # First request: Claude creates the file inside a fresh code execution container1375 response1 = client.messages.create(1376 model: Anthropic::Model::CLAUDE_OPUS_5,1377 max_tokens: 4096,1378 messages: [1379 {1380 role: "user",1381 content: "Write a file with a random number and save it to '/tmp/number.txt'"1382 }1383 ],1384 tools: [Anthropic::CodeExecutionTool20250825.new]1385 )13861387 # Second request: pass the container ID back so Claude reuses the same container1388 response2 = client.messages.create(1389 container: response1.container.id,1390 model: Anthropic::Model::CLAUDE_OPUS_5,1391 max_tokens: 4096,1392 messages: [1393 {1394 role: "user",1395 content: "Read the number from '/tmp/number.txt' and calculate its square"1396 }1397 ],1398 tools: [Anthropic::CodeExecutionTool20250825.new]1399 )14001401 puts response2.to_json1402 ```1403</CodeGroup>14041405## Using code execution with other execution tools14061407When you provide code execution alongside client-provided tools that also run code (such as a [Bash tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/bash-tool) or custom REPL), Claude is operating in a multicomputer environment. The code execution tool runs in Anthropic's sandboxed container, while your client-provided tools run in a separate environment that you control. Claude can sometimes confuse these environments, attempting to use the wrong tool or assuming state is shared between them.14081409To avoid this, add instructions to your system prompt that clarify the distinction:14101411```text wrap1412When multiple code execution environments are available, be aware that:1413- Variables, files, and state do NOT persist between different execution environments1414- Use the code_execution tool for general-purpose computation in Anthropic's sandboxed environment1415- Use client-provided execution tools (e.g., bash) when you need access to the user's local system, files, or data1416- If you need to pass results between environments, explicitly include outputs in subsequent tool calls rather than assuming shared state1417```14181419This is especially important when combining code execution with [web search](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) or [web fetch](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool), which enable code execution automatically. If your application already provides a client-side shell tool, the automatic code execution creates a second execution environment that Claude needs to distinguish between.14201421When Claude calls one of your client tools alongside code execution, the API returns the code execution call without its result. The result arrives in a later response, after you send back the `tool_result` blocks for your client tools.14221423## Streaming14241425With [streaming](https://platform.claude.com/docs/en/build-with-claude/streaming) enabled (`"stream": true`), you'll receive code execution events as they occur. The sub-tool input streams as `input_json_delta` events, and each result block arrives whole in a single `content_block_start` event:14261427```sse1428event: content_block_start1429data: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "bash_code_execution"}}14301431// Tool input streamed as partial JSON1432event: content_block_delta1433data: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"command\": \"python analyze.py\"}"}}14341435// Pause while the command runs14361437// Execution result delivered as a complete block1438event: content_block_start1439data: {"type": "content_block_start", "index": 2, "content_block": {"type": "bash_code_execution_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": {"type": "bash_code_execution_result", "stdout": " A B C\n0 1 2 3\n1 4 5 6", "stderr": "", "return_code": 0, "content": []}}}1440```14411442## Batch requests14431444You can include the code execution tool in the [Messages Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing). Code execution tool calls through the Messages Batches API are priced the same as those in regular Messages API requests.14451446## Usage and pricing14471448**Code execution is free when used with web search or web fetch.** When `web_search_20260209` (or later) or `web_fetch_20260209` (or later) is included in your API request, there are no additional charges for code execution tool calls beyond the standard input and output token costs.14491450When used without these tools, code execution is billed by execution time, tracked separately from token usage:14511452* Execution time has a minimum of 5 minutes1453* Each organization receives **1,550 free hours** of usage per month1454* Additional usage beyond 1,550 hours is billed at **$0.05 USD per hour, per container**1455* If files are included in the request, execution time is billed even if the tool is not called, because files are preloaded onto the container14561457Code execution usage is tracked in the response:14581459```json1460{1461 "usage": {1462 "input_tokens": 105,1463 "output_tokens": 239,1464 "server_tool_use": {1465 "code_execution_requests": 11466 }1467 }1468}1469```14701471## Upgrade to latest tool version14721473The latest tool version is `code_execution_20260521`. To move between the three current versions, update the `type` string in your request: all three return the response blocks documented in [Response format](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#response-format). See [Tool versions](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#tool-versions) for what each version adds and [Compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#compatibility) for the models that support them.14741475The rest of this section covers migrating from the legacy Python-only `code_execution_20250522` to the current tool versions.14761477### What's changed14781479| Component | Legacy | Current |1480| -------------- | --------------------------- | ------------------------------------------------------------------- |1481| Beta header | `code-execution-2025-05-22` | None required |1482| Tool type | `code_execution_20250522` | `code_execution_20250825` or later |1483| Capabilities | Python only | Bash commands, file operations |1484| Response types | `code_execution_result` | `bash_code_execution_result`, `text_editor_code_execution_*_result` |14851486### Backward compatibility14871488* All existing Python code execution continues to work exactly as before1489* No changes required to existing Python-only workflows14901491### Upgrade steps14921493To upgrade, update the tool type in your API requests:14941495```diff1496- "type": "code_execution_20250522"1497+ "type": "code_execution_20250825"1498```14991500**Review response handling** (if parsing responses programmatically):15011502* The API no longer sends the previous blocks for Python execution responses1503* Instead, the API sends new response types for Bash and file operations (see [Response format](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#response-format))15041505## Data retention15061507Code execution runs in server-side sandbox containers. Container data, including execution artifacts, uploaded files, and outputs, is retained for up to 30 days. This retention applies to all data processed within the container environment. Files that code execution creates in the [Files API](https://platform.claude.com/docs/en/build-with-claude/files) (retrievable with `client.files.download()`) persist until explicitly deleted.15081509For ZDR eligibility across all features, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).15101511## Next steps15121513<CardGroup cols={2}>1514 <Card title="Advisor tool" icon="compass" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool">1515 Pair a faster executor model with a higher-intelligence advisor model that provides strategic guidance mid-generation.1516 </Card>15171518 <Card title="Programmatic tool calling" icon="code" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling">1519 Call your own tools from code that runs inside the code execution container.1520 </Card>15211522 <Card title="Files API" icon="file" href="https://platform.claude.com/docs/en/build-with-claude/files">1523 Upload files for analysis and download the files that code execution creates.1524 </Card>15251526 <Card title="Using Agent Skills with the API" icon="book" href="https://platform.claude.com/docs/en/build-with-claude/skills-guide">1527 Learn how to use Agent Skills to extend Claude's capabilities through the API.1528 </Card>1529</CardGroup>1530