User guideDeveloper guideGoverning tool calls
Developer guide

Governing tool calls

The four decisions, approval polling, run correlation and fail-modes.

Governing tool calls

When your agent asks the gateway about a tool call, it gets back one of four decisions. This page explains each one, how to group calls into a run and how failures are handled.

The four decisions

DecisionWhat it means and what to do
allowThe call passed all checks. Run the tool.
denyA guardrail blocked the call. Do not run the tool. The response includes a reason.
approval_requiredA human must approve first. The response includes an approval id and a poll endpoint. Wait for approval, then retry.
rate_limitedThe agent key went over its per-minute limit. Back off and retry later.

Handling approval

When the decision is approval_required, the gateway has created a request for a human to approve or deny. Poll the status endpoint until you get a final answer.

json
{
  "decision": "approval_required",
  "approval_id": 42,
  "poll_endpoint": "/v1/mcp/approvals/42/status",
  "expires_at": "2026-04-20T15:30:00+00:00"
}
  1. Call GET /v1/mcp/approvals/{approval_id}/status with your agent key.
  2. When the status is approved, run the tool.
  3. When the status is denied, do not run it.
  4. When the status is expired, the window passed with no decision; treat it as a block.

On the MCP proxy path the same information comes back as a JSON-RPC error with code -32001, carrying the approval id, poll endpoint and expiry in error.data.

Grouping calls into a run

A run groups one turn of work: the model calls and the tool calls that belong together. They are tied by a shared run id.

  • Tool calls: The native hook reuses the agent session id it already sends, so tool calls are grouped automatically.
  • Model calls: Send the same id on your model requests using the header x-vw-agent-run-id. The aliases x-session-id and helicone-session-id are also accepted.
Use the same id on every call
A turn only groups correctly when the agent sends the same run id on every call, including sub-calls. A call with no id is still checked and logged; it just will not appear inside a run.

Failures and fail-modes

  • Gateway unreachable: With VW_FAIL_MODE=open (the default) the call runs anyway, so an outage never blocks your agent. Set it to closed to block instead.
  • Approval timed out: Controlled by VW_APPROVAL_FAIL_MODE (default closed, which blocks). Set it to open to allow on timeout.
  • Rate limited: Follows VW_FAIL_MODE. The call is an infra outcome, not a policy block.
PreviousConnect any agent
NextAPI reference
Governing tool calls - Developer guide - VerifyWise User Guide