Process results programmatically changedagents-and-tools/tool-use/programmatic-tool-calling
Nearest release: v2.1.319, published an hour after 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+20added
Lines−18removed
From line
457
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits23to this page, all time
The whole hunk
from line 457, old and new numbered
/
from line 457
457457* **Container creation:** A new container is created for each request unless you reuse an existing one.
458458* **Container ID:** Returned in responses in the `container` field, along with an `expires_at` timestamp.
459459* **Reuse:** Pass the container ID back on the next request to keep state. While a programmatic tool call is waiting for your result, the container ID is required on that request, not optional: the API rejects the request without it.
460* **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.
460* **Expiration:** 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 is a shorter rolling value and doesn’t report the 30-day limit.
461461
462462<Warning>
463463 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).
from line 475
475475 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
478The 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"`.
478The 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 call 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"`.
479479
480480### Step 2: API response with tool call
481481
from line 544
544544 "content": [
545545 {
546546 "type": "text",
547 "text": "I'\''ll query the purchase history and analyze the results."
547 "text": "I will query the purchase history and analyze the results."
548548 },
549549 {
550550 "type": "server_tool_use",
from line 655
655655 ```
656656
657657 ```python Python
658 client = anthropic.Anthropic()
659
658660 response = client.messages.create(
659661 model="claude-opus-5-5",
660662 max_tokens=4096,
from line 724
722724 ```
723725
724726 ```typescript TypeScript
727 const client = new Anthropic();
728
725729 const response = await client.messages.create({
726730 model: "claude-opus-5-5",
727731 max_tokens: 4096,
from line 1040
10361040 ],
10371041 ],
10381042 ],
1039 model: 'claude-opus-5-5',
1043 model: Model::CLAUDE_OPUS_5_5,
10401044 container: 'container_xyz789',
10411045 // Same tools array as the original request
10421046 tools: [
from line 1070
10661070 ```
10671071
10681072 ```ruby Ruby
1069 require "anthropic"
1070
10711073 client = Anthropic::Client.new
10721074
10731075 message = client.messages.create(
1074 model: "claude-opus-5-5",
1076 model: Anthropic::Model::CLAUDE_OPUS_5_5,
10751077 max_tokens: 4096,
10761078 container: "container_xyz789",
10771079 messages: [
from line 1196
11941196
11951197This pattern:
11961198
1197* Reduces model round-trips from N (one for each region) to 1
1199* Reduces model round trips from N (one for each region) to 1
11981200* Processes large result sets programmatically before returning to Claude
11991201* Saves tokens by only returning aggregated conclusions instead of raw data
12001202
from line 1319
13171319
13181320To prevent timeouts:
13191321
1320* Monitor the `expires_at` field in responses.
1322* Monitor the `expires_at` field on paused responses.
13211323* Implement timeouts for your tool execution.
13221324* Consider breaking long operations into smaller chunks.
13231325
from line 1408
14061408
14071409### Validate tool results before use
14081410
1409When implementing user-defined tools that will be called programmatically:
1411When implementing user-defined tools that Claude calls programmatically:
14101412
14111413* **Tool results are returned as strings:** They can contain any content, including code snippets or executable commands that might be processed by the execution environment.
14121414* **Validate external tool results:** If your tool returns data from external sources or accepts user input, be aware of code injection risks if the output is interpreted or run as code.
from line 1417
14151417
14161418Programmatic tool calling reduces token consumption in three ways:
14171419
1418* **Tool results from programmatic calls are not added to Claude’s context** - only the final code output is
1419* **Intermediate processing occurs in code** - filtering, aggregation, and other transformations don’t consume model tokens
1420* **Multiple tool calls in one code execution** - reduces overhead compared to separate model turns
1420* **Tool results from programmatic calls are not added to Claude’s context:** Only the final code output is.
1421* **Intermediate processing occurs in code:** Filtering, aggregation, and other transformations don’t consume model tokens.
1422* **Multiple tool calls in one code execution:** This reduces overhead compared to separate model turns.
14211423
1422For example, calling 10 tools directly uses \~10x the tokens of calling them programmatically and returning a summary.
1424For example, calling 10 tools directly uses roughly 10 times the tokens of calling them programmatically and returning a summary.
14231425
14241426In Anthropic’s internal evaluations on a production Claude model:
14251427
from line 1449
14471449
14481450### When to use programmatic calling
14491451
1450Programmatic tool calling trades a small fixed overhead (container startup, script generation) for large savings on tool-result tokens and model round-trips. Whether that trade is worthwhile depends on workload shape.
1452Programmatic tool calling trades a small fixed overhead (container startup, script generation) for large savings on tool-result tokens and model round trips. Whether that trade is worthwhile depends on workload shape.
14511453
14521454**Strong fit:**
14531455
from line 1459
14571459
14581460**Weak fit:**
14591461
1460* Strictly sequential workflows where each call depends on Claude reasoning over the previous result, because the script cannot skip the model round-trip in that case
1462* Strictly sequential workflows where each call depends on Claude reasoning over the previous result, because the script cannot skip the model round trip in that case
14611463* A small number of tool calls with small responses, especially on the first turn of a conversation, where container and script overhead can exceed the savings
14621464* Tools that require immediate user feedback between calls
14631465
from line 1480
14781480
14791481**Container expiration**
14801482
1481* 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.
1483* 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.
14821484* Consider implementing faster tool execution.
14831485
14841486**Tool result not parsed correctly**
No line in this hunk matches that.