> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Tool approvals

Tool approval pauses an Agent run before a tool runs, so a person can approve or deny the call first. Use it for tools that send messages, change records, spend money, or take any other action that you want a person to review. This page covers how to turn approval on, how to approve or deny a paused run in the dashboard or through the API, and how remembered approvals work.

## How tool approval works

When the model calls a tool that requires approval, Runtype stops before the tool runs and waits for a decision. The approval request shows the tool name and its parameters. It can also show a short justification from the model in **Agent's stated reason**. Treat that text as context, not as a guarantee, and review the parameters before you decide.

The decision controls what happens next:

* **Approve**: the tool runs with the parameters shown, and the run continues.
* **Deny**: the tool doesn't run. The model receives a tool result that says the call was denied, and the run continues without it.

Parameters that Runtype fills in for you, such as protected identity values, appear as `[REDACTED]` in the approval request. You don't need to supply them to approve or deny the call.

## Require approval for tools

To require approval on an Agent, follow these steps:

1. Open the Agent in the dashboard.
2. In the **Safety** section, turn on **Tool approval**.
3. Choose a scope. **All tools** gates every tool call. **Only selected** gates the tools and Capabilities that you pick.
4. Optional: in **Only selected**, enter a custom pattern and click **Add**. The pattern `mcp:*` gates every MCP tool, and `builtin:*` gates every built-in tool.
5. Save the Agent.

Approval rules match tool names, so renaming a tool clears its rule. If you save **Only selected** with no tools selected, Runtype saves the Agent with approval off.

In the Agent configuration, the same setting is `tools.approval.require`. Set it to `true` for all tools, or to an array of tool names and patterns:

**`Agent configuration`**

```json title="Agent configuration"
{
  "tools": {
    "approval": {
      "require": ["send_email", "mcp:*"]
    }
  }
}
```

To change the approval setting for a single run, pass `agent.tools.approval` in a `POST /v1/dispatch` request. For details, see [Dispatch-time approval overrides](/developer-guides/guides/runtime-tools#dispatch-time-approval-overrides).

## Approve or deny in the dashboard

When you run the Agent in the dashboard, a gated call shows an approval prompt with the tool name. Approve the call to run the tool, or click **Deny** to skip it. The run continues in the same chat.

On Slack, Telegram, SMS, and iMessage, the approval request appears in the conversation instead. For how each channel shows the request and reads the reply, see [Approvals on messaging surfaces](/user-guide/products-surfaces/approvals-on-messaging-surfaces).

## Approve or deny through the API

When you run an Agent through the API, a gated call pauses the run and returns the details that you need to resume it. You then send the decision to the approve endpoint.

### Find the paused approval

How the pause arrives depends on how you called the Agent:

* **Streaming** (the default): the stream sends an `approval_start` event. The event carries `executionId`, `approvalId`, `toolName`, and `parameters`.
* **Non-streaming** (`streamResponse: false`): the response has `status: "paused"` and a `pausedReason` object. For an approval, `pausedReason.awaitReason` is `approval_required`, and `pausedReason` carries `executionId`, `approvalId`, `toolName`, and `parameters`.

A paused non-streaming response returns `success: true` because the run can continue. Check `status` for `"paused"`, not `success`.

### Send the decision

The following request approves a paused call on an Agent that you ran with `POST /v1/agents/{id}/execute`:

**`cURL`**

```bash title="cURL"
curl -X POST https://api.runtype.com/v1/agents/YOUR_AGENT_ID/approve \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "executionId": "YOUR_EXECUTION_ID",
    "approvalId": "YOUR_APPROVAL_ID",
    "decision": "approved",
    "streamResponse": false
  }'
```

Replace the following:

* `YOUR_AGENT_ID`: the ID of the Agent
* `YOUR_API_KEY`: your Runtype API key
* `YOUR_EXECUTION_ID`: the `executionId` from the pause
* `YOUR_APPROVAL_ID`: the `approvalId` from the pause

For a run that you started with `POST /v1/dispatch`, send the same body to `POST /v1/dispatch/approve` instead. That endpoint has no Agent ID in the path.

The request body accepts the following fields:

| Field            | Required | Description                                                                                                       |
| ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| `executionId`    | Yes      | The paused execution.                                                                                             |
| `approvalId`     | Yes      | The approval to resolve.                                                                                          |
| `decision`       | Yes      | `approved` or `denied`.                                                                                           |
| `reason`         | No       | Text that explains the decision.                                                                                  |
| `remember`       | No       | Set to `true` with `approved` to create a remembered approval. See [Remember an approval](#remember-an-approval). |
| `streamResponse` | No       | Defaults to `true`, which streams the rest of the run. Set to `false` to receive the result as JSON.              |

The response contains the rest of the run. If the model calls another gated tool, the run pauses again with a new `approvalId`. Resolve each pause the same way. If the execution isn't waiting for that approval, for example because someone already resolved it, the API returns status code `409`.

## Remember an approval

A remembered approval, also called a grant, stores an **Always allow** decision. Later runs of the same Agent skip the approval prompt for that tool, whatever parameters the model sends. Remembered approvals are off by default.

To let people remember approvals, follow these steps:

1. In the Agent's **Safety** section, turn on **Allow 'always allow'**. The setting appears after you turn on **Tool approval**.
2. Save the Agent.

After you save, the dashboard chat shows **Always allow**, **Allow once**, and **Deny** on each approval prompt. Click **Always allow** to approve the call and create a grant. Through the API, send `"remember": true` with `"decision": "approved"`. In the Agent configuration, the setting is `tools.approval.choices.alwaysAllow`.

A grant applies to one Agent and one tool. Its scope depends on the run that created it:

* If the run identified an end user, the grant applies to that end user only. For how Runtype identifies end users, see [End-user identity and credentials](/developer-guides/guides/end-user-identity).
* If the run had no end user, the grant applies to every end user of the Agent and appears as **All users**.

Grants have the following limits:

* Runtype creates grants only for saved Agents, not for Agents defined inline in a dispatch request.
* Grants take effect only while **Allow 'always allow'** is on. Turn it off to stop applying every grant on the Agent without deleting them.
* Runtype doesn't remember approvals for loading an Agent Skill. Each skill load prompts for approval.
* A grant skips only the prompt. Tool access, ownership checks, and secret access don't change.

Slack and Telegram approval prompts offer one-time choices only, so they don't create grants.

## Review and revoke remembered approvals

The Agent's **Safety** section lists its grants in the **Remembered approvals** card. Each entry shows the tool, its scope, and the date of the grant. To revoke a grant, click the delete control on its row. The next call to that tool prompts for approval again.

To list grants through the API, send a `GET` request to `/v1/tool-approval-grants`. The optional `agentId` query parameter limits the list to one Agent:

**`cURL`**

```bash title="cURL"
curl "https://api.runtype.com/v1/tool-approval-grants?agentId=YOUR_AGENT_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Replace `YOUR_AGENT_ID` with the Agent ID and `YOUR_API_KEY` with your Runtype API key.

The response has a `data` array. Each grant has an `id`, `agentId`, `toolType`, `toolName`, `decision`, and `endUserRef`. An `endUserRef` that is empty or `null` marks a grant that applies to all users.

To revoke a grant, send a `DELETE` request with the grant `id`:

**`cURL`**

```bash title="cURL"
curl -X DELETE https://api.runtype.com/v1/tool-approval-grants/YOUR_GRANT_ID \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Replace `YOUR_GRANT_ID` with the `id` from the list and `YOUR_API_KEY` with your Runtype API key. The API returns `{ "revoked": true }`, or status code `404` if no active grant has that ID.

The TypeScript SDK exposes the same operations as `client.toolApprovalGrants.list()` and `client.toolApprovalGrants.revoke()`.

## Runs that nobody can approve

Some runs have no person available to answer an approval request. Schedules, Batches, Evals, webhooks, and API requests with no live caller fall in this group. Runtype refuses these runs before the Agent starts and returns an error that names the tool approval policy, so no gated tool runs. To run the Agent unattended, turn off **Tool approval** or remove the tool from the approval list. For details, see the Safety section of [Creating and configuring agents](/user-guide/agents/creating-and-configuring-agents#safety).

## Next steps

* [Creating and configuring agents](/user-guide/agents/creating-and-configuring-agents): set the other options in the **Safety** section.
* [Approvals on messaging surfaces](/user-guide/products-surfaces/approvals-on-messaging-surfaces): approve tool calls from Slack, Telegram, SMS, and iMessage.
* [Runtime tools developer guide](/developer-guides/guides/runtime-tools#tool-approval-grants): see the full pause, resume, and grant API reference.
* [Agent tools](/user-guide/agents/agent-tools): attach tools to an Agent.