code-execution-tool
agents-and-tools/tool-use/code-execution-tool
History
agents-and-tools/tool-use/code-execution-tool Changed · +1 / -1 lines
* **External connections:** No outbound network requests permitted * **Sandbox isolation:** Full isolation from host system and other containers * **File access:** Limited to workspace directory only -* **Workspace scoping:** Like the [Files API](https://platform.claude.com/docs/en/build-with-claude/files), containers are scoped to the workspace of the API key +* **Workspace scoping:** Like the [Files API](https://platform.claude.com/docs/en/build-with-claude/files), containers are scoped to the request's workspace * **Expiration:** Containers expire 30 days after creation ### Pre-installed libraries
agents-and-tools/tool-use/code-execution-tool Changed · +12 / -18 lines
* `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. * `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. -All three tool versions are generally available and don't require an `anthropic-beta` header. The legacy code execution beta headers remain valid opt-ins. +None of the three tool versions requires an `anthropic-beta` header. The legacy code execution beta headers remain valid opt-ins. The examples on this page use `code_execution_20250825`, which covers the Bash and file operations they demonstrate and behaves the same way on every model in the table; 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.
```bash CLI # First, upload a file and capture the file ID - FILE_ID=$(ant files upload \ - --file ./data.csv \ - --transform id --raw-output) + FILE_ID=$(ant files upload --file ./data.csv --transform id --raw-output) # Then use the file_id with code execution ant messages create <<YAML
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $client = new Client(); // Upload a file - $fileObject = $client->beta->files->upload( + $fileObject = $client->files->upload( file: FileParam::fromResource(fopen('data.csv', 'r')), ); // Use the file_id with code execution - $response = $client->beta->messages->create( + $response = $client->messages->create( model: Model::CLAUDE_OPUS_5, maxTokens: 4096, - betas: [AnthropicBeta::FILES_API_2025_04_14], messages: [ [ 'role' => 'user', 'content' => [ - BetaTextBlockParam::with(text: 'Analyze this CSV data'), - BetaContainerUploadBlockParam::with(fileID: $fileObject->id), + TextBlockParam::with(text: 'Analyze this CSV data'), + ContainerUploadBlockParam::with(fileID: $fileObject->id), ], ], ], - tools: [new BetaCodeExecutionTool20250825()], + tools: [new CodeExecutionTool20250825()], ); echo json_encode($response), PHP_EOL;
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $client = new Client(); // Request code execution that creates files - $response = $client->beta->messages->create( + $response = $client->messages->create( maxTokens: 4096, messages: [ [
], ], model: Model::CLAUDE_OPUS_5, - betas: [AnthropicBeta::FILES_API_2025_04_14], - tools: [new BetaCodeExecutionTool20250825()], + tools: [new CodeExecutionTool20250825()], ); /**
* * @return list<string> */ - function extractFileIds(BetaMessage $response): array + function extractFileIds(Message $response): array { $fileIds = []; foreach ($response->content as $block) {
// Download the created files foreach (extractFileIds($response) as $fileId) { - $fileMetadata = $client->beta->files->retrieveMetadata($fileId); - $fileContent = $client->beta->files->download($fileId); + $fileMetadata = $client->files->retrieveMetadata($fileId); + $fileContent = $client->files->download($fileId); file_put_contents($fileMetadata->filename, $fileContent); echo "Downloaded: {$fileMetadata->filename}\n";
agents-and-tools/tool-use/code-execution-tool Changed · +3 / -5 lines
### Upload and analyze your own files -To analyze your own data files (such as CSV, Excel, or images), upload them through the Files API and reference them in your request: +To analyze your own data files (such as CSV, Excel, or images), upload them through the Files API and reference them in your request. -<Note> - This workflow doesn't require a beta header: uploading and downloading files through the Files API and referencing them in `container_upload` blocks are all generally available. -</Note> - The Python environment can process various file types uploaded through the Files API, including: * CSV
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $client = new Client(); // Upload a file
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $client = new Client(); // Request code execution that creates files
agents-and-tools/tool-use/code-execution-tool Changed · +67 / -84 lines
To analyze your own data files (such as CSV, Excel, or images), upload them through the Files API and reference them in your request: <Note> - This workflow doesn't require a beta header: uploading and downloading files through the Files API and referencing them in `container_upload` blocks are all generally available. The examples on this page send `anthropic-beta: files-api-2025-04-14`, which the API accepts but doesn't require. + This workflow doesn't require a beta header: uploading and downloading files through the Files API and referencing them in `container_upload` blocks are all generally available. </Note> The Python environment can process various file types uploaded through the Files API, including:
FILE_ID=$(curl --fail-with-body -sS https://api.anthropic.com/v1/files \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ - -H "anthropic-beta: files-api-2025-04-14" \ -F "[email protected]" | jq -r '.id') # Then use the file_id with code execution
curl --fail-with-body -sS https://api.anthropic.com/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ - -H "anthropic-beta: files-api-2025-04-14" \ -H "content-type: application/json" \ -d '{ "model": "claude-opus-5",
```bash CLI # First, upload a file and capture the file ID - FILE_ID=$(ant beta:files upload \ + FILE_ID=$(ant files upload \ --file ./data.csv \ --transform id --raw-output) # Then use the file_id with code execution - ant beta:messages create \ - --beta files-api-2025-04-14 <<YAML + ant messages create <<YAML model: claude-opus-5 max_tokens: 4096 messages:
client = anthropic.Anthropic() # Upload a file - file_object = client.beta.files.upload(file=Path("data.csv")) + file_object = client.files.upload(file=Path("data.csv")) # Use the file_id with code execution - response = client.beta.messages.create( + response = client.messages.create( model="claude-opus-5", - betas=["files-api-2025-04-14"], max_tokens=4096, messages=[ {
const client = new Anthropic(); // Upload a file - const fileObject = await client.beta.files.upload({ + const fileObject = await client.files.upload({ file: createReadStream("data.csv") }); // Use the file_id with code execution - const response = await client.beta.messages.create({ + const response = await client.messages.create({ model: "claude-opus-5", - betas: ["files-api-2025-04-14"], max_tokens: 4096, messages: [ {
AnthropicClient client = new(); // Upload a file - var fileObject = await client.Beta.Files.Upload(new FileUploadParams + var fileObject = await client.Files.Upload(new FileUploadParams { File = File.OpenRead("data.csv") });
{ Model = Model.ClaudeOpus5, MaxTokens = 4096, - Betas = [AnthropicBeta.FilesApi2025_04_14], Messages = [ new() { Role = Role.User, Content = new([ - new BetaTextBlockParam { Text = "Analyze this CSV data" }, - new BetaContainerUploadBlockParam { FileID = fileObject.ID } + new TextBlockParam { Text = "Analyze this CSV data" }, + new ContainerUploadBlockParam { FileID = fileObject.ID } ]) } ], - Tools = [new BetaCodeExecutionTool20250825()] + Tools = [new CodeExecutionTool20250825()] }; - var response = await client.Beta.Messages.Create(parameters); + var response = await client.Messages.Create(parameters); Console.WriteLine(response); ```
} defer file.Close() - fileObject, err := client.Beta.Files.Upload(ctx, anthropic.BetaFileUploadParams{ + fileObject, err := client.Files.Upload(ctx, anthropic.FileUploadParams{ File: file, }) if err != nil {
} // Use the file_id with code execution - response, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{ + response, err := client.Messages.New(ctx, anthropic.MessageNewParams{ Model: anthropic.ModelClaudeOpus5, MaxTokens: 4096, - Messages: []anthropic.BetaMessageParam{ - anthropic.NewBetaUserMessage( - anthropic.NewBetaTextBlock("Analyze this CSV data"), - anthropic.NewBetaContainerUploadBlock(fileObject.ID), + Messages: []anthropic.MessageParam{ + anthropic.NewUserMessage( + anthropic.NewTextBlock("Analyze this CSV data"), + anthropic.NewContainerUploadBlock(fileObject.ID), ), }, - Tools: []anthropic.BetaToolUnionParam{ - {OfCodeExecutionTool20250825: &anthropic.BetaCodeExecutionTool20250825Param{}}, + Tools: []anthropic.ToolUnionParam{ + {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}}, }, - Betas: []anthropic.AnthropicBeta{ - anthropic.AnthropicBetaFilesAPI2025_04_14, - }, }) if err != nil { log.Fatal(err)
AnthropicClient client = AnthropicOkHttpClient.fromEnv(); // Upload a file - FileMetadata fileObject = client.beta().files().upload( + FileMetadata fileObject = client.files().upload( FileUploadParams.builder() .file(Path.of("data.csv")) .build()
); // Use the file_id with code execution - BetaMessage response = client.beta().messages().create( + Message response = client.messages().create( MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_5) - .addBeta(AnthropicBeta.FILES_API_2025_04_14) .maxTokens(4096L) - .addUserMessageOfBetaContentBlockParams(List.of( - BetaContentBlockParam.ofText(BetaTextBlockParam.builder() + .addUserMessageOfBlockParams(List.of( + ContentBlockParam.ofText(TextBlockParam.builder() .text("Analyze this CSV data") .build()), - BetaContentBlockParam.ofContainerUpload(BetaContainerUploadBlockParam.builder() + ContentBlockParam.ofContainerUpload(ContainerUploadBlockParam.builder() .fileId(fileObject.id()) .build()) )) - .addTool(BetaCodeExecutionTool20250825.builder().build()) + .addTool(CodeExecutionTool20250825.builder().build()) .build() );
client = Anthropic::Client.new # Upload a file - file_object = client.beta.files.upload( + file_object = client.files.upload( file: Pathname("data.csv") ) # Use the file_id with code execution - response = client.beta.messages.create( + response = client.messages.create( model: Anthropic::Model::CLAUDE_OPUS_5, - betas: [Anthropic::AnthropicBeta::FILES_API_2025_04_14], max_tokens: 4096, messages: [ {
} ], tools: [ - Anthropic::Beta::BetaCodeExecutionTool20250825.new + Anthropic::CodeExecutionTool20250825.new ] )
client = Anthropic() # Request code execution that creates files - response = client.beta.messages.create( + response = client.messages.create( model="claude-opus-5", - betas=["files-api-2025-04-14"], max_tokens=4096, messages=[ {
# Extract file IDs from the response - def extract_file_ids(response: BetaMessage) -> list[str]: + def extract_file_ids(response: Message) -> list[str]: file_ids: list[str] = [] for item in response.content: if item.type == "bash_code_execution_tool_result":
# Download the created files for file_id in extract_file_ids(response): - file_metadata = client.beta.files.retrieve_metadata(file_id) - file_content = client.beta.files.download(file_id) + file_metadata = client.files.retrieve_metadata(file_id) + file_content = client.files.download(file_id) file_content.write_to_file(file_metadata.filename) print(f"Downloaded: {file_metadata.filename}") ```
const client = new Anthropic(); // Request code execution that creates files - const response = await client.beta.messages.create({ + const response = await client.messages.create({ model: "claude-opus-5", - betas: ["files-api-2025-04-14"], max_tokens: 4096, messages: [ {
if (result.type === "bash_code_execution_result") { for (const outputBlock of result.content) { const [fileMetadata, fileResponse] = await Promise.all([ - client.beta.files.retrieveMetadata(outputBlock.file_id), - client.beta.files.download(outputBlock.file_id) + client.files.retrieveMetadata(outputBlock.file_id), + client.files.download(outputBlock.file_id) ]); await writeFile(fileMetadata.filename, await fileResponse.bytes()); console.log(`Downloaded: ${fileMetadata.filename}`);
{ Model = Model.ClaudeOpus5, MaxTokens = 4096, - Betas = [AnthropicBeta.FilesApi2025_04_14], Messages = [new() { Role = Role.User, Content = "Create a matplotlib visualization and save it as output.png" }], - Tools = [new BetaCodeExecutionTool20250825()] + Tools = [new CodeExecutionTool20250825()] }; - var response = await client.Beta.Messages.Create(parameters); + var response = await client.Messages.Create(parameters); // Collect the file IDs from the tool results List<string> fileIds = [];
{ if (!block.TryPickBashCodeExecutionToolResult(out var toolResult)) continue; - if (!toolResult.Content.TryPickBetaBashCodeExecutionResultBlock(out var result)) + if (!toolResult.Content.TryPickBashCodeExecutionResultBlock(out var result)) continue; foreach (var output in result.Content) {
// Download each created file foreach (var fileId in fileIds) { - var fileMetadata = await client.Beta.Files.RetrieveMetadata(fileId); - using var download = await client.Beta.Files.Download(fileId); + var fileMetadata = await client.Files.RetrieveMetadata(fileId); + using var download = await client.Files.Download(fileId); var downloadStream = await download.ReadAsStream(); await using var target = File.Create(fileMetadata.Filename); await downloadStream.CopyToAsync(target);
client := anthropic.NewClient() ctx := context.Background() - response, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{ + response, err := client.Messages.New(ctx, anthropic.MessageNewParams{ Model: anthropic.ModelClaudeOpus5, MaxTokens: 4096, - Messages: []anthropic.BetaMessageParam{ - anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Create a matplotlib visualization and save it as output.png")), + Messages: []anthropic.MessageParam{ + anthropic.NewUserMessage(anthropic.NewTextBlock("Create a matplotlib visualization and save it as output.png")), }, - Tools: []anthropic.BetaToolUnionParam{ - {OfCodeExecutionTool20250825: &anthropic.BetaCodeExecutionTool20250825Param{}}, + Tools: []anthropic.ToolUnionParam{ + {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}}, }, - Betas: []anthropic.AnthropicBeta{ - anthropic.AnthropicBetaFilesAPI2025_04_14, - }, }) if err != nil { log.Fatal(err)
fileIDs := extractFileIDs(response) for _, fileID := range fileIDs { - fileMetadata, err := client.Beta.Files.GetMetadata(ctx, fileID, anthropic.BetaFileGetMetadataParams{}) + fileMetadata, err := client.Files.GetMetadata(ctx, fileID) if err != nil { log.Fatal(err) } - fileContent, err := client.Beta.Files.Download(ctx, fileID, anthropic.BetaFileDownloadParams{}) + fileContent, err := client.Files.Download(ctx, fileID) if err != nil { log.Fatal(err) }
} // ... - func extractFileIDs(response *anthropic.BetaMessage) []string { + func extractFileIDs(response *anthropic.Message) []string { var fileIDs []string for _, item := range response.Content { switch variant := item.AsAny().(type) { - case anthropic.BetaBashCodeExecutionToolResultBlock: + case anthropic.BashCodeExecutionToolResultBlock: // Collect the file IDs from the tool result for _, file := range variant.Content.Content { if file.FileID != "" {
MessageCreateParams params = MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_5) - .addBeta(AnthropicBeta.FILES_API_2025_04_14) .maxTokens(4096L) .addUserMessage("Create a matplotlib visualization and save it as output.png") - .addTool(BetaCodeExecutionTool20250825.builder().build()) + .addTool(CodeExecutionTool20250825.builder().build()) .build(); - BetaMessage response = client.beta().messages().create(params); + Message response = client.messages().create(params); List<String> fileIds = extractFileIds(response); for (String fileId : fileIds) { - FileMetadata fileMetadata = client.beta().files().retrieveMetadata(fileId); - try (HttpResponse fileContent = client.beta().files().download(fileId)) { + FileMetadata fileMetadata = client.files().retrieveMetadata(fileId); + try (HttpResponse fileContent = client.files().download(fileId)) { Files.copy( fileContent.body(), Path.of(fileMetadata.filename()),
} } - List<String> extractFileIds(BetaMessage response) { + List<String> extractFileIds(Message response) { List<String> fileIds = new ArrayList<>(); // Collect the file IDs from the tool results - for (BetaContentBlock item : response.content()) { + for (ContentBlock item : response.content()) { item.bashCodeExecutionToolResult().ifPresent(toolResult -> { - if (toolResult.content().isBetaBashCodeExecutionResultBlock()) { - BetaBashCodeExecutionResultBlock result = - toolResult.content().asBetaBashCodeExecutionResultBlock(); - for (BetaBashCodeExecutionOutputBlock output : result.content()) { + if (toolResult.content().isBashCodeExecutionResultBlock()) { + BashCodeExecutionResultBlock result = + toolResult.content().asBashCodeExecutionResultBlock(); + for (BashCodeExecutionOutputBlock output : result.content()) { fileIds.add(output.fileId()); } }
```ruby Ruby client = Anthropic::Client.new - response = client.beta.messages.create( + response = client.messages.create( model: Anthropic::Model::CLAUDE_OPUS_5, - betas: ["files-api-2025-04-14"], max_tokens: 4096, messages: [ {
end extract_file_ids(response).each do |file_id| - file_metadata = client.beta.files.retrieve_metadata(file_id) - file_content = client.beta.files.download(file_id) + file_metadata = client.files.retrieve_metadata(file_id) + file_content = client.files.download(file_id) File.open(file_metadata.filename, "wb") do |f| f.write(file_content.read)
// Reuse the container from the first request so the file is still there. response2, err := client.Messages.New(ctx, anthropic.MessageNewParams{ - Container: anthropic.String(response1.Container.ID), + Container: anthropic.MessageCreateParamsContainerUnion{ + OfString: anthropic.String(response1.Container.ID), + }, Model: anthropic.ModelClaudeOpus5, MaxTokens: 4096, Messages: []anthropic.MessageParam{
## Data retention -Code 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.beta.files.download()`) persist until explicitly deleted. +Code 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. For ZDR eligibility across all features, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).
agents-and-tools/tool-use/code-execution-tool Changed · +1 / -1 lines
To analyze your own data files (such as CSV, Excel, or images), upload them through the Files API and reference them in your request: <Note> - Using the Files API with code execution requires the Files API beta header: `"anthropic-beta": "files-api-2025-04-14"` + This workflow doesn't require a beta header: uploading and downloading files through the Files API and referencing them in `container_upload` blocks are all generally available. The examples on this page send `anthropic-beta: files-api-2025-04-14`, which the API accepts but doesn't require. </Note> The Python environment can process various file types uploaded through the Files API, including:
agents-and-tools/tool-use/code-execution-tool Changed · +14 / -2 lines
#### How generated files are captured
### Retrieve generated files -When Claude creates files during code execution, each created 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): +When 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): <CodeGroup> ```bash cURL
``` </CodeGroup> +#### How generated files are captured + +Each `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. + +The 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): + +```bash +python /tmp/make_report.py && cp /tmp/report.pdf "$OUTPUT_DIR/" && ls "$OUTPUT_DIR" +``` + +A 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`. + ## Tool definition The code execution tool requires no additional parameters:
* `stdout`: Output from successful execution * `stderr`: Error messages if execution fails * `return_code`: 0 for success, non-zero for failure -* `content`: A list with an entry for each file the command created. 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 API +* `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 API File operation results have their own fields:
agents-and-tools/tool-use/code-execution-tool First recorded · 1562 lines, first recorded
## Model compatibility ## Platform availability ## Quick start ## How code execution works ### When Claude runs code ## Work with files ### Upload and analyze your own files #### Upload and analyze files ### Retrieve generated files ## Tool definition ## Response format ### Bash command response ### File operation responses ### Results ### Errors ### `pause_turn` stop reason ## Containers ### Runtime environment ### Resource limits ### Networking and security ### Pre-installed libraries ## Container reuse ### Example ## Using code execution with other execution tools ## Streaming ## Batch requests ## Usage and pricing ## Upgrade to latest tool version ### What's changed ### Backward compatibility ### Upgrade steps ## Data retention ## Next steps
The first capture of this source. The page was already there, and this is what it said.
---
title: Code execution tool
url: https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool
description: Run Python and bash code in a sandboxed container to analyze data, generate files, and iterate on solutions.
---
Claude 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.
**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.
Code 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.
<Note>
Reach out through the [feedback form](https://forms.gle/LTAU6Xn2puCJMi1n6) to share your feedback on this feature.
</Note>
<Note>
For how zero data retention (ZDR) applies to this feature, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).
</Note>
## Model compatibility
The code execution tool is available on the following models:
| Model | Tool versions |
| ---------------------------------------------- | ------------------------------------------------------------------------------- |
| Claude Opus 5 (claude-opus-5) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Fable 5 (claude-fable-5) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Mythos 5 (claude-mythos-5) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Sonnet 5 (claude-sonnet-5) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Opus 4.8 (claude-opus-4-8) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Opus 4.7 (claude-opus-4-7) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Opus 4.6 (claude-opus-4-6) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Sonnet 4.6 (claude-sonnet-4-6) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Opus 4.5 (claude-opus-4-5-20251101) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
| Claude Haiku 4.5 (claude-haiku-4-5-20251001) | `code_execution_20250825`, `code_execution_20260120`, `code_execution_20260521` |
Each tool version builds on the previous one:
* `code_execution_20250825` supports Bash commands and file operations.
* `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.
* `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.
All three tool versions are generally available and don't require an `anthropic-beta` header. The legacy code execution beta headers remain valid opt-ins.
The examples on this page use `code_execution_20250825`, which covers the Bash and file operations they demonstrate and behaves the same way on every model in the table; 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.
<Note>
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.
</Note>
<Warning>
Older tool versions are not guaranteed to stay compatible with newer models. When you adopt a new model, check the [model compatibility table](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#model-compatibility) and prefer the newest tool version your integration supports.
</Warning>
## Platform availability
Code execution is available on:
* **Claude API** (Anthropic)
* **[Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws)**
* **[Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry)** (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))
Code execution is not currently available on Amazon Bedrock or Google Cloud.
<Note>
For [Claude Mythos Preview](https://anthropic.com/glasswing), code execution is supported on the Claude API and Microsoft Foundry only. It is not available for Mythos Preview on Amazon Bedrock, Claude Platform on AWS, or Google Cloud.
</Note>
## Quick start
Here's an example that asks Claude to perform a calculation:
<CodeGroup>
```bash cURL
curl --fail-with-body -sS https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 4096,
"messages": [
{
"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]"
}
],
"tools": [
{
"type": "code_execution_20250825",
"name": "code_execution"
}
]
}'
```
```bash CLI
ant messages create \
--model claude-opus-5 \
--max-tokens 4096 \
--message '{
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]"
}' \
--tool '{type: code_execution_20250825, name: code_execution}'
```
```python Python
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
messages=[
{
"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]",
}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
print(response.to_json())
```
```typescript TypeScript
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-opus-5",
max_tokens: 4096,
messages: [
{
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]"
}
],
tools: [{ type: "code_execution_20250825", name: "code_execution" }]
});
console.log(JSON.stringify(response));
```
```csharp C#
AnthropicClient client = new();
var message = await client.Messages.Create(new()
{
Model = Model.ClaudeOpus5,
MaxTokens = 4096,
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]" }],
Tools = [new CodeExecutionTool20250825()]
});
Console.WriteLine(message);
```
```go Go
client := anthropic.NewClient()
response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus5,
MaxTokens: 4096,
Messages: []anthropic.MessageParam{
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]")),
},
Tools: []anthropic.ToolUnionParam{
{OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON())
```
```java Java
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5)
.maxTokens(4096L)
.addUserMessage("Use the code execution tool to calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")
.addTool(CodeExecutionTool20250825.builder().build())
.build();
Message response = client.messages().create(params);
IO.println(ObjectMappers.jsonMapper().valueToTree(response));
```
```php PHP
$client = new Client();
$message = $client->messages->create(
maxTokens: 4096,
messages: [
[
'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]',
],
],
model: Model::CLAUDE_OPUS_5,
tools: [new CodeExecutionTool20250825()],
);
echo json_encode($message, JSON_PRETTY_PRINT), PHP_EOL;
```
```ruby Ruby
client = Anthropic::Client.new
message = client.messages.create(
model: Anthropic::Model::CLAUDE_OPUS_5,
max_tokens: 4096,
messages: [
{
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]"
}
],
tools: [Anthropic::CodeExecutionTool20250825.new]
)
puts message.to_json
```
</CodeGroup>
The 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.
## How code execution works
When you add the code execution tool to your API request:
1. Claude evaluates whether code execution would help answer your question
2. The tool automatically provides Claude with the following capabilities:
* **Bash commands:** Run shell commands for system operations
* **File operations:** Create, view, and edit files directly, including writing code
3. Claude can use any combination of these capabilities in a single request
4. 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 available
5. 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 tools
6. 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))
7. Claude provides results with any generated charts, calculations, or analysis
The 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.
### When Claude runs code
Claude runs code when the request benefits from computation or file handling:
* Non-trivial math (large numbers, many steps, precision-sensitive results)
* Data analysis, file parsing, or visualization
* Algorithm execution or simulation
* Explicit requests to "run", "compute", or "execute"
Claude answers directly without running code for:
* Simple arithmetic and well-known math facts
* Factual, conversational, or creative requests
* Simple unit conversions or translations
If you want Claude to run code for a borderline request, ask explicitly (for example, "run code to verify this").
## Work with files
### Upload and analyze your own files
To analyze your own data files (such as CSV, Excel, or images), upload them through the Files API and reference them in your request:
<Note>
Using the Files API with code execution requires the Files API beta header: `"anthropic-beta": "files-api-2025-04-14"`
</Note>
The Python environment can process various file types uploaded through the Files API, including:
* CSV
* Excel (.xlsx, .xls)
* JSON
* XML
* Images (JPEG, PNG, GIF, WebP)
* Text files (.txt, .md, .py, and others)
#### Upload and analyze files
1. **Upload your file** using the [Files API](https://platform.claude.com/docs/en/build-with-claude/files)
2. **Reference the file** in your message using a `container_upload` content block
3. **Include the code execution tool** in your API request
<CodeGroup>
```bash cURL
Cut at 300 lines.