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

# Resumen

> Ejecuta hasta 10 acciones sobre una conversación en un solo request.

<Info>
  **Endpoint** · `POST /conversation/actions`
</Info>

El endpoint `POST /conversation/actions` ejecuta un **grupo de hasta 10
acciones** sobre **una sola conversación**, en el orden que las envías. En vez
de hacer N requests para etiquetar, dejar una nota y ejecutar el AI, los
encadenas en un solo request. Es el camino recomendado para mutar una
conversación desde un cliente externo.

Cada elemento del array `actions` lleva un campo `type`. `send_message` unifica
los cuatro modos de envío (texto, media, respuesta rápida, plantilla).
`send_quick_reply_or_template` es la única cuyo modo lo decide el servidor: manda
la respuesta rápida si la [ventana de 24h](/es/conversations) está abierta, o la
[plantilla](/es/templates) si está cerrada.

| Acción                                                                           | Qué hace                                                     | ¿Dispara AI?         |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------------------- |
| [`send_message`](/es/action-groups/send-message)                                 | Envía un mensaje: texto, media, respuesta rápida o plantilla | No                   |
| [`send_quick_reply_or_template`](/es/action-groups/send-quick-reply-or-template) | Respuesta rápida o plantilla según la ventana                | No                   |
| [`assign_label`](/es/action-groups/assign-label)                                 | Asigna una o varias etiquetas                                | No                   |
| [`remove_label`](/es/action-groups/remove-label)                                 | Quita una o varias etiquetas                                 | No                   |
| [`assign_mailbox`](/es/action-groups/assign-mailbox)                             | Mueve la conversación a un buzón o categoría                 | No                   |
| [`context_note`](/es/action-groups/context-note)                                 | Deja una nota de contexto                                    | No                   |
| [`mark_resolved`](/es/action-groups/conversation-status)                         | Marca la conversación como resuelta                          | No                   |
| [`mark_pending`](/es/action-groups/conversation-status)                          | Marca la conversación como pendiente                         | No                   |
| [`run_ai`](/es/action-groups/run-ai)                                             | Ejecuta el empleado AI asignado (o uno explícito)            | Sí                   |
| [`ai_assistance`](/es/action-groups/ai-assistance)                               | Consulta a otro empleado AI para una respuesta sugerida      | Sí                   |
| [`assign_ai_employee`](/es/action-groups/ai-employee)                            | Asigna un empleado AI (con `run: true`, además ejecuta)      | Solo con `run: true` |
| [`unassign_ai`](/es/action-groups/ai-employee)                                   | Retira el empleado AI (pasa a humano)                        | No                   |
| [`cancel_schedule`](/es/action-groups/cancel-scheduled-message)                  | Cancela la programación activa: mensaje o ejecución de AI    | No                   |

<Note>
  Un grupo admite hasta **10 acciones**, de las cuales como máximo **3** pueden
  disparar al AI. Excederlo falla con `BATCH_LIMIT_EXCEEDED`.
</Note>

Cada acción tiene su propia página con sus campos y un ejemplo — abre la que
necesites desde la tabla o el nav. Para enviar multimedia, primero súbela con el
flujo de [Subir multimedia](/es/action-groups/upload-media).

## Identificar la conversación

El grupo corre sobre **una** conversación: la identificas con el objeto
`conversation`, que lleva **exactamente uno** de `uuid`, `whatsapp_user_id`,
`username` o `phone`, **más `channel` (obligatorio)**.

<ParamField body="uuid" type="string">
  Clave estable de una conversación que ya conoces. El camino más directo.
</ParamField>

<ParamField body="whatsapp_user_id" type="string">
  BSUID del contacto (identidad opaca de Meta). Resuelve por igualdad exacta;
  identificador recomendado de aquí en adelante.
</ParamField>

<ParamField body="username" type="string">
  Username público de WhatsApp, con o sin `@` y sin distinguir mayúsculas. Si
  varios contactos lo comparten, la API responde `409` (`USERNAME_AMBIGUOUS`).
</ParamField>

<ParamField body="phone" type="string">
  Teléfono en formato E.164. Si está duplicado entre contactos, la API responde
  `409` (`PHONE_NUMBER_AMBIGUOUS`) en vez de adivinar.
</ParamField>

<ParamField body="channel" type="string" required>
  Clave pública del canal — cópiala del dashboard en **Configuración → Canales**
  (campo **Clave de canal**), o lístalas con `GET /channels`. **Obligatorio** en todo
  request: fija el canal objetivo. En las vías por contacto (`phone`, `username`,
  `whatsapp_user_id`) restringe la resolución a ese canal; con `uuid` el motor lo
  ignora, pero el contrato igual lo exige. Una clave que no existe → `404`
  (`CHANNEL_NOT_FOUND`).
</ParamField>

Referencia completa (orden de resolución, unificación de conversaciones y
ambigüedades de contacto) en [Identificar una conversación](/es/conversations).

## Cómo se ejecuta

<Steps>
  <Step title="Validación síncrona">
    La API valida el request. Si el preflight lo rechaza (ej. el AI no tiene
    tokens), responde un `4xx` síncrono y **ninguna** acción se ejecuta.
  </Step>

  <Step title="202 Accepted">
    Si pasa la validación, responde **`202`** de inmediato; el grupo corre en
    **background**.
  </Step>

  <Step title="Ejecución en orden">
    Las acciones se ejecutan una por una, en el orden enviado.
  </Step>
</Steps>

<Warning>
  El `202` confirma que el grupo fue **aceptado**, no que cada acción tuvo éxito.
  El resultado por acción **no viaja en la respuesta** — consúltalo en el estado
  de la conversación o en el activity log del negocio.
</Warning>

## Stop on error

`stop_on_error` controla qué pasa cuando una acción falla durante la ejecución:

| Valor            | Comportamiento                                                         |
| ---------------- | ---------------------------------------------------------------------- |
| `true` (default) | La primera falla **corta** las acciones siguientes.                    |
| `false`          | El grupo ejecuta **todas** las acciones, ignorando fallos intermedios. |

## Escalada a pending

`escalate_on_error` controla si una falla del grupo escala la conversación a `inbox_status='pending'` para que un humano la revise:

| Valor            | Comportamiento                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `true` (default) | Si una acción falla con un error de **entrega, ejecución AI, escritura en DB, o race de asignación AI** (`SEND_FAILED`, `PREPARE_FAILED`, `AI_EXECUTION_FAILED`, `ACTIONS_DEPTH_EXCEEDED`, `UPDATE_FAILED`, `NO_AI_EMPLOYEE_ASSIGNED`), la conversación se marca como `pending` con `pending_reason='action_set_failed'`. Una sola escalada por grupo aunque varias acciones fallen. |
| `false`          | Las fallas se reportan en el activity log pero la conversación queda intacta.                                                                                                                                                                                                                                                                                                        |

<Note>
  Los errores de input del integrador (`*_NOT_FOUND`, `*_AMBIGUOUS`, `WINDOW_CLOSED`, `TEMPLATE_NOT_APPROVED`, etc.), los guards de billing (`WALLET_BLOCKED`, `VISION_WALLET_BLOCKED`) y el guard de integridad de `mark_resolved` (`TRANSCRIPTION_REQUIRED_TO_RESOLVE`) **nunca escalan** — corrígelos y reintenta sin intervención humana.
</Note>

## Armar una lista de acciones

Cada acción es un objeto en el array `actions`, identificado por su `type`. Un
request agrupa varias acciones sobre la **misma** conversación y se ejecutan en el
orden enviado. El objeto `conversation` siempre incluye `channel`. Ejemplo —
etiquetar, dejar una nota y ejecutar el AI, sin cortar ante fallos:

<CodeGroup>
  ```jsonc Request theme={null}
  {
    "conversation": {
      "phone": "+5215512345678",
      "channel": "ch_7A9K2M4Q"
    },
    "stop_on_error": false,
    "actions": [
      { "type": "assign_label", "tags": [{ "name": "VIP" }] },
      { "type": "context_note", "note": "Cliente pidió cotización." },
      { "type": "run_ai", "ai_employee": { "name": "Agente Ventas" } }
    ]
  }
  ```

  ```jsonc Respuesta 202 theme={null}
  {
    "status": "processing",
    "actions_accepted": 3
  }
  ```
</CodeGroup>

### Identificar por distintos campos

Cambia solo el identificador dentro de `conversation` (`channel` va siempre); el
resto del request no cambia:

<CodeGroup>
  ```jsonc Por teléfono theme={null}
  {
    "conversation": {
      "phone": "+5215512345678",
      "channel": "ch_7A9K2M4Q"
    },
    "actions": [{ "type": "mark_resolved" }]
  }
  ```

  ```jsonc Por BSUID theme={null}
  {
    "conversation": {
      "whatsapp_user_id": "5f8d0a2b1c9e",
      "channel": "ch_7A9K2M4Q"
    },
    "actions": [{ "type": "mark_resolved" }]
  }
  ```

  ```jsonc Por username theme={null}
  {
    "conversation": {
      "username": "@mariana.lopez",
      "channel": "ch_7A9K2M4Q"
    },
    "actions": [{ "type": "mark_resolved" }]
  }
  ```

  ```jsonc Por uuid theme={null}
  {
    "conversation": {
      "uuid": "7b8a1c2d-3e4f-5a6b-7c8d-9e0f1a2b3c4d",
      "channel": "ch_7A9K2M4Q"
    },
    "actions": [{ "type": "mark_resolved" }]
  }
  ```
</CodeGroup>

**Pasar a humano** — una sola acción `unassign_ai`, sin campos. Es idempotente:
si la conversación ya no tiene AI, es un no-op exitoso.

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

  ```jsonc Respuesta 202 theme={null}
  {
    "status": "processing",
    "actions_accepted": 1
  }
  ```
</CodeGroup>

<Tip>
  Si el preflight rechaza el grupo, la respuesta es un `4xx` síncrono y ninguna
  acción se ejecuta. Ver [Errores](/es/errors).
</Tip>
