> 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.

# Approvals on messaging surfaces

When you turn on [**Tool approval**](/user-guide/agents/creating-and-configuring-agents), a person must approve a gated tool before the Agent runs it. This page covers how messaging channels collect that decision. Slack and Telegram show **Approve** and **Deny** buttons. SMS and iMessage read the decision from a text reply. Surfaces with a live caller, such as the API, MCP, A2A, the Chrome extension, and hosted pages, return the approval request to that caller.

> **Note**
>
> SMS and iMessage show as **Coming Soon** in the production dashboard. For details, see [Setting up an SMS surface](/user-guide/products-surfaces/setting-up-an-sms-surface) and [Setting up an iMessage surface](/user-guide/products-surfaces/setting-up-an-imessage-surface).

The following table shows how each Surface collects an approval:

| Surface                                                | Approval method                                                   | Requirement                                                                                                                             |
| ------------------------------------------------------ | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Dashboard **Run** interface                            | Explicit **Approve** and **Deny** controls                        | None                                                                                                                                    |
| Slack                                                  | **Approve** and **Deny** buttons                                  | **Agent loop** with **Max turns** set to 2 or higher                                                                                    |
| Telegram                                               | **Approve** and **Deny** buttons                                  | **Agent loop** with **Max turns** set to 2 or higher and a configured webhook secret                                                    |
| SMS                                                    | Your reply text                                                   | **Agent loop** with **Max turns** set to 2 or higher and a configured Twilio Auth Token                                                 |
| iMessage                                               | Your reply text                                                   | **Agent loop** with **Max turns** set to 2 or higher and a configured Sendblue signing secret                                           |
| Client Chat, chat widget                               | **Approve** and **Deny** in the widget, for `end-user` gates only | A Runtype Agent whose gate sets `tools.approval.approver` to `end-user`. Owner gates return HTTP `501` with `APPROVAL_MODE_UNSUPPORTED` |
| Email, WhatsApp, Discord, and other messaging channels | No approval path                                                  | The run is refused, and no gated tool runs                                                                                              |
| Schedules                                              | No approval path                                                  | The scheduled run fails with an error naming the tool approval policy                                                                   |
| Batches                                                | No approval path                                                  | Every record fails with an error naming the tool approval policy                                                                        |
| Evals                                                  | No approval path                                                  | The case fails with an error naming the tool approval policy                                                                            |
| Webhooks                                               | No approval path                                                  | The triggered run fails with an error naming the tool approval policy                                                                   |
| API and JSON surfaces (no live caller)                 | No approval path                                                  | The request is refused with an error naming the tool approval policy                                                                    |

## Requirements

An approval-gated Agent on Slack, Telegram, SMS, or iMessage needs the following setup:

* **Agent loop:** For a Runtype Agent, turn on **Agent loop** and set **Max turns** to 2 or higher. Single-pass Runtype Agents cannot run approval-gated tools on messaging Surfaces because they cannot resume after a decision. A Managed external Agent already supports multi-turn tool approval and needs no **Agent loop** or **Max turns** setting.
* **Inbound credential:** Telegram, SMS, and iMessage accept decisions only when the Surface has the inbound credential shown in the table. Runtype sets the Telegram webhook secret when you connect a bot to the Telegram Surface.

Reply-based approval has no separate setting. Attach approval-required tools to the Agent and bind it to the Surface.

Runtype checks these bindings while you author them. It reports `APPROVAL_UNANSWERABLE_ON_SURFACE` when a binding cannot answer an approval, and `APPROVAL_REPLY_CAPTURE_ON_SURFACE` as a recommendation for SMS and iMessage bindings. Both appear in product validation, when you add or update a surface item, and when you save the Agent. For details, see [Flow validation warnings](/user-guide/flows/flow-validation-warnings).

Unattended Surfaces have nobody to answer an approval prompt, so Runtype refuses the run before the Agent starts instead of leaving it pending. The error names the policy to change: remove `tools.approval.require` from the Agent, or move the work to a Surface that can collect a decision. No gated tool runs, and the execution is recorded as failed.

Messaging approvals are one-time decisions. Slack and Telegram prompts offer only **Approve** and **Deny**, and a reply approves or denies only the current call. These Surfaces never offer **Always allow**, even when the Agent lets users choose **Always allow**. To create a remembered approval, use the dashboard **Run** interface. For details, see [Creating and configuring Agents](/user-guide/agents/creating-and-configuring-agents).

## What the approval message looks like

The approval message depends on how the Surface collects the decision.

### Slack and Telegram

The prompt shows the following parts, followed by **Approve** and **Deny** buttons:

1. **Header:** `Tool approval required:` and the tool name.
2. **Description:** The tool's description.
3. **Stated reason:** `Agent's stated reason:` and the Agent's explanation, when it gives one.
4. **Parameters:** The call's parameters as formatted JSON. Long parameter blocks are shortened.

Check the **Parameters** block before you select a button. It identifies the call that you authorize. The stated reason comes from the Agent and is not a guarantee of what the tool does.

### SMS and iMessage

The message contains three parts:

1. **Question:** The Agent writes a question that describes the action.
2. **Action line:** Runtype adds the tool name and a summary of its parameters.
3. **Reply instruction:** Runtype adds `Reply YES to approve or NO to deny.`

The following sample shows all three parts in one message:

```text
Is it okay if I email the quarterly report to dana@example.com?
Approval needed to run send_email (to: dana@example.com, subject: Quarterly report).
Reply YES to approve or NO to deny.
```

Read the action line before you reply. The Agent writes the question. Runtype writes the action line, which identifies the call that you authorize. Long values are shortened to fit a text message.

On every Surface, Runtype replaces the values of [hidden parameters](/user-guide/tools/runtime-tools#hide-parameters-from-the-model) with `[REDACTED]`.

## How your reply is read

On SMS and iMessage, Runtype reads your reply in two stages:

1. **Exact keywords:** Runtype checks exact keywords first. The set includes `YES`, `NO`, and close variants such as `Y`, `OK`, `APPROVE`, `N`, and `DENY`. It also includes the emoji `👍`, `✅`, `👎`, and `❌` when you send them as a message.
2. **Other replies:** A small language model classifies replies that do not match a keyword. The classification counts toward the Product owner's model usage. The result is an approval, a denial, an unrelated reply, or an unclear reply. If classification fails, Runtype treats the reply as unclear.

Ask approvers to reply `YES` or `NO`. A keyword reply skips the model call.

On iMessage, reactions on the approval message work as follows:

* **Disliked:** Denies the request.
* **Liked or Loved:** Runtype asks you to confirm with `YES`. The reaction does not approve the request.
* **Other reactions:** Runtype asks you to reply `YES` or `NO`.

A reaction on a different message counts as an unrelated reply.

Runtype handles replies that do not produce a clear decision as follows:

* **Unclear replies:** Runtype keeps the approval pending and asks you to reply `YES` or `NO`, up to two times. After that, Runtype ignores further unclear replies until the request expires. A clear `YES` or `NO` still resolves it.
* **Unrelated replies:** Runtype sends one reminder. It counts toward the same limit of two.
* **Uncertain approvals:** Runtype asks you to confirm. It does not run the tool until you send a clear approval.
* **Denials:** Runtype resumes the Agent with a denial and passes your reply text as context. For example, `No, send it to finance instead` denies the current tool call and gives the Agent your requested change.

## Who can decide

Who can resolve an approval depends on the Surface:

* **SMS and iMessage:** Only the participant who triggered the run. A reply from a different conversation or phone number does not resolve the approval.
* **Telegram:** Only the person who started the conversation with the bot. Taps from other group members do not resolve the approval.
* **Slack:** Anyone in the channel who can see the prompt can select **Approve** or **Deny**.

After a decision on Slack or Telegram, the prompt shows who decided, for example `Approved by` followed by that person.

Put Agents with high-stakes approval-gated tools in private channels or direct messages.

## What happens after you decide

The first accepted decision is final. On Slack and Telegram, the buttons are replaced with the decision. On SMS and iMessage, Runtype sends `Approved. Continuing.` or `Denied. I will not run` followed by the tool name.

On SMS and iMessage, Runtype sends a correction when it cannot act on your reply. The following table lists each correction and what to do:

| Message starts with                                          | Meaning                                            | What to do                |
| ------------------------------------------------------------ | -------------------------------------------------- | ------------------------- |
| `Correction: your earlier approval was already accepted`     | A later reply does not change an accepted approval | Nothing                   |
| `Correction: your earlier denial was already accepted`       | A later reply does not change an accepted denial   | Nothing                   |
| `Correction: your decision could not be recorded`            | Nothing ran                                        | Reply `YES` or `NO` again |
| `Correction: I could not confirm your decision was recorded` | Runtype is not sure the decision was saved         | Reply `YES` or `NO` again |
| `Correction: I could not continue after your decision`       | The action did not run, and the request is closed  | Start a fresh run         |
| `Correction: this approval request had already timed out`    | The request expired before your reply counted      | Ask the Agent again       |

## If nobody decides

An approval request expires after 1 hour. When it expires, the run continues without the tool:

* Runtype denies the pending tool call with the reason "Approval request timed out; the action was not performed." The tool does not run.
* The Agent continues from that result and posts a follow-up in the conversation, such as "I couldn't send that email because nobody approved it in time."
* On Slack and Telegram, the approval message loses its **Approve** and **Deny** buttons and shows that the request timed out.
* A later reply or button selection has no effect. To try the action again, ask the Agent again.

If a person has taken over the conversation when the request expires, Runtype waits until the conversation is handed back to the Agent before it posts the follow-up.

While an approval is pending on SMS or iMessage, reply to the approval before you send other messages in the same conversation. Runtype reads each inbound message as a possible approval reply.

## Limits of reply-based approval

Reply-based approval has these limits:

* Free-form replies can be misread. Exact keywords avoid the model. Other replies go through a language model, and an unclear result never approves the tool.
* For high-stakes tools, use a Surface with explicit controls: the dashboard **Run** interface, Slack, or Telegram.

> **Warning**
>
> **Prompt injection can affect model classification.** Runtype excludes the Agent's question and the parameter values from the model input, and limits the result to approval, denial, unrelated, or unclear. These measures reduce the risk but do not remove it.
>
> **Use `NO` to deny an SMS approval.** Do not reply `STOP` or `CANCEL`. Carriers treat these words as opt-out commands and can unsubscribe your number before Runtype receives the message. The approval stays pending, and future messages to that number stop.

## Troubleshooting

Use the following table to fix common approval problems:

| Problem                                                      | Cause                                                        | Fix                                                               |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ----------------------------------------------------------------- |
| Telegram shows no approval prompt, or its buttons do nothing | The Telegram webhook secret is missing or does not match     | Connect the bot to the Telegram Surface again to reset the secret |
| A button or reply does nothing after a long wait             | The request expired after 1 hour and the tool did not run    | Ask the Agent again                                               |
| The run stops without an approval prompt                     | The Runtype Agent is single-pass                             | Turn on **Agent loop** and set **Max turns** to 2 or higher       |
| Unclear replies no longer get an answer                      | Runtype asked for a clear reply twice and now ignores others | Reply `YES` or `NO`                                               |

## Compare approval methods

Client Chat and chat widgets are not part of this comparison because they cannot collect an approval. Client-side tool pauses in Client Chat are a separate feature and cannot approve a server-side tool.

Use the following table to choose a Surface for a high-stakes tool:

| Question                        | Explicit approval controls (dashboard **Run**, Slack, Telegram)                                          | Reply-based approval (SMS, iMessage)                                |
| ------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| How you decide                  | Select **Approve** or **Deny**                                                                           | Reply with text                                                     |
| Can Runtype misread your reply? | No. The control has one meaning.                                                                         | Yes. A model interprets non-keyword text.                           |
| Does a model read your reply?   | No. The control returns a decision.                                                                      | Only when your reply is not an exact keyword.                       |
| Unclear reply                   | The control returns a decision.                                                                          | Runtype keeps the approval pending and asks again, up to two times. |
| Prompt injection path           | None                                                                                                     | Model classification reduces the risk but does not remove it.       |
| Who can decide                  | Dashboard: you. Slack: anyone who can see the prompt. Telegram: the person who started the conversation. | Only the participant who triggered the run                          |
| Always allow                    | Dashboard only                                                                                           | Not offered                                                         |
| No response                     | The request expires, and the tool does not run                                                           | The request expires, and the tool does not run                      |
| High-stakes tools               | Use an explicit control in a private channel or direct message.                                          | Choose a Surface with explicit controls instead.                    |

## Next steps

Continue with one of these guides:

* [Creating and configuring Agents](/user-guide/agents/creating-and-configuring-agents): turn on **Tool approval** and configure its scope
* [Setting up a Slack surface](/user-guide/products-surfaces/setting-up-a-slack-surface): use approval buttons in a channel
* [Setting up an SMS surface](/user-guide/products-surfaces/setting-up-an-sms-surface) and [setting up an iMessage surface](/user-guide/products-surfaces/setting-up-an-imessage-surface): use reply-based approval over text messaging
* [Flow validation warnings](/user-guide/flows/flow-validation-warnings): understand the approval warnings Runtype reports while you author
* [What are Surfaces?](/user-guide/products-surfaces/what-are-surfaces): review the available Surface types
* [Tool approvals](/user-guide/tools/tool-approvals): require approval before a tool runs, and approve or resume from the API
* [Taking over messaging conversations](/user-guide/products-surfaces/taking-over-conversations): take over a conversation from the Agent and hand it back