---
title: "Authorize a tool invocation"
method: POST
path: "/authorize/tool"
---

# Authorize a tool invocation

`POST /authorize/tool`

## Request

- Base URL: `https://getsanction.com/api/v1`
- URL: `https://getsanction.com/api/v1/authorize/tool`
- Auth: API key in header `x-api-key`

Check whether an agent may invoke a tool or external action (an MCP tool, a shell command, a deploy). Governed by the wallet's tool block/allow/escalate lists; an empty allow-list allows all (governance is opt-in). Escalated invocations persist to the owner's approval inbox; approval mints a one-use grant — retry the same tool with grant_id to consume it, or poll /authorize/{id}. Supports Idempotency-Key: replaying the key returns the escalation's current state, including the terminal decision once resolved.

## Request body

- ToolAuthorizeRequest
  - `tool` string, required: Exact name of the tool/action about to be invoked (e.g. github.create_deployment, shell.exec)
  - `server` string: MCP server or integration the tool belongs to (e.g. github, filesystem) — matched on grant redemption
  - `arguments` object: Arguments bound to a one-use approval. Encrypted at rest; reviewed by an admin in the dashboard. Not policy-evaluated. Maximum request size 64 KiB and nesting depth 32.
  - `input` object: Legacy SDK alias for arguments. Send only one of input or arguments.
  - `require_approval` boolean: Request a one-off human approval even when policy allows. Enforced in observe mode; hard denials win. Timeout always denies.
  - `approval_reason` string: Why the agent requests review. Shown to the owner; omit secrets.
  - `grant_id` string: One-use grant minted when a human approves the escalation. Retry the same tool, server, and arguments with this field to consume it. Legacy unbound tool grants require fresh approval.

## Response `200`

Authorization decision (200 for allowed/escalated; 403 for denied; 409 for an already-consumed grant)

- ToolAuthorizeResponse
  - `authorized` boolean
  - `approval_status` string: Historical status on an idempotent replay; never permission to execute. Redeem the grant for an attempt.
  - `status` 'allowed' | 'denied' | 'escalated'
  - `request_id` string: Decision request ID. A consumed tool-grant replay gets a separate denied attempt ID; poll /authorize/{id} for its terminal decision.
  - `original_request_id` string: Original approval request linked to a consumed tool-grant replay, after wallet and agent ownership checks.
  - `rejected_grant_id` string: Consumed grant referenced for audit only. Never usable authority.
  - `reason` string
  - `code` 'TOOL_BLOCKED' | 'TOOL_NOT_ALLOWED' | 'TOOL_ESCALATION_REQUIRED' | 'NO_POLICY' | 'GRANT_NOT_FOUND' | 'GRANT_ALREADY_USED' | 'GRANT_EXPIRED' | 'GRANT_MISMATCH' | 'GRANT_UNSUPPORTED': Machine-readable decision code (absent when allowed)
  - `remediation` string: Hint for how the agent should proceed
  - `agent` string
  - `tool` string
  - `server` string
  - `grant_id` string: Echoed on successful grant redemption
  - `grant_status` 'consumed'
  - `grant_consumed_at` string, date-time

## Other responses

- `401`: Invalid API key
- `403`: Denied by policy or grant mismatch

---

[API](https://skmtc.dev/getsanction/apis/sanction-agent-governance-api.md) · [All operations](https://skmtc.dev/getsanction/apis/sanction-agent-governance-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getsanction/apis/sanction-agent-governance-api/revisions/c645a9e4b72d?raw)
