Skip to main content
Some tool calls should not happen on a model’s say-so. Set require_approval on a tool and every call to it pauses the run, shows the user what the agent is about to do, and waits for a decision. Approve, and the call runs exactly as proposed. Decline, and the agent is told so and carries on.

When to require approval

Anything that writes, charges, sends, or is hard to undo: creating a booking, issuing a refund, sending an email, deleting a record. Not reads — an approval prompt on every lookup trains users to click through without looking, which defeats the one on the refund.

Turning it on

require_approval is a flag on the tool’s entry in an agent’s tool list, not on the tool itself. The same tool can require approval in one agent and not in another.
In the Studio it is the Require approval before executing this tool badge on the tool card, and the checkbox of the same name in the agent’s tool list. The flag saves immediately. Like every other part of an agent’s configuration, it lives on the draft: published versions are frozen, so changing it means publishing and activating a new version. See Versions, environments and deploying.
Approvals are honoured for API tools, MCP tools and connected-app actions held by the agent. Tools that arrive through a per-user MCP connection built at request time are not yet gated.

What the user sees

When the agent decides to call a gated tool, the platform pauses it before the call runs and asks the model for one thing first: a short sentence, in the user’s language, saying what the call will do with its decisive details — the recipient and subject of an email, what a deletion removes. That sentence is the headline of the approval card, next to Approve and Decline. The proposed arguments are shown beneath it, so the user is deciding on the real call, not a paraphrase. The agent is told to treat the pause as the consent step. It does not ask permission in chat first and then call the tool: it calls the tool, and the card collects the decision. You do not need to write any of this into your own prompt — the platform adds the guidance whenever an agent holds a gated tool.

Deciding

Approve resumes the suspended run against the exact agent version that paused, and the tool runs with the arguments the user saw. Decline skips the call; the model receives “Tool call was not approved by the user”, and is instructed to treat that as a decision rather than an error — acknowledge it and continue without repeating the call unless asked. In the conversation history a declined call is recorded as denied, with the reason the model gave, so a replay of the thread shows what was proposed and that it did not happen.

Durability

The paused run is persisted as a snapshot keyed by its run id, so it outlives the HTTP request that started it. A client that drops mid-pause can reconnect to the stream with GET /v1/chat/stream inside the disconnect grace window and replay the approval chunk. Beyond that window an unanswered run is abandoned; the thread is intact and the user can simply ask again.

From the API

A gated call arrives on the chat stream as a data-tool-call-approval chunk instead of a tool result. It carries everything needed to answer it:
The stream ends there — the pause finishes the turn, and no follow-up suggestions are generated for it. To answer, POST /v1/chat again with the same threadId, the chunk’s agentVersionId (which skips routing so the continuation reaches the agent that paused), and an approval object. On a continuation messages may be empty:
The same approval field works on POST /v1/agents/{id}/run and POST /v1/copilots/{id}/run. Those request/response endpoints report the pause in their collected output — the approval chunk is present and there is no finishReason — and are continued the same way. The SDK handles all of this for you; the shapes above matter when you drive the API yourself.

Design guidance

  • Argument names are user-facing. They appear on the card, so guest_email reads better than p_email_v2. If a parameter is an internal id the user cannot judge, make sure the reason sentence names the thing it refers to.
  • Gate the write, not the read that precedes it. Let the agent look up the order freely and pause only on the refund.
  • Don’t double-ask. If your prompt tells the agent to “always confirm before sending”, it will confirm in chat and then pause again on the card. The card is the confirmation.
  • Pinned configuration still applies. Values fixed on the agent’s copy of the tool are merged in when the approved call runs, so the user approves the arguments the model chose and your pins fill in the rest.