Endpoint ·
POST /conversation/actionsPOST /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).
Si le pasas una template junto a un primario (texto/media o respuesta rápida), el
servidor decide según la ventana de 24h: manda el primario si
está abierta, o la plantilla si está cerrada.
Un grupo admite hasta 10 acciones, de las cuales como máximo 3 pueden
disparar al AI o ser un
send_json, cuya respuesta puede continuar la
conversación. Excederlo falla con BATCH_LIMIT_EXCEEDED.Identificar la conversación
El grupo corre sobre una conversación: la identificas con el objetoconversation, que lleva exactamente uno de uuid, whatsapp_user_id,
username o phone, más channel (obligatorio).
BSUID del contacto (identidad opaca de Meta). Resuelve por igualdad exacta;
identificador recomendado de aquí en adelante.
Username público de WhatsApp, con o sin
@ y sin distinguir mayúsculas. Si
dos contactos distintos lo comparten en el mismo canal, la API responde 409
(USERNAME_AMBIGUOUS); el mismo username en canales distintos no es ambiguo:
channel lo resuelve.Teléfono en formato E.164. Si está duplicado entre dos contactos distintos del
mismo canal, la API responde
409 (PHONE_NUMBER_AMBIGUOUS) en vez de
adivinar; el mismo número en canales distintos no es ambiguo: channel lo
resuelve.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).Cómo se ejecuta
1
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.2
202 Accepted
Si pasa la validación, responde
202 de inmediato; el grupo corre en
background.3
Ejecución en orden
Las acciones se ejecutan una por una, en el orden enviado.
AI_EMPLOYEE_V2_NOT_SUPPORTED (422), antes de ejecutar: una acción que ejecutaría a un v2 con el motor v2 apagado, y un empleado clásico que ejecuta al asignado (run_assigned) cuando el asignado es v2. Asignar un v2 sin run no se rechaza nunca, y la respuesta de un send_json la puede procesar un v2. Los dos casos de destino dinámico —un run_ai sin ai_employee precedido por un assign_ai_employee del grupo, y una acción cuyo empleado clásico ejecuta al asignado (run_assigned) cuando, después de un assign_ai_employee o un unassign_ai anterior, el asignado es un v2 (porque ese assign lo asignó, o porque no llegó a cambiarlo)— fallan por acción, después del 202.
Stop on error
stop_on_error controla qué pasa cuando una acción falla durante la ejecución:
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:
Los errores de input del integrador (
*_NOT_FOUND, *_AMBIGUOUS, WINDOW_CLOSED, TEMPLATE_NOT_APPROVED, etc.), los marcadores de pago mal usados (PAYMENT_MARKER_UNKNOWN, PAYMENT_MARKER_UNSUPPORTED_FIELD, TEMPLATE_BODY_TOO_LONG — el arreglo está en el texto que enviaste, no en la conversación), los guards de billing (WALLET_BLOCKED, VISION_WALLET_BLOCKED), el guard de integridad de mark_resolved (TRANSCRIPTION_REQUIRED_TO_RESOLVE) y el destino v2 (AI_EMPLOYEE_V2_NOT_SUPPORTED, también cuando falla por acción después del 202) nunca escalan — corrígelos y reintenta sin intervención humana; el destino v2 no se reintenta tal cual: con el motor v2 apagado, vuelve a intentar más tarde; en los otros casos, usa un empleado clásico.Armar una lista de acciones
Cada acción es un objeto en el arrayactions, 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:
Identificar por distintos campos
Cambia solo el identificador dentro deconversation (channel va siempre); el
resto del request no cambia:
unassign_ai, sin campos. Es idempotente:
si la conversación ya no tiene AI, es un no-op exitoso.