# Team approval for actions: a person approves before the agent acts

> Make an API action or a procedure step wait until someone from your team approves it. The agent tells the visitor the request is being reviewed, and the outcome is posted in the chat.

Some actions shouldn't run on the agent's word alone, such as a refund, a cancellation or a credit. Switch on **Requires team approval** for an [API action](/en/docs/api-actions) or a [procedure](/en/docs/procedures) step, and the agent no longer runs it by itself: the call waits on the **Approvals** page until someone from your team approves or rejects it.

- The agent tells the visitor their request is being reviewed and carries on with the conversation as usual.
- Approving runs the action once, with exactly the inputs that were waiting. The AI isn't asked again.
- Rejecting means it never runs. The visitor is told, with your reason if you give one.
- A request nobody decides in time expires and doesn't run either.

> Team approval is part of the Pro and Enterprise plans. See [Plans](#plans).

## Plans

| | Free | Starter | Pro | Enterprise |
| --- | --- | --- | --- | --- |
| Team approval for actions | No | No | Yes | Yes |

On Free and Starter the switch can't be turned on. After a downgrade, actions and steps that have it keep it and can still be edited, but **the agent doesn't run them from the chat**: it tells the visitor it can't do this here. Requests made before the downgrade still wait on the **Approvals** page and can be decided.

## Switch it on

**For an API action:** open the action on the **Actions** tab, go to **3. When the AI should use it**, switch on **Requires team approval** and choose when a request expires: after 1 hour, 4 hours, 24 hours (the default) or 3 days. Save the action. It shows a **Needs approval** badge in the list. Only server-side actions can require approval; client-side actions and buttons can't.

**For a procedure step:** in a **Call an action** step, tick **Requires team approval** and choose when a request expires. The action's own switch counts too: an action marked **Requires team approval** waits for approval in every procedure step that calls it, with the action's expiry.

With **Ask the visitor to confirm first** also ticked, the visitor confirms first and the request goes to your team after that.

## What the visitor sees

When the agent calls the action, nothing is sent to your API. The agent tells the visitor, in their language, that the request was passed to your team for review and that they'll see the outcome in the chat. The visitor can keep chatting about anything else meanwhile.

When the request is decided, intoCHAT posts a message in the conversation, in the visitor's language (English, German, French, Italian or Spanish):

| Outcome | Message (in English) |
| --- | --- |
| Approved, and the action succeeded | "Good news: our team approved your request, and it has been carried out." |
| Approved, but the action failed | "Our team approved your request, but it couldn't be completed just now. …" |
| Rejected | "Our team has reviewed your request and couldn't approve it." followed by "Reason: …" when you give one |
| Expired | "Our team couldn't review your request in time, so it wasn't carried out. …" |

The language comes from what the visitor wrote, or from the agent's **Reply language** when it is always used. An open chat shows the message within about 15 seconds; otherwise the visitor sees it the next time they open the chat. The agent also knows the outcome at the visitor's next message.

A conversation can have up to 3 requests waiting at once. If the agent calls the same action with the same inputs again while it waits, no second request is made.

## Approve or reject

Requests appear on the **Approvals** page in the sidebar, with a badge counting those waiting. Use **Agent** to see one agent's requests.

Each waiting request shows the action, the agent, the procedure if it came from one, when it was asked and when it expires, its inputs, and a link to the conversation.

- **Approve** asks you to confirm, then runs the action with exactly the inputs shown and tells the visitor the outcome. If the action fails, the request shows **Approved, failed** with the error, and the visitor is told it couldn't be completed.
- **Reject** asks for an optional reason, up to 500 characters, which the visitor sees in their chat.

Two people can't both decide: whoever clicks first decides, and the other sees "Already decided". An action never runs twice for one request.

**Recent decisions** lists the latest 50, with who decided, when, the reason and the result.

### Who can decide

Everyone whose role can edit the agent's actions: the owner, admins and editors, and [custom roles](/en/docs/team) with **Edit** on **Actions & procedures**. Members limited to selected agents see only those agents' requests. Viewers can't open the page. Each approval and rejection is recorded in the [audit log](/en/docs/audit-log).

### Inputs and secrets

The page, the emails, Slack and webhooks show each input by name. A value whose name or form looks like a credential, such as an input called `api_key` or `password`, a bearer token or a long key, is shown as **Hidden**. Your action's headers and authentication are never part of a request: intoCHAT stores only the inputs and builds the request from the saved action when it runs.

## Notifications

When a request is made:

- **Email** to everyone who can decide on that agent (see [Who can decide](#who-can-decide)), with the inputs and a link to the **Approvals** page. Each person can turn these off under **Notifications** in their account settings (**Approval requests**). Up to 30 request emails per agent go out each hour; requests past that still wait on the page.
- **Slack**: the **Approval request** alert, if you connected [Slack alerts](/en/docs/lead-alerts-and-export#slack-alerts) and ticked it.
- **Webhooks**: the `action_approval.requested` event, and `action_approval.decided` when it is approved, rejected or expires. See [Webhooks](/en/docs/webhooks#action-approval-data).
- **Inbox**: the conversation enters the [Inbox](/en/docs/inbox) as **Open**, unless it is already open or pending there.

## Procedures

A procedure step waiting for approval stays the current step. Calling the action again makes no second request, and the agent keeps helping the visitor with other questions without stopping the procedure.

- **Approved and succeeded:** the procedure continues from the next step at the visitor's next message. If the next step is an **End** step with a message, the agent says it then; if it is an **End** step without a message, or there are no more steps, the procedure is completed.
- **Approved but failed, rejected or expired:** the procedure stops.
- If the visitor cancels and the agent stops the procedure while a request waits, or another procedure starts, or you delete the procedure or change it so the step no longer exists or calls another action, the request is withdrawn. It shows as **Rejected** with "Withdrawn when the procedure ended in the chat" and never runs: clicking **Approve** on it then only withdraws it. No message is posted, since the chat already moved on.

## Expiry

A request expires at the time you chose. It is checked whenever the conversation continues, the **Approvals** page is opened or the chat is open, and once a day for all requests. An expired request never runs, and the visitor is told.

## Limits

- Requests need a saved conversation: in a temporary chat, an action that requires approval doesn't run at all.
- In the **Playground**, requests are real: they appear on the **Approvals** page and notify your team, and approving runs your real action.
- In tests with simulated customers (**Playground → Tests**), nothing is requested: the agent hears that the request was made.
- In chats through the [REST API](/en/docs/rest-api), the outcome message is saved in the conversation, where your integration can read it.
- In [Slack](/en/docs/slack-agent) and [email](/en/docs/email-agent) conversations, the outcome message is saved in the conversation but not posted in the thread or emailed; the agent tells the person at their next message.
- Approving runs the action as the agent would have, within its 30-second timeout, with the verified visitor and contact of the conversation for `{{user.*}}` and `{{contact.*}}` placeholders. If the action was deleted, switched off or changed into a client-side action meanwhile, approving fails and the visitor is told.

## Next steps

- Set up the action: [API actions](/en/docs/api-actions).
- Put it in a step-by-step flow: [Procedures](/en/docs/procedures).
- Get the events in your tools: [Webhooks](/en/docs/webhooks) and [Slack alerts](/en/docs/lead-alerts-and-export#slack-alerts).
