Source Intelligence
Sweep 28 Aug 2026 ยท 00:00Z Build v2.1.250 478 read Stable v2.1.236 Latest v2.1.250 Next v2.1.250 Feeds RSS JSON llms.txt

DisclaimerUnofficial, and not affiliated with Anthropic. Nearly all of this is read straight out of what ships: npm bundles, captured prompts, published docs. Anthropic's own notes go in verbatim, marked as theirs. The rest is my reading, and every entry carries the strings behind it. If one looks wrong, vote it down and say why.

Page history

code-execution-tool

agents-and-tools/tool-use/code-execution-tool

7 recorded changes 1549 lines First seen Last changed Upstream

History

agents-and-tools/tool-use/code-execution-tool Changed · +1 / -1 lines

from line 1113
 * **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

from line 42
 * `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.
 
from line 324
 
   ```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
from line 503
   ```
 
   ```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;
from line 803
   ```
 
   ```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: [
           [
from line 815
           ],
       ],
       model: Model::CLAUDE_OPUS_5,
-      betas: [AnthropicBeta::FILES_API_2025_04_14],
-      tools: [new BetaCodeExecutionTool20250825()],
+      tools: [new CodeExecutionTool20250825()],
   );
 
   /**
from line 823
    *
    * @return list<string>
    */
-  function extractFileIds(BetaMessage $response): array
+  function extractFileIds(Message $response): array
   {
       $fileIds = [];
       foreach ($response->content as $block) {
from line 843
 
   // 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

from line 275
 
 ### 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
from line 505
   ```
 
   ```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
from line 807
   ```
 
   ```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

from line 278
 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:
from line 302
   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
from line 308
   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",
from line 328
 
   ```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:
from line 353
   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=[
           {
from line 380
   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: [
       {
from line 412
   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")
   });
from line 422
   {
       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);
   ```
 
from line 450
   }
   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 {
from line 458
   }
 
   // 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)
from line 482
   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()
from line 489
   );
 
   // 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()
   );
 
from line 540
   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: [
       {
from line 558
       }
     ],
     tools: [
-      Anthropic::Beta::BetaCodeExecutionTool20250825.new
+      Anthropic::CodeExecutionTool20250825.new
     ]
   )
 
from line 587
   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=[
           {
from line 601
 
 
   # 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":
from line 614
 
   # 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}")
   ```
from line 626
   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: [
       {
from line 650
       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}`);
from line 668
   {
       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 = [];
from line 680
   {
       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)
       {
from line 691
   // 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);
from line 704
   	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)
from line 721
   	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)
   		}
from line 747
   	}
   // ...
 
-  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 != "" {
from line 770
 
       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()),
from line 791
       }
   }
 
-  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());
                   }
               }
from line 862
   ```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: [
       {
from line 898
   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)
from line 1320
 
   // 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{
from line 1532
 
 ## 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

from line 278
 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

from line 579
 
 ### 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
from line 929
   ```
 </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:
from line 1075
 * `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.