Code execution tool
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 and web fetch 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.
Tool versions
The code execution tool has three current versions, and every supported model accepts all three. Each version builds on the previous one:
code_execution_20250825supports Bash commands and file operations.code_execution_20260120adds REPL state persistence and programmatic tool calling from within the sandbox. Claude Haiku 4.5 accepts thecode_execution_20260120andcode_execution_20260521tool types, but programmatic tool calling and the REPL state persistence that depends on it aren't available on it, so the newer versions behave likecode_execution_20250825there.code_execution_20260521is the same runtime ascode_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-zeroreturn_codeand adetection_timeoutstatus message in its output. This is separate from theexecution_time_exceedederror code, which the API returns when a whole tool invocation exceeds the maximum execution time.
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 supported model; use code_execution_20260120 or later when you need programmatic tool calling or REPL state persistence. The current web search and web fetch tools (web_search_20260209, web_fetch_20260209, and later) require code_execution_20260120 or later as their code execution version.
Older tool versions aren't guaranteed to stay compatible with newer models. When you adopt a new model, check Tool versions and Compatibility, and prefer the newest tool version your integration supports.
Quick start
Here's an example that asks Claude to perform a calculation:
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())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. See Response format for the block shapes.
How code execution works
When you add the code execution tool to your API request:
- Claude evaluates whether code execution would help answer your question
- 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
- Claude can use any combination of these capabilities in a single request
- 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 are available
- 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_resultblocks 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 thetool_resultblocks for your client tools - Each request runs in a new container unless you pass an earlier response's container ID back (see Container reuse)
- 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, 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.
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
- Upload your file using the Files API
- Reference the file in your message using a
container_uploadcontent block - Include the code execution tool in your API request
client = anthropic.Anthropic()
# Upload a file
file_object = client.files.upload(file=Path("data.csv"))
# Use the file_id with code execution
response = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Analyze this CSV data"},
{"type": "container_upload", "file_id": file_object.id},
],
}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
print(response.to_json())Retrieve generated files
When Claude saves files to its output directory during code execution (see 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:
client = Anthropic()
# Request code execution that creates files
response = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Create a matplotlib visualization and save it as output.png",
}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
# Extract file IDs from the response
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":
content_item = item.content
if content_item.type == "bash_code_execution_result":
for output_block in content_item.content:
file_ids.append(output_block.file_id)
return file_ids
# Download the created files
for file_id in extract_file_ids(response):
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}")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):
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 and ask Claude to copy it into $OUTPUT_DIR.
Content Credentials on generated files
On the Claude API, supported image, video, and audio files that Claude produces in the code execution sandbox carry C2PA Content Credentials when you download them through the Files API. 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."
Signing 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.
To verify a credential, inspect the file with any C2PA-compatible tool, such as the open-source c2patool command-line utility. 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.
Tool definition
The code execution tool requires no additional parameters:
{
"type": "code_execution_20250825",
"name": "code_execution"
}Both fields are fixed: type selects the tool version, and name must be code_execution.
When you provide this tool, Claude automatically gains access to two sub-tools:
bash_code_execution: Run shell commandstext_editor_code_execution: View, create, and edit files, including writing code
When 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.
Response format
The code execution tool can return two types of results depending on the operation:
Bash command response
{
"type": "server_tool_use",
"id": "srvtoolu_01B3C4D5E6F7G8H9I0J1K2L3",
"name": "bash_code_execution",
"input": {
"command": "ls -la | head -5"
}
},
{
"type": "bash_code_execution_tool_result",
"tool_use_id": "srvtoolu_01B3C4D5E6F7G8H9I0J1K2L3",
"content": {
"type": "bash_code_execution_result",
"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",
"stderr": "",
"return_code": 0,
"content": []
}
}File operation responses
View file:
{
"type": "server_tool_use",
"id": "srvtoolu_01C4D5E6F7G8H9I0J1K2L3M4",
"name": "text_editor_code_execution",
"input": {
"command": "view",
"path": "config.json"
}
},
{
"type": "text_editor_code_execution_tool_result",
"tool_use_id": "srvtoolu_01C4D5E6F7G8H9I0J1K2L3M4",
"content": {
"type": "text_editor_code_execution_view_result",
"file_type": "text",
"content": "{\n \"setting\": \"value\",\n \"debug\": true\n}",
"num_lines": 4,
"start_line": 1,
"total_lines": 4
}
}Create file:
{
"type": "server_tool_use",
"id": "srvtoolu_01D5E6F7G8H9I0J1K2L3M4N5",
"name": "text_editor_code_execution",
"input": {
"command": "create",
"path": "new_file.txt",
"file_text": "Hello, World!"
}
},
{
"type": "text_editor_code_execution_tool_result",
"tool_use_id": "srvtoolu_01D5E6F7G8H9I0J1K2L3M4N5",
"content": {
"type": "text_editor_code_execution_create_result",
"is_file_update": false
}
}Edit file (str_replace):
{
"type": "server_tool_use",
"id": "srvtoolu_01E6F7G8H9I0J1K2L3M4N5O6",
"name": "text_editor_code_execution",
"input": {
"command": "str_replace",
"path": "config.json",
"old_str": "\"debug\": true",
"new_str": "\"debug\": false"
}
},
{
"type": "text_editor_code_execution_tool_result",
"tool_use_id": "srvtoolu_01E6F7G8H9I0J1K2L3M4N5O6",
"content": {
"type": "text_editor_code_execution_str_replace_result",
"old_start": 3,
"old_lines": 1,
"new_start": 3,
"new_lines": 1,
"lines": ["- \"debug\": true", "+ \"debug\": false"]
}
}Results
Bash command results (bash_code_execution_result) include:
stdout: Output from successful executionstderr: Error messages if execution failsreturn_code: 0 for success, non-zero for failurecontent: A list with an entry for each file the command left in$OUTPUT_DIR(see How generated files are captured). Each entry carries thefile_idto retrieve the file with the Files API
File operation results have their own fields:
- View (
text_editor_code_execution_view_result):file_type,content,num_lines,start_line,total_lines - Create (
text_editor_code_execution_create_result):is_file_update(whether the file already existed) - Edit (
text_editor_code_execution_str_replace_result):old_start,old_lines,new_start,new_lines,lines(diff format)
Errors
Each tool type can return specific errors:
Common errors (all tools):
{
"type": "bash_code_execution_tool_result",
"tool_use_id": "srvtoolu_01VfmxgZ46TiHbmXgy928hQR",
"content": {
"type": "bash_code_execution_tool_result_error",
"error_code": "unavailable"
}
}Error codes by tool type:
| Tool | Error code | Description |
|---|---|---|
| All tools | unavailable | The tool is temporarily unavailable |
| All tools | execution_time_exceeded | The tool invocation exceeded the maximum execution time |
| All tools | invalid_tool_input | Invalid parameters provided to the tool |
| All tools | too_many_requests | Rate limit exceeded for tool usage |
| bash | output_file_too_large | Command output exceeded the maximum size |
| text_editor | file_not_found | File doesn't exist (for view/edit operations) |
An 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.
pause_turn stop reason
The 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.
Containers
The code execution tool runs in a secure, containerized environment designed specifically for code execution, with a higher focus on Python.
Runtime environment
- Python version: 3.11
- Operating system: Linux-based container
- Architecture: x86_64 (AMD64)
Resource limits
- Memory: 5 GiB RAM
- Disk space: 5 GiB workspace storage
- CPU: 1 CPU
- Execution time: A tool invocation that runs past the maximum execution time returns an
execution_time_exceedederror. With programmatic tool calling, each REPL cell also has a 90-second wall-clock limit
Networking and security
- Internet access: Completely disabled for security
- 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, containers are scoped to the request's workspace
- Expiration: Containers expire 30 days after creation
Pre-installed libraries
The sandboxed Python environment includes these commonly used libraries:
- Data science: pandas, numpy, scipy, scikit-learn, statsmodels
- Visualization: matplotlib, seaborn
- File processing: pyarrow, openpyxl, xlsxwriter, xlrd, pillow, python-pptx, python-docx, pypdf, pdfplumber, pypdfium2, pdf2image, pdfkit, tabula-py, reportlab[pycairo], Img2pdf
- Math and computing: sympy, mpmath
- Utilities: tqdm, python-dateutil, pytz, joblib
The container also includes command-line tools such as unzip, unrar, 7zip, bc, rg (ripgrep), fd, and sqlite.
The container has no internet access, so Claude can't download or install additional packages at runtime: only the pre-installed libraries are available.
Container reuse
You 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, the Python interpreter state persists as well.
Containers 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.
Example
client = anthropic.Anthropic()
# First request: create a file with a random number in a new container
response1 = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Write a file with a random number and save it to '/tmp/number.txt'",
}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
# Second request: pass the container ID back so Claude reuses the same container
response2 = client.messages.create(
container=response1.container.id,
model="claude-opus-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Read the number from '/tmp/number.txt' and calculate its square",
}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
print(response2.to_json())Using code execution with other execution tools
When you provide code execution alongside client-provided tools that also run code (such as a 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.
To avoid this, add instructions to your system prompt that clarify the distinction:
When multiple code execution environments are available, be aware that:
- Variables, files, and state do NOT persist between different execution environments
- Use the code_execution tool for general-purpose computation in Anthropic's sandboxed environment
- Use client-provided execution tools (e.g., bash) when you need access to the user's local system, files, or data
- If you need to pass results between environments, explicitly include outputs in subsequent tool calls rather than assuming shared stateThis is especially important when combining code execution with web search or web fetch, 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.
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.
Streaming
With 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:
event: content_block_start
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "bash_code_execution"}}
// Tool input streamed as partial JSON
event: content_block_delta
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"command\": \"python analyze.py\"}"}}
// Pause while the command runs
// Execution result delivered as a complete block
event: content_block_start
data: {"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": []}}}Batch requests
You can include the code execution tool in the Messages Batches API. Code execution tool calls through the Messages Batches API are priced the same as those in regular Messages API requests.
Usage and pricing
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.
When used without these tools, code execution is billed by execution time, tracked separately from token usage:
- Execution time has a minimum of 5 minutes
- Each organization receives 1,550 free hours of usage per month
- Additional usage beyond 1,550 hours is billed at $0.05 USD per hour, per container
- If files are included in the request, execution time is billed even if the tool is not called, because files are preloaded onto the container
Code execution usage is tracked in the response:
{
"usage": {
"input_tokens": 105,
"output_tokens": 239,
"server_tool_use": {
"code_execution_requests": 1
}
}
}Upgrade to latest tool version
The 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. See Tool versions for what each version adds and Compatibility for the models that support them.
The rest of this section covers migrating from the legacy Python-only code_execution_20250522 to the current tool versions.
What's changed
| Component | Legacy | Current |
|---|---|---|
| Beta header | code-execution-2025-05-22 | None required |
| Tool type | code_execution_20250522 | code_execution_20250825 or later |
| Capabilities | Python only | Bash commands, file operations |
| Response types | code_execution_result | bash_code_execution_result, text_editor_code_execution_*_result |
Backward compatibility
- All existing Python code execution continues to work exactly as before
- No changes required to existing Python-only workflows
Upgrade steps
To upgrade, update the tool type in your API requests:
- "type": "code_execution_20250522"
+ "type": "code_execution_20250825"Review response handling (if parsing responses programmatically):
- The API no longer sends the previous blocks for Python execution responses
- Instead, the API sends new response types for Bash and file operations (see Response format)
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 (retrievable with client.files.download()) persist until explicitly deleted.
For ZDR eligibility across all features, see API and data retention.
Next steps
Pair a faster executor model with a higher-intelligence advisor model that provides strategic guidance mid-generation.
Call your own tools from code that runs inside the code execution container.
Upload files for analysis and download the files that code execution creates.
Learn how to use Agent Skills to extend Claude's capabilities through the API.
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
- On Microsoft Foundry, code execution requires a Hosted on Anthropic deployment. ↩
- Every supported model accepts all three 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_20250825there. - For Claude Mythos Preview, code execution is supported on the Claude API and Microsoft Foundry.
Was this page helpful?