1. Descripción general
La Conversational Agent Interface (CAI) es la interfaz estándar de OMB Cloud AES para incorporar un proveedor externo de agente conversacional a los canales digitales de un cliente. Cubre la captación por formularios, web chat y canales de mensajería, y el manejo de la conversación resultante hasta una cita agendada o un resultado registrado.
La división del trabajo es deliberada y acotada. El Proveedor aporta la inteligencia conversacional. AES aporta el flujo de contactos, el ruteo y el registro permanente. Todo lo que el cliente ve, mide y opera sigue viviendo en AES.
La empresa que implementa esta interfaz se denomina en adelante el Proveedor. A cada Proveedor se le asigna un provider_code y un juego de credenciales al incorporarse.
Esta especificación está versionada y es común a todos los Proveedores. Los valores propios de cada entorno — código de proveedor, catálogo, credenciales, direcciones autorizadas — se entregan por separado en un anexo privado.
2. Responsabilidades
| Responsabilidad | AES | Proveedor |
|---|---|---|
| Captación del contacto | Sí | — |
| Resolución de la unidad de destino | Sí | — |
| Selección del número o identidad de origen | — | Sí |
| Conversación con el contacto | — | Sí |
| Cierre de la cita | — | Sí |
| Registro y resguardo de la conversación | Sí | — |
| Seguimiento comercial posterior | Sí | — |
2.1 Interfaces
| Id | Dirección | Método | Propósito |
|---|---|---|---|
A | AES → Proveedor | POST | Entrega de encargos de contacto |
B | Proveedor → AES | POST | Retorno de conversación, citas y resultados |
Ambas direcciones son de empuje. Ninguna de las dos partes sondea a la otra, y esta interfaz no expone endpoints de consulta. Eso mantiene la latencia baja, elimina los procesos de sincronización periódica, y hace que integrarse tenga exactamente dos piezas móviles.
3. Ciclo de vida
1. Contacto Llena un formulario o escribe en un canal digital.
2. AES Crea el registro, resuelve la unidad de destino y
asigna un lead_id que acompaña la relación.
3. AES → Prov. [Interfaz A] Entrega el encargo de contacto con la
unidad y el contexto de la solicitud.
4. Proveedor Selecciona el número de origen de esa unidad e inicia
la conversación.
5. Prov. → AES [Interfaz B] Devuelve la conversación conforme ocurre,
y el resultado: cita agendada o motivo de cierre.
6. AES Registra ambos contra el lead, marcados con el
provider_code. El cliente continúa el seguimiento.
La unidad de destino se resuelve en el momento de la captación, donde se conocen el landing, la campaña y la ubicación solicitada. Viaja en el campo branch_code de cada encargo, de modo que un Proveedor nunca tiene que mantener ni actualizar lógica de ruteo conforme un cliente abre nuevas unidades.
4. Interfaz A — Encargos de contacto
POST {provider_endpoint}/contact-jobs
Content-Type: application/json
X-CAI-Source: aes
X-CAI-Signature: sha256=<hmac_hex>
X-CAI-Timestamp: 1787923271
AES firma lo que envía con el mismo esquema de la sección 6, usando el secreto contrario del par. El Proveedor debe verificarlo igual que AES verifica lo suyo: mismo algoritmo, misma ventana de 300 segundos, comparación en tiempo constante.
AES entrega cada contacto que corresponde atender al Proveedor, en el momento de la captación.
4.1 Cuerpo de la petición
{
"lead_id": "AES-38-104772",
"event_id": "job_9f2c1a8e4b",
"branch_code": "ACME-NORTE",
"city": "Monterrey",
"contact": {
"name": "María Fernanda Ríos",
"phone_e164": "+5218112345678",
"email": "mfrios@example.com",
"language": "es-MX"
},
"origin": {
"channel": "landing_form",
"source": "example.com/norte/servicio",
"campaign": "primavera-norte",
"captured_at": "2026-08-27T14:02:11-06:00"
},
"brief": {
"intent": "book_appointment",
"notes": "Solicitó horario vespertino."
},
"callback_url": "https://omb.cloud/app/api/cai_events.php"
}
4.2 Campos
| Campo | Tipo | Oblig. | Descripción |
|---|---|---|---|
lead_id | string | Sí | Identificador del contacto en AES. Se devuelve sin modificar en cada evento de la Interfaz B. Es lo que mantiene unida la conversación con el registro. |
event_id | string | Sí | Único por encargo. Permite reintentos seguros. Un valor repetido debe ignorarse. |
branch_code | string | Sí | Unidad de destino. Determina el número de origen. El catálogo se entrega por implementación. |
city | string | No | Referencia legible, para reportes y contexto de la conversación. |
contact.name | string | Sí | Nombre declarado por el contacto. |
contact.phone_e164 | string | Sí | Formato E.164. Llave principal de contacto en ambas plataformas. |
contact.email | string | No | Presente cuando el contacto lo proporciona. |
contact.language | string | No | Idioma preferente. Por omisión, el del entorno. |
origin | object | No | Procedencia de la captación, para abrir la conversación en contexto. |
brief.intent | enum | No | Intención detectada. Ver Anexo A. |
brief.notes | string | No | Lo que el contacto solicitó, resumido por AES. |
callback_url | string | Sí | Destino de los eventos de la Interfaz B. |
4.3 Respuesta esperada
HTTP/1.1 202 Accepted
Content-Type: application/json
{
"provider_job_id": "prv_77219",
"assigned_number_e164": "+528112345678"
}
Informar el número asignado permite a AES atribuir correctamente los mensajes entrantes de ese contacto, y mantener una sola conversación si más adelante regresa por otro canal.
5. Interfaz B — Eventos de conversación
POST https://omb.cloud/app/api/cai_events.php
Content-Type: application/json
X-CAI-Provider: {provider_code}
X-CAI-Signature: sha256=<hmac_hex>
X-CAI-Timestamp: 1787923271
Un solo endpoint recibe todo lo que el Proveedor devuelve. Está diseñado para escritura en tiempo real, firmado e idempotente, de modo que el Proveedor pueda enviar y reintentar sin riesgo de duplicación.
5.1 conversation.message
Un evento por cada mensaje, en ambos sentidos, conforme ocurre. El registro completo es lo que permite al cliente ver el trabajo del agente tal como sucedió y atribuir con precisión las citas resultantes.
{
"event": "conversation.message",
"event_id": "evt_4b81c07f",
"lead_id": "AES-38-104772",
"provider_job_id": "prv_77219",
"channel": "whatsapp",
"from_number_e164": "+528112345678",
"direction": "outbound",
"author": "agent",
"text": "Buenas tardes María Fernanda, le escribo de...",
"occurred_at": "2026-08-27T14:04:39-06:00"
}
Campos del evento. event y event_id son obligatorios en todos los eventos; el resto según el tipo:
| Campo | Presencia | Descripción |
|---|---|---|
event | Obligatorio | Tipo del evento |
event_id | Obligatorio | Identificador único del evento, hasta 120 caracteres |
lead_id | Opcional | El identificador entregado en el encargo, sin modificar |
provider_job_id | Opcional | El identificador propio del Proveedor |
channel | Opcional | Canal del mensaje; ver A.6 |
from_number_e164 | Opcional | Número de origen en E.164 |
direction | Opcional | inbound o outbound |
author | Opcional | Quién escribió; ver A.3 |
text | Opcional | Texto del mensaje |
occurred_at | Opcional | Cuándo ocurrió, ISO 8601 con huso |
5.2 Eventos de cita
Se envían al agendar, reprogramar o cancelar. AES registra la cita y la refleja en el tablero de la unidad correspondiente.
{
"event": "appointment.booked",
"event_id": "evt_4b93a112",
"lead_id": "AES-38-104772",
"branch_code": "ACME-NORTE",
"scheduled_at": "2026-08-29T11:30:00-06:00",
"service": "consulta_inicial",
"notes": "Prefiere turno matutino.",
"occurred_at": "2026-08-27T14:11:02-06:00"
}
Valores aceptados para event: appointment.booked, appointment.rescheduled, appointment.cancelled.
5.3 job.closed
Se envía cuando la gestión termina sin cita. Permite al cliente retomar por otros medios y evita contacto duplicado hacia la misma persona.
{
"event": "job.closed",
"event_id": "evt_4ba7d290",
"lead_id": "AES-38-104772",
"outcome": "no_answer",
"attempts": 4,
"occurred_at": "2026-08-29T18:00:00-06:00"
}
5.4 Idempotencia y reintentos
| Código | Significado | Acción sugerida |
|---|---|---|
202 | Evento aceptado, o descartado por duplicado | Ninguna |
400 | Esquema inválido | No reintentar. Revisar el cuerpo |
401 | Firma inválida, fuera de ventana, proveedor no reconocido u origen no autorizado | No reintentar. Verificar credencial, reloj y origen dado de alta |
413 | Cuerpo mayor a 256 KB | No reintentar. Reducir el evento |
429 | Tope de peticiones alcanzado | Reintentar después del valor de Retry-After |
5xx | Indisponibilidad temporal | Reintento con retroceso exponencial hasta 24 h |
Cada evento lleva un event_id único (hasta 120 caracteres). AES descarta los repetidos y responde 202 con {"ok": true, "duplicate": true}, de modo que un reintento nunca produce un registro duplicado. En la práctica, cualquier 2xx significa aceptado.
Un lead_id que AES no reconoce no genera error: el evento se acepta con 202 y queda registrado para conciliación entre ambos equipos.
6. Autenticación
Ambas direcciones se firman con HMAC-SHA256 sobre el cuerpo de la petición, con un secreto compartido independiente por dirección. Es el mismo mecanismo que AES opera con sus integraciones de mensajería y pagos.
signature = HMAC_SHA256(secret, timestamp + "." + raw_body)
header = "sha256=" + hex(signature)
6.1 Ejemplo resuelto
Comprueba tu implementación contra estos valores exactos antes de escribir el resto de la integración.
secret cai_test_5f3a9c21b7e04d8a
timestamp 1787923271
body {"event":"conversation.message","event_id":"evt_4b81c07f","lead_id":"AES-38-104772"}
signature = HMAC_SHA256(secret, timestamp + "." + body)
X-CAI-Signature: sha256=a893b6460bbb5063910f16ed0b8bbaa44204ea83d9a0ceaa6ac539e0d7bd9f1a
Lo que se firma es el timestamp, un punto literal, y el cuerpo crudo tal como viaja: sin volver a serializar, sin cambiar espacios, sin reordenar llaves. Ahí es donde casi todas las implementaciones pierden tiempo.
| Elemento | Definición |
|---|---|
| Ventana de validez | 300 segundos, para acotar la exposición a reenvío. |
| Credencial | Emitida por Proveedor y por entorno. Identificada mediante el encabezado X-CAI-Provider. |
| Direcciones de origen | El Proveedor comparte sus IP de salida y AES las registra como origen autorizado. |
| Rotación | Coordinada entre ambos equipos, con ventana de traslape para no interrumpir el servicio. |
| Transporte | TLS 1.2 o superior en ambas direcciones. |
7. Entornos y catálogo de unidades
Cada implementación tiene su propio entorno: un provider_code, un par de credenciales, y un catálogo de valores branch_code con su nombre legible. AES mantiene el catálogo y lo actualiza conforme el cliente abre unidades. El Proveedor asocia cada código a su número de origen.
Como el ruteo viaja con el encargo, una unidad nueva no requiere cambios de integración de ninguno de los dos lados. El Proveedor agrega una línea a su tabla de correspondencia; nada más se mueve.
El catálogo, las credenciales y las direcciones autorizadas se entregan en el anexo privado que acompaña a esta especificación en cada implementación.
Junto con las credenciales de producción se entrega un par de credenciales de ensayo: apuntan a las mismas URLs y usan el mismo esquema de firma, pero sus datos aterrizan en un espacio de pruebas aislado. Todo lo descrito en este documento puede ejercitarse de extremo a extremo con ellas antes de tocar un dato real, incluida la recepción de un encargo de muestra emitido por AES.
8. Alcance de la versión 1.0
La primera versión se concentra en lo que produce resultado desde el día uno: alcanzar al contacto, sostener la conversación y cerrar la cita. Mantenerla acotada permite que ambas partes lleguen a producción rápido y con bajo riesgo.
8.1 Incluido
- Entrega en tiempo real de contactos desde todos los canales digitales.
- Ruteo por unidad, resuelto por AES y entregado con cada encargo.
- Registro de la conversación completa, en ambos sentidos.
- Citas agendadas, reprogramadas y canceladas.
- Resultados con motivo, para coordinar el seguimiento.
- Atribución de cada resultado al código del Proveedor.
8.2 Previsto para versiones posteriores
- Canales adicionales, conforme se validen los resultados en los ya activos.
- Disponibilidad por unidad, para que el agente ofrezca horarios ya confirmados.
- Eventos posteriores a la cita, asistencia y seguimiento, para cerrar el ciclo de medición.
- Reportes ampliados, según lo que ambos equipos identifiquen como útil en operación.
8.3 Lo que no forma parte de esta interfaz
CAI es una interfaz de empuje en ambas direcciones y no expone endpoints de consulta. Las cifras de operación que un Proveedor necesita para su propia reportería las entrega AES con la periodicidad acordada, como se describe en la sección 9.
En sectores regulados, los registros que viven en el sistema de operación del cliente — expedientes clínicos, historiales financieros, documentos de caso — quedan fuera de esta interfaz, ya que no intervienen en el agendado de una cita. Cuando algún dato puntual sea genuinamente necesario para una conversación, se evalúa caso por caso con el cliente.
9. Reportería y datos personales
9.1 Reportería
AES entrega al Proveedor un reporte periódico de su propia operación: encargos recibidos, tiempo de primer contacto, conversaciones sostenidas, citas generadas y resultados. La periodicidad y los campos se acuerdan entre ambos equipos.
Como lo construye AES, el reporte se calcula sobre la misma base que ve el cliente. La medición del servicio y la del cliente siempre coinciden, y no hay conciliación de cifras entre plataformas.
9.2 Datos personales
El Proveedor actúa como encargado del tratamiento por cuenta del cliente: utiliza la información para la finalidad de esta interfaz, no la transfiere a terceros, no la emplea para ningún otro fin incluido el entrenamiento de modelos, y la elimina al concluir la relación contractual.
AES conserva el registro completo de cada conversación como parte de sus obligaciones de resguardo hacia el cliente. Eso además garantiza continuidad de servicio ante cualquier incidencia en cualquiera de las dos plataformas.
10. Niveles de servicio
Objetivos de referencia. Se ajustan por implementación contra el modelo de operación real del Proveedor.
| Concepto | Objetivo |
|---|---|
| Primer contacto | Dentro de los 5 minutos de recibido el encargo, en horario de operación. |
| Entrega de mensajes | Dentro de los 60 segundos de ocurrido cada mensaje. |
| Entrega de citas | Al momento de confirmar con el contacto. |
| Respuesta síncrona en web chat | Menos de 5 segundos. AES mantiene una respuesta de continuidad para que ningún contacto quede sin atención si el servicio no está disponible. |
| Reintentos | Retroceso exponencial hasta 24 horas de cualquiera de los dos lados. |
| Disponibilidad del endpoint | 99.5% mensual, en ambas direcciones. |
11. Incorporación como Proveedor
- Confirmar el esquema de esta especificación.
- Entregar la documentación del endpoint de encargos y las IP de salida.
- Entregar los números o identidades de origen disponibles por región.
- Intercambiar secretos en el entorno de pruebas.
- Ejecutar pruebas de extremo a extremo contra un entorno de pruebas emitido por AES.
- Piloto en una sola unidad, durante dos semanas.
- Habilitación del resto de las unidades.
Pilotear en una unidad permite a ambos equipos ajustar guion, tiempos y calidad de datos con volumen controlado antes de abrir el resto.
12. Control de versiones
Este documento describe la versión 1.0. Pueden agregarse campos nuevos sin previo aviso y los campos no reconocidos deben ignorarse. Ningún campo se elimina ni cambia de significado dentro de la misma versión mayor. Las ampliaciones de alcance se acuerdan entre ambos equipos y dan lugar a una nueva versión.
| Versión | Fecha | Cambios |
|---|---|---|
1.0 | 2026-08-27 | Versión inicial publicada. |
Anexo A — Enumeraciones
A.1 origin.channel
landing_form | contact_form | webchat | whatsapp_button | phone | referral
A.2 brief.intent
book_appointment | pricing_information | service_information |
reschedule | follow_up | other
A.3 author
agent Agente conversacional del Proveedor
contact La persona contactada
human Operador humano del Proveedor
A.4 outcome
| Valor | Significado |
|---|---|
no_answer | No respondió tras los intentos configurados |
not_interested | Manifestó no tener interés |
wrong_number | El número no corresponde al contacto |
callback_later | Solicitó ser contactado en otro momento |
opted_out | Pidió no ser contactado nuevamente |
A.5 Formatos
| Tipo | Formato | Ejemplo |
|---|---|---|
| Teléfono | E.164 | +5218112345678 |
| Fecha y hora | ISO 8601 con huso | 2026-08-27T14:02:11-06:00 |
| Idioma | BCP 47 | es-MX |
| Codificación | UTF-8 | application/json |
A.6 channel y direction (Interfaz B)
channel: whatsapp | webchat | sms | phone | email
direction: inbound | outbound
Contacto
Para incorporarse como Proveedor, o para dudas sobre esta especificación, escribir a developers@omb.cloud.