Programmatic Tool Calling OpenAI introduced Programmatic Tool Calling, a feature that lets a model write and run JavaScript in a fresh, isolated V8 runtime to coordinate its tools in parallel, with loops and conditions, while keeping intermediate results in the hosted runtime. In the Responses API, applications add the programmatic_tool_calling hosted tool and set allowed_callers on each eligible tool, while the Agents API enables the feature by default and manages the agent loop. OpenAI says the runtime supports JavaScript with top-level await but provides no Node.js, package installation, direct network access, general-purpose filesystem, subprocess execution, console, or persistent state between executions, and that Responses API requests support Zero Data Retention workflows without a persistent code-execution container when ZDR is enabled for the organization or project. Programmatic Tool Calling lets a model write and run JavaScript that coordinates its tools. A program can call tools in parallel, use loops and conditions, and keep intermediate results in the hosted runtime. This is useful when a task needs a sequence of related tool calls or needs to process large tool outputs before returning a result. In the Responses API, your application decides whether Programmatic Tool Calling is available and which eligible tools the model can call directly, from a program, or either way. It continues to run any client-owned tool calls. The Agents API agents-api enables Programmatic Tool Calling by default and manages the agent loop for you. Check the model page https://developers.openai.com/api/docs/models before enabling Programmatic Tool Calling. Understand the runtime environment OpenAI runs each generated program in a fresh, isolated V8 runtime. The runtime supports JavaScript with top-level await , but it does not provide Node.js, package installation, direct network access, a general-purpose filesystem, subprocess execution, a console, or persistent JavaScript state between program executions. Programs can interact with external systems only through tools enabled in the request and can emit output with text ... or image ... . For Responses API requests, Programmatic Tool Calling supports Zero Data Retention ZDR workflows without requiring a persistent code-execution container. ZDR must be enabled for the organization or project; setting store: false enables stateless continuation but does not enable ZDR by itself. Eligibility and retention depend on the complete request, including its model, tools, and third-party services; see data controls https://developers.openai.com/api/docs/guides/your-data . Choose when to use Programmatic Tool Calling Use Programmatic Tool Calling when a stage has predictable control flow and code can return a smaller structured result. Use direct tool calling when one call is sufficient, each result requires fresh model judgment, or the work requires approval or preservation of citations or native artifacts. | Task shape | Recommended mode | |---|---| | A single lookup or action | Use direct tool calling. | | Several results that code can filter, join, rank, remove duplicates from, aggregate, or validate | Use Programmatic Tool Calling when the program can return a smaller structured result. | | Dependent calls with predictable data flow | Use Programmatic Tool Calling when code can derive later arguments and the limits and failure behavior are explicit. | | Adaptive search or semantic evaluation | Use direct tool calling when each result should influence the model’s next decision. | | Writes or approval-sensitive actions | Use direct tool calling by default to preserve a clear authorization boundary. | | Final citation or native artifact validation | Use direct tool calling unless the program preserves the native output and validates every required item. | Configure Programmatic Tool Calling For the Responses API, add the programmatic tool calling hosted tool to the request. Then set allowed callers on each eligible tool that the program can invoke. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 { "type": "function", "name": "get inventory", "description": "Return an object with sku string and available units number .", "parameters": { "type": "object", "properties": { "sku": { "type": "string" } }, "required": "sku" , "additionalProperties": false }, "output schema": { "type": "object", "properties": { "sku": { "type": "string" }, "available units": { "type": "number" } }, "required": "sku", "available units" , "additionalProperties": false }, "allowed callers": "programmatic" }, { "type": "programmatic tool calling" } allowed callers controls how the model can invoke a tool: | Value | Behavior | |---|---| | Omitted or "direct" | The model can call the tool directly. | | "programmatic" | Only code in a program item can call the tool. | | "direct", "programmatic" | The model can call the tool directly or from a program. | parameters describes the function arguments. When a function returns predictable structured data, output schema describes the JSON object encoded in its function call output.output string. Define both so generated JavaScript can use the returned fields reliably. Supported tools The following tool types support allowed callers: "programmatic" : - function and custom - mcp - apply patch - Local and hosted shell - code interpreter For MCP tools, the tool’s require approval policy can pause the program until you approve the call. For OpenAI-hosted tools, review the tool’s data-retention and security guidance before enabling it in a program. Combine with tool search Tool search https://developers.openai.com/api/docs/guides/tools-tool-search runs as a top-level Responses API tool, not from inside generated JavaScript. Function, custom, and MCP tools with defer loading: true are not initially available to a program. After the model loads a matching tool, a later program can invoke it through tools. when its allowed callers includes "programmatic" . An already-running program cannot invoke tool search, so the model must load deferred tools before starting a program that needs them. Guide routing when both modes are available When your application lets the model call a function directly or from a program, assign each route to a specific workflow stage. Generic instructions such as “use Programmatic Tool Calling efficiently” don’t identify the intended boundary. For example: