External Agent está disponible en los planes YCloud Pro y superiores.
Antes de comenzar
Prepara:- Un endpoint HTTPS accesible públicamente que acepte solicitudes JSON
POST. - Un servicio que verifique las firmas de webhook, almacene eventos, evite el procesamiento de duplicados y ejecute tu agente de IA.
- Una clave de API estándar de tu cuenta de YCloud, almacenada en tu servidor. Las claves de API de Developer App no son compatibles con estos endpoints de Inbox.
- Un número comercial de WhatsApp conectado a YCloud y un equipo o agente humano para recibir transferencias.
https://api.ycloud.com como la URL base de la API.
Conecta tu agente
1. Crear un External Agent
- En la consola de YCloud, abre AI Agent > AI Agent.
- Selecciona Create Agent > External Agent.
- Introduce un Name y tu Webhook URL, como
https://agent.example.com/webhooks/ycloud. - Selecciona Save.
- Copia el Bot ID generado desde los detalles del agente. Usa este valor como
botIden las solicitudes de la API; no necesitas proporcionar un ID de tu propio sistema de IA.

Create an External Agent with a name and a webhook URL. This example shows the form before saving.
X-API-Key autentica tus solicitudes REST salientes. Un Bot ID es un identificador, no una credencial.
2. Asignar un número de WhatsApp
Abre WhatsApp Manager > WhatsApp accounts, luego abre la configuración del número comercial y selecciona Inbox > Assignment. En Priority 3 Assign to, selecciona AI Agent, y después elige tu agente en la sección External Agent del selector de agentes. Comprueba la prioridad de las reglas: la asignación al propietario del cliente o al último agente que atendió puede tener precedencia. Consulta Conversation assignment rules. Un solo External Agent puede gestionar múltiples números. Cada número está asociado con un solo bot a la vez. Administra estas asociaciones en la configuración de asignación del número.3. Procesar una conversación
- Un cliente envía un mensaje de WhatsApp a tu número comercial.
- YCloud abre o continúa un diálogo de Inbox y aplica las reglas de asignación del número.
- Cuando tu External Agent gestiona el diálogo, YCloud envía los eventos de webhook correspondientes a su endpoint.
- Tu servicio verifica y almacena el evento, devuelve
2xxy procesa la entrada del cliente de forma asíncrona. - Tu servicio llama a la API de Inbox para responder, transferir o cerrar el diálogo.
- Tu servicio rastrea la entrega mediante
whatsapp.message.updated.
Comprender los identificadores
Los ID son cadenas. Las marcas de tiempo utilizan UTC RFC 3339. Usa
dialogId, no conversationId, en las rutas de la API del diálogo.
Recibir eventos de webhook
Los cuatro tipos de eventos llegan a la misma URL de webhook. Cada entrega dedicada de External Agent incluyeid, type, apiVersion, createTime e externalBotContext, además del objeto de negocio correspondiente.
Verificar, almacenar y confirmar
Verifica el encabezadoYCloud-Signature usando el secreto de firma del endpoint y el cuerpo sin procesar de la solicitud HTTP, antes de analizar el JSON. El formato de la firma es:
2xx exitosa. Ejecuta la inferencia de IA y otros procesos lentos de forma asíncrona. Las respuestas que no sean 2xx y los tiempos de espera pueden activar un número limitado de reintentos.
Deduplica por (botId, event.id), dentro de tu cuenta de YCloud. Un cambio de asignación puede notificar tanto al agente saliente como al entrante; usar únicamente un ID de evento global puede descartar la notificación de uno de los agentes. Mantén el estado de procesamiento para que un evento repetido no envíe una segunda respuesta.
Ejemplo: mensaje del cliente
inboxMessage.inbound. Los eventos de creación salientes usan inboxMessage.outbound en su lugar. Conserva los tipos de mensajes y campos desconocidos por motivos de compatibilidad en lugar de tratarlos como texto.
Decidir si responder
externalBotContext es una instantánea tomada cuando se genera la notificación. Su campo botId identifica al bot receptor; assignee identifica al gestor real en esa instantánea. Estos pueden diferir tras una transferencia.
actionable=true significa que el bot receptor estaba gestionando un diálogo abierto en ese momento. También puede ser true en un evento de creación saliente o en un recibo de entrega.
Los eventos pueden llegar más de una vez o desordenados. No existe un campo de secuencia de eventos. Agrupa el trabajo por dialogId y evita procesar dos veces la misma entrada del cliente. Un evento de asignación inicial no debe activar de forma independiente una segunda respuesta al mensaje inicial del cliente.
¿Qué ocurre tras una transferencia o cierre?
Los nuevos mensajes de clientes y las respuestas humanas ya no se entregan al External Agent anterior una vez que el diálogo es gestionado por un humano, queda en cola, sin asignar o cerrado. El agente anterior sigue recibiendo la notificación correspondiente de asignación saliente o de cierre. Las notificaciones de creación y los recibos de entrega de los mensajes que ya envió permanecen asociados a ese agente emisor, incluso después de una transferencia o reasignación de número. Las notificaciones generadas previamente pueden llegar tarde. Cancela el trabajo pendiente cuando cambie la asignación o se cierre el diálogo, y no lo reanudes únicamente porque un evento antiguo tengaactionable=true.
Los endpoints de webhook normales conservan su comportamiento de suscripción y su formato de carga útil existentes. La entrega dedicada de External Agent añade externalBotContext; no exijas ese campo en entregas ordinarias de whatsapp.message.updated.
Usar la API de Inbox
EnvíaX-API-Key en cada solicitud y Content-Type: application/json en solicitudes POST. Todos los ejemplos que aparecen a continuación usan identificadores de marcador de posición. Sustitúyelos por valores de tu agente y de los eventos recibidos.
Las respuestas correctas devuelven directamente el objeto de negocio, sin un contenedor
data. Las operaciones de escritura comprueban que el diálogo esté abierto y gestionado actualmente por el bot especificado. YCloud determina el remitente y el cliente a partir del diálogo; no envíes tenantId, from, to, recipient, operatorId ni source para anularlos.
Obtener el diálogo actual
status, assignee y canAct. El campo bot puede hacer referencia al último bot externo asociado y no es una prueba de la propiedad actual. canAct refleja los permisos del bot consultado en el momento de la solicitud; una escritura posterior seguirá realizando sus propias comprobaciones.
Recuperar el historial de conversaciones
items y nextCursor. Cada elemento incluye un mensaje de Inbox id, direction, type, content y createTime. Para un mensaje de texto, lee content.text.body.
El historial incluye los mensajes visibles para el cliente de la misma conversación, posiblemente a través de diálogos anteriores. El propio dialogId de un mensaje puede ser diferente del diálogo solicitado o no estar presente en un historial más antiguo. Las notas internas, los resúmenes privados de derivación y los mensajes internos del sistema quedan excluidos.
Los mensajes se devuelven en orden ascendente por ID de mensaje, de más antiguos a más recientes. Omite after en la primera solicitud; pasa nextCursor sin modificar como after en las solicitudes posteriores hasta que sea null. El valor predeterminado de limit es 50, con un rango de 1 a 100. La lista de destinatarios de derivación utiliza el mismo patrón de paginación.
Enviar una respuesta
botId y message son obligatorios. sourceEventId y replyToMessageId son opcionales. La referencia de respuesta es un ID de mensaje de Inbox, como inboxMessage.id; no es un wamid.
status incluso cuando HTTP devuelva 200. accepted significa que el mensaje entró en la canalización de envío, no que haya llegado al cliente. Una respuesta 200 también puede indicar failed; es posible que channelMessageId aún no esté disponible.
Usa whatsapp.message.updated para rastrear los estados posteriores, incluidos sent, delivered, read, failed, expired o deleted. Correlaciona el externalBotContext.inboxMessageId del recibo con el inboxMessageId de la respuesta de envío. Revisa whatsappMessage.errorCode y errorMessage en busca de errores.
Tipos de mensaje
El objetomessage utiliza el modelo estándar de mensajes de WhatsApp: type más el campo de contenido correspondiente. Entre los ejemplos se incluyen text, image, video, audio, document, sticker, location, contacts, interactive, template y reaction. Los requisitos existentes de envío y plantillas de WhatsApp siguen aplicando.
Por ejemplo, sustituye el objeto message por:
id o bien link. Para conocer las estructuras del cuerpo del mensaje, consulta Enviar un mensaje de WhatsApp. Envía la respuesta a través del endpoint de Inbox anterior para que utilice las comprobaciones de gestión del diálogo y el contexto de Inbox. No envíes ni dependas de filterUnsubscribed o filterBlocked en esta solicitud de mensaje de Inbox.
Las respuestas de los clientes pueden incluir interactive.button_reply, interactive.list_reply, interactive.nfm_reply o button. El response_json de una respuesta de Flow es una cadena JSON. El tipo entrante button no es un tipo de mensaje saliente para este endpoint.
Derivar a un agente humano
Primero, lista los equipos o agentes disponibles para el número de negocio del diálogo:type=agent para listar los miembros en su lugar. Cada destinatario devuelto proporciona el id y el type para la solicitud de derivación. El campo opcional online de un agente describe la presencia; no garantiza una asignación inmediata.
target con type (team o agent) y id. No hay una alternativa humana predeterminada. El campo opcional reason admite hasta 256 caracteres; el campo opcional summary admite hasta 4000 caracteres y no forma parte del historial de mensajes visible para el cliente.
La respuesta contiene outcome y el dialog actualizado. Los resultados son assigned, queued, team_unassigned o unassigned. Comprueba el resultado real en lugar de asumir que un agente humano ha aceptado la conversación.
Una derivación mantiene el mismo dialogId. Una vez que tu agente pierda la asignación, deja de responder o de intentar cerrar ese diálogo.
Cerrar un diálogo resuelto
dialog con status=closed y canAct=false. Tu agente no puede continuar enviando mensajes ni derivando ese diálogo cerrado. Un mensaje válido posterior del cliente iniciará un nuevo diálogo y volverá a ejecutar las reglas de asignación del número.
Gestionar errores y reintentos
Las respuestas de error utilizan un objetoerror con status, code, message y requestId. Conserva el ID de solicitud al ponerte en contacto con el soporte de YCloud.
Monitorea View delivery logs para detectar fallos de webhook. Conserva los ID de evento, ID de diálogo, ID de mensaje, ID de solicitud y los resultados del procesamiento. Los reintentos de Webhook son limitados, así que usa consultas de diálogo e historial para recuperar el contexto cuando sea necesario.
Preguntas frecuentes
¿Puedo conectar un agente creado con mi propio framework de IA?
Sí. Tu servicio debe recibir y verificar los webhooks de YCloud y llamar a la API REST de Inbox. Tú controlas cómo genera respuestas tu servicio, cómo accede al conocimiento y cómo invoca sus propias herramientas.¿Mi agente recibirá todas las conversaciones de Inbox?
No. Su endpoint dedicado recibe eventos dentro de su ámbito de gestión, junto con notificaciones pertinentes de asignación y cierre, y recibos de sus propios mensajes enviados. Los nuevos mensajes tras una transferencia a un agente humano no se reenvían al agente anterior. Los eventos generados previamente aún pueden llegar con retraso.¿Puede mi agente utilizar mensajes de diálogos anteriores?
Sí. El endpoint de historial devuelve el historial visible para el cliente correspondiente a la conversación, incluidos los diálogos anteriores. Utiliza el propiodialogId de cada mensaje cuando esté disponible; no asumas que cada mensaje devuelto pertenece a la sesión de servicio actual.
¿Qué ocurre si cambio el agente asignado a un número?
Los diálogos abiertos gestionados actualmente por un bot se reasignan de forma asíncrona según el comportamiento de enrutamiento del número. El agente saliente recibeassignmentRole=outgoing y debe detener su trabajo. El agente entrante recibe reason=phone_binding_changed con assignmentRole=incoming; debe consultar el diálogo actual y el historial antes de continuar.
El ID del diálogo y el historial permanecen sin cambios. Los diálogos gestionados actualmente por una persona no se transfieren al nuevo bot mediante esta reasignación de número. Después de que otro bot lo sustituya, el bot anterior ya no podrá consultar ese diálogo a través de estos endpoints.
¿La respuesta de mi webhook se convierte en la respuesta al cliente?
No. Devuelve2xx para confirmar la recepción del evento y luego envía la respuesta al cliente a través de POST /v2/inbox/dialogs/{dialogId}/messages.
¿Por qué recibe mi agente actionable=true para su propia respuesta?
El campo describe quién gestionaba el diálogo abierto cuando se generó el evento. Por tanto, los eventos de creación de salida y los recibos de entrega pueden tener actionable=true. Activa una respuesta de IA normal únicamente para un evento inbox.message.created entrante, y ten en cuenta los cambios en la titularidad del diálogo en vivo.
