Process results programmatically changedagents-and-tools/tool-use/programmatic-tool-calling
Nearest release: v2.1.312, published under an hour before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+26added
Lines−26removed
From line
32
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits19to this page, all time
The whole hunk
from line 32, old and new numbered
/
from line 32
3232 - Claude Haiku 4.5 accepts the `code_execution_20260120` and later tool versions but doesn't support programmatic tool calling.
3333---
3434
35Programmatic tool calling allows Claude to write code that calls your tools programmatically within a [code execution](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) container, rather than requiring round trips through the model for each tool call. This reduces latency for multi-tool workflows and decreases token consumption by allowing Claude to filter or process data before it reaches the model's context window. On agentic search benchmarks such as [BrowseComp](https://arxiv.org/abs/2504.12516) and [DeepSearchQA](https://github.com/google-deepmind/deepsearchqa), which test multistep web research and complex information retrieval, adding programmatic tool calling on top of basic search tools improved performance by an average of 11 percent while using 24 percent fewer input tokens (see [Improved web search with dynamic filtering](https://claude.com/blog/improved-web-search-with-dynamic-filtering)).
35Programmatic tool calling allows Claude to write code that calls your tools programmatically within a [code execution](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) container, rather than requiring round trips through the model for each tool call. This reduces latency for multi-tool workflows and decreases token consumption by allowing Claude to filter or process data before it reaches the model’s context window. On agentic search benchmarks such as [BrowseComp](https://arxiv.org/abs/2504.12516) and [DeepSearchQA](https://github.com/google-deepmind/deepsearchqa), which test multistep web research and complex information retrieval, adding programmatic tool calling on top of basic search tools improved performance by an average of 11 percent while using 24 percent fewer input tokens (see [Improved web search with dynamic filtering](https://claude.com/blog/improved-web-search-with-dynamic-filtering)).
3636
3737Consider checking budget compliance across 20 employees: the traditional approach requires 20 separate model round-trips, pulling thousands of expense line items into the context along the way. With programmatic tool calling, a single script runs all 20 lookups, filters the results, and returns only the employees who exceeded their limits, shrinking what Claude needs to reason over from hundreds of kilobytes down to a few lines.
3838
from line 44
4444
4545## Quick start
4646
47Here's an example where Claude programmatically queries a database multiple times and aggregates results. Adding `allowed_callers: ["code_execution_20260120"]` to a tool definition is what makes that tool callable from within code execution (see [The `allowed_callers` field](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling#the-allowed-callers-field)):
47Here’s an example where Claude programmatically queries a database multiple times and aggregates results. Adding `allowed_callers: ["code_execution_20260120"]` to a tool definition is what makes that tool callable from within code execution (see [The `allowed_callers` field](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling#the-allowed-callers-field)):
4848
4949<CodeGroup>
5050 ```bash cURL
from line 371
3713711. Claude writes Python code that calls the tool as a function. The code can include multiple tool calls, plus preprocessing and post-processing logic.
3723722. Claude runs this code in a sandboxed container through code execution.
3733733. When a tool function is called, code execution pauses and the API returns a `tool_use` block.
3744. You provide the tool result, and code execution continues (intermediate results are not loaded into Claude's context window).
3744. You provide the tool result, and code execution continues (intermediate results are not loaded into Claude’s context window).
3753755. Once all code execution completes, Claude receives the final output and continues working on the task.
376376
377377This approach is particularly useful for:
378378
379* **Large data processing:** Filter or aggregate tool results before they reach Claude's context.
379* **Large data processing:** Filter or aggregate tool results before they reach Claude’s context.
380380* **Multistep workflows:** Save tokens and latency by calling tools serially or in a loop without sampling Claude between tool calls.
381381* **Conditional logic:** Make decisions based on intermediate tool results.
382382
383383<Note>
384 Tools that allow a code execution caller are exposed to Claude's code as async Python functions, so Claude can run them in parallel with `asyncio.gather`. Each function takes a single dict of arguments and returns a string: the text of the `tool_result` you send back. Claude's code awaits these functions with top-level `await` and parses results that it needs as structured data, for example `rows = json.loads(await query_database({"sql": "<sql>"}))`.
384 Tools that allow a code execution caller are exposed to Claude’s code as async Python functions, so Claude can run them in parallel with `asyncio.gather`. Each function takes a single dict of arguments and returns a string: the text of the `tool_result` you send back. Claude’s code awaits these functions with top-level `await` and parses results that it needs as structured data, for example `rows = json.loads(await query_database({"sql": "<sql>"}))`.
385385</Note>
386386
387387## Core concepts
from line 460
460460* **Expiration:** `expires_at` tells you how long the container has left. Idle containers are currently reclaimed after about 5 minutes, and no container can be reused more than 30 days after it was created.
461461
462462<Warning>
463 While Claude's code is waiting for a programmatic tool result, the pending call times out after about 4 minutes and raises a `TimeoutError` inside the code. Return each tool result well before the `expires_at` timestamp on the paused response. See [Container expiration during tool call](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling#container-expiration-during-tool-call).
463 While Claude’s code is waiting for a programmatic tool result, the pending call times out after about 4 minutes and raises a `TimeoutError` inside the code. Return each tool result well before the `expires_at` timestamp on the paused response. See [Container expiration during tool call](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling#container-expiration-during-tool-call).
464464</Warning>
465465
466466## Example workflow
467467
468Here's how a complete programmatic tool calling flow works:
468Here’s how a complete programmatic tool calling flow works:
469469
470470### Step 1: Initial request
471471
from line 472
472472Send a request with code execution and a tool that allows programmatic calling. To enable programmatic calling, add the `allowed_callers` field to your tool definition.
473473
474474<Note>
475 Provide detailed descriptions of your tool's output format in the tool description. If you specify that the tool returns JSON, Claude attempts to deserialize and process the result in code. The more detail you provide about the output schema, the better Claude can handle the response programmatically.
475 Provide detailed descriptions of your tool’s output format in the tool description. If you specify that the tool returns JSON, Claude attempts to deserialize and process the result in code. The more detail you provide about the output schema, the better Claude can handle the response programmatically.
476476</Note>
477477
478478The request shape is identical to the [Quick start](https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling#quick-start) example: include `code_execution` in your tools list, add `allowed_callers: ["code_execution_20260120"]` to any tool you want Claude to invoke from code, and send your user message. The remaining steps in this workflow use the user message `"Query customer purchase history from the last quarter and identify our top 5 customers by revenue"`.
from line 1143
11431143
11441144### Step 4: Next tool call or completion
11451145
1146The code picks up where it paused and processes your result. Each continuation response either pauses again with more programmatic `tool_use` blocks, or completes the code execution and lets Claude continue the turn (Step 5). Check `stop_reason` and each `tool_use` block's `caller` to tell the two apart. A response that pauses for you has `stop_reason: "tool_use"` and a `tool_use` block whose `caller` names a code execution version. In that case, repeat Step 3 with a `tool_result` for every pending programmatic call in one user message.
1146The code picks up where it paused and processes your result. Each continuation response either pauses again with more programmatic `tool_use` blocks, or completes the code execution and lets Claude continue the turn (Step 5). Check `stop_reason` and each `tool_use` block’s `caller` to tell the two apart. A response that pauses for you has `stop_reason: "tool_use"` and a `tool_use` block whose `caller` names a code execution version. In that case, repeat Step 3 with a `tool_result` for every pending programmatic call in one user message.
11471147
11481148### Step 5: Final response
11491149
from line 1293
12931293| Error | Where it appears | Description | Solution |
12941294| ------------------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
12951295| `invalid_tool_input` | `error_code` on the `code_execution_tool_result` error block in the response | Invalid parameters were passed to the code execution tool | See the [code execution tool errors](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#errors) |
1296| `invalid_request_error` (on `tool_choice`) | HTTP 400 error response | `tool_choice` names a tool whose `allowed_callers` does not include `"direct"` | Either add `"direct"` to that tool's `allowed_callers`, or remove the tool from `tool_choice` and let Claude call it from code |
1296| `invalid_request_error` (on `tool_choice`) | HTTP 400 error response | `tool_choice` names a tool whose `allowed_callers` does not include `"direct"` | Either add `"direct"` to that tool’s `allowed_callers`, or remove the tool from `tool_choice` and let Claude call it from code |
12971297
12981298### Container expiration during tool call
12991299
1300If your tool result doesn't arrive within about 4 minutes, the pending call raises a `TimeoutError` inside Claude's running code. Claude receives the error in `stderr` and typically retries the call:
1300If your tool result doesn’t arrive within about 4 minutes, the pending call raises a `TimeoutError` inside Claude’s running code. Claude receives the error in `stderr` and typically retries the call:
13011301
13021302```json
13031303{
from line 1331
13311331}
13321332```
13331333
1334Claude's code receives this error and can handle it appropriately.
1334Claude’s code receives this error and can handle it appropriately.
13351335
13361336## Constraints and limitations
13371337
from line 1413
14131413
14141414Programmatic tool calling reduces token consumption in three ways:
14151415
1416* **Tool results from programmatic calls are not added to Claude's context** - only the final code output is
1417* **Intermediate processing occurs in code** - filtering, aggregation, and other transformations don't consume model tokens
1416* **Tool results from programmatic calls are not added to Claude’s context** - only the final code output is
1417* **Intermediate processing occurs in code** - filtering, aggregation, and other transformations don’t consume model tokens
14181418* **Multiple tool calls in one code execution** - reduces overhead compared to separate model turns
14191419
14201420For example, calling 10 tools directly uses \~10x the tokens of calling them programmatically and returning a summary.
14211421
1422In Anthropic's internal evaluations on a production Claude model:
1422In Anthropic’s internal evaluations on a production Claude model:
14231423
14241424* On a 75-tool project-management agent benchmark, enabling programmatic tool calling reduced billed input tokens by roughly 38 percent with no change in task accuracy.
14251425* On [τ²-bench](https://arxiv.org/abs/2506.07982) (airline, retail, and telecom domains), where each turn makes one or two sequential tool calls, programmatic tool calling left scores unchanged and cost roughly 8 percent more. Sequential single-call workflows do not benefit.
from line 1432
14321432Programmatic tool calling uses the same pricing as code execution. See the [code execution pricing](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#usage-and-pricing) for details.
14331433
14341434<Note>
1435 Token counting for programmatic tool calls: Tool results from programmatic calls do not count toward your input/output token usage. Only the final code execution result and Claude's response count.
1435 Token counting for programmatic tool calls: Tool results from programmatic calls do not count toward your input/output token usage. Only the final code execution result and Claude’s response count.
14361436</Note>
14371437
14381438## Best practices
from line 1450
14501450**Strong fit:**
14511451
14521452* Fan-out or parallel operations across many items (for example, checking 50 endpoints or looking up 20 records)
1453* Large tool results that can be filtered, aggregated, or summarized before reaching Claude's context
1453* Large tool results that can be filtered, aggregated, or summarized before reaching Claude’s context
14541454* Agentic search and retrieval, where iterative querying and result filtering dominate the workflow
14551455
14561456**Weak fit:**
from line 1472
14721472
14731473**`invalid_request_error` when setting `tool_choice`**
14741474
1475* `tool_choice` cannot name a tool whose `allowed_callers` omits `"direct"`. Either add `"direct"` to that tool's `allowed_callers`, or remove the tool from `tool_choice` and let Claude call it from code.
1475* `tool_choice` cannot name a tool whose `allowed_callers` omits `"direct"`. Either add `"direct"` to that tool’s `allowed_callers`, or remove the tool from `tool_choice` and let Claude call it from code.
14761476
14771477**Container expiration**
14781478
1479* Respond to each programmatic tool call well before the paused response's `expires_at` timestamp. Claude's code stops waiting for a result after about 4 minutes, and idle containers are currently reclaimed after about 5 minutes.
1479* Respond to each programmatic tool call well before the paused response’s `expires_at` timestamp. Claude’s code stops waiting for a result after about 4 minutes, and idle containers are currently reclaimed after about 5 minutes.
14801480* Consider implementing faster tool execution.
14811481
14821482**Tool result not parsed correctly**
from line 1496
14961496Claude is trained on large amounts of code, so presenting tools as callable Python functions lets it use that strength:
14971497
14981498* **Tool composition:** Chained calls, loops, and conditionals are ordinary Python control flow instead of a series of model round trips.
1499* **Result processing:** Claude's code filters and aggregates large tool outputs, or writes them to files, and only the final output enters the context window.
1499* **Result processing:** Claude’s code filters and aggregates large tool outputs, or writes them to files, and only the final output enters the context window.
15001500* **Latency:** The model is not re-sampled between the tool calls inside one code execution.
15011501
15021502## Alternative implementations
15031503
1504Programmatic tool calling is a generalizable pattern that can also be implemented on your own infrastructure. Here's how the approaches compare:
1504Programmatic tool calling is a generalizable pattern that can also be implemented on your own infrastructure. Here’s how the approaches compare:
15051505
15061506### Client-side direct execution
15071507
from line 1517
15171517* Runs untrusted code outside of a sandbox
15181518* Tool calls can be vectors for code injection
15191519
1520**Use when:** Your application can safely run arbitrary code, you want the smallest implementation, and Anthropic's managed offering doesn't fit your needs.
1520**Use when:** Your application can safely run arbitrary code, you want the smallest implementation, and Anthropic’s managed offering doesn’t fit your needs.
15211521
15221522### Self-managed sandboxed execution
15231523
1524Same approach from Claude's perspective, but code runs in a sandboxed container with security restrictions (for example, no network egress). If your tools require external resources, you'll need a protocol for running tool calls outside the sandbox.
1524Same approach from Claude’s perspective, but code runs in a sandboxed container with security restrictions (for example, no network egress). If your tools require external resources, you’ll need a protocol for running tool calls outside the sandbox.
15251525
15261526**Advantages:**
15271527
from line 1533
15331533* Complex to build and maintain
15341534* Requires managing both infrastructure and inter-process communication
15351535
1536**Use when:** Security is critical and Anthropic's managed solution doesn't fit your requirements.
1536**Use when:** Security is critical and Anthropic’s managed solution doesn’t fit your requirements.
15371537
15381538### Anthropic-managed execution
15391539
1540Anthropic's programmatic tool calling is a managed version of sandboxed execution with an opinionated Python environment tuned for Claude. Anthropic handles container management, code execution, and secure tool call communication.
1540Anthropic’s programmatic tool calling is a managed version of sandboxed execution with an opinionated Python environment tuned for Claude. Anthropic handles container management, code execution, and secure tool call communication.
15411541
15421542**Advantages:**
15431543
from line 1545
15451545* Enabled with a tool definition, with no infrastructure to run
15461546* Environment and instructions optimized for Claude
15471547
1548Consider using Anthropic's managed solution if you're using the Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), or [Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry). On Microsoft Foundry, programmatic tool calling 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).
1548Consider using Anthropic’s managed solution if you’re using the Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), or [Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry). On Microsoft Foundry, programmatic tool calling 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).
15491549
15501550## Data retention
15511551
No line in this hunk matches that.