> ## Documentation Index
> Fetch the complete documentation index at: https://docs.1to1ai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Action group

> Run up to 10 actions on a conversation in a single request.

The `POST /conversation/actions` endpoint runs a **group of up to 10 actions**
on **a single conversation**, in the order you send them. Instead of making N
requests to label, leave a note and run the AI, you chain them in a single
request.

## The 12 actions

Each element of the `actions` array carries a `type` field. Almost all mirror
an individual API endpoint; `send_quick_reply_or_template` is the exception:
it sends the quick reply if the 24h window is open, or the
[template](/en/templates) if it's closed — the mode is decided by the server
at runtime.

<AccordionGroup>
  <Accordion title="Messaging" icon="paper-plane">
    * `send_message` — sends a message (text, media, quick reply, or template).
    * `send_quick_reply_or_template` — quick reply or template, depending on the window.
  </Accordion>

  <Accordion title="Labels" icon="tag">
    * `assign_label` — assigns a label to the conversation.
    * `remove_label` — removes a label from the conversation.
  </Accordion>

  <Accordion title="Mailbox and notes" icon="inbox">
    * `assign_mailbox` — moves the conversation to a mailbox.
    * `context_note` — leaves an internal note.
    * `mark_resolved` — marks the conversation as resolved.
    * `mark_pending` — marks the conversation as pending.
  </Accordion>

  <Accordion title="AI" icon="robot">
    * `run_ai` — runs the AI employee on the conversation.
    * `ai_assistance` — generates a suggested reply with the AI.
    * `assign_ai_employee` — assigns an AI employee to the conversation.
    * `unassign_ai` — removes the AI employee (hands the conversation off to a human). No fields; idempotent (no-op if the conversation already has no AI).
  </Accordion>
</AccordionGroup>

<Note>
  A group allows up to **10 actions**, of which at most **3** can trigger the AI.
  Exceeding it fails with `BATCH_LIMIT_EXCEEDED`.
</Note>

## How it runs

<Steps>
  <Step title="Synchronous validation">
    The API validates the request. If the preflight rejects it (e.g. the AI has
    no tokens), it responds a synchronous `4xx` and **no** action runs.
  </Step>

  <Step title="202 Accepted">
    If validation passes, it responds **`202`** immediately; the group runs in
    the **background**.
  </Step>

  <Step title="Execution in order">
    The actions run one by one, in the order sent.
  </Step>
</Steps>

<Warning>
  The `202` confirms the group was **accepted**, not that every action succeeded.
  The per-action result **does not travel in the response** — query it in the
  conversation status or in the business's activity log.
</Warning>

## Stop on error

`stop_on_error` controls what happens when an action fails during execution:

| Value            | Behavior                                                        |
| ---------------- | --------------------------------------------------------------- |
| `true` (default) | The first failure **halts** the remaining actions.              |
| `false`          | The group runs **all** actions, ignoring intermediate failures. |

## Escalation to pending

`escalate_on_error` controls whether a group failure escalates the conversation to `inbox_status='pending'` for human review:

| Value            | Behavior                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `true` (default) | If an action fails with a **delivery, AI execution, DB write, or AI assignment race** error (`SEND_FAILED`, `PREPARE_FAILED`, `AI_EXECUTION_FAILED`, `ACTIONS_DEPTH_EXCEEDED`, `UPDATE_FAILED`, `NO_AI_EMPLOYEE_ASSIGNED`), the conversation is marked `pending` with `pending_reason='action_set_failed'`. Only one escalation per group, even if multiple actions fail. |
| `false`          | Failures are reported in the activity log but the conversation state is left untouched.                                                                                                                                                                                                                                                                                   |

<Note>
  Integrator input errors (`*_NOT_FOUND`, `*_AMBIGUOUS`, `WINDOW_CLOSED`, `TEMPLATE_NOT_APPROVED`, etc.), billing guards (`WALLET_BLOCKED`, `VISION_WALLET_BLOCKED`), and the `mark_resolved` integrity guard (`TRANSCRIPTION_REQUIRED_TO_RESOLVE`) **never escalate** — fix and retry without human intervention.
</Note>

## Example

Label, leave a note and run the AI, without halting on failures:

<CodeGroup>
  ```jsonc Request theme={null}
  {
    "conversation": { "phone": "+5215512345678" },
    "stop_on_error": false,
    "actions": [
      { "type": "assign_label", "tags": [{ "name": "VIP" }] },
      { "type": "context_note", "note": "Customer requested a quote." },
      { "type": "run_ai", "ai_employee": { "name": "Sales Agent" } }
    ]
  }
  ```

  ```jsonc 202 Response theme={null}
  {
    "conversation": { "uuid": "..." },
    "status": "processing",
    "actions_accepted": 3
  }
  ```
</CodeGroup>

**Hand off to a human** — a single `unassign_ai` action, no fields. It's
idempotent: if the conversation already has no AI, it's a successful no-op.

<CodeGroup>
  ```jsonc Request theme={null}
  {
    "conversation": { "phone": "+5215512345678" },
    "actions": [{ "type": "unassign_ai" }]
  }
  ```

  ```jsonc 202 Response theme={null}
  {
    "conversation": { "uuid": "..." },
    "status": "processing",
    "actions_accepted": 1
  }
  ```
</CodeGroup>

<Note>
  Only need to hand off to a human and want the result right away? The synchronous
  `POST /conversation/unassign-ai`
  endpoint does exactly this and responds `200` with the real result
  (`{ "ai_employee": null, "schedule_action": "cancelled" | "none" }`), without the
  group's async model.
</Note>

<Tip>
  If the preflight rejects the group, the response is a synchronous `4xx` and no
  action runs. See [Errors](/en/errors).
</Tip>
