Conversational Agent Interface (CAI)

La interfaz estándar de AES para incorporar un proveedor externo de agente conversacional a los canales digitales de un cliente, con AES como sistema de registro.

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

ResponsabilidadAESProveedor
Captación del contactoSí—
Resolución de la unidad de destinoSí—
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ónSí—
Seguimiento comercial posteriorSí—

2.1 Interfaces

IdDirecciónMétodoPropósito
AAES → ProveedorPOSTEntrega de encargos de contacto
BProveedor → AESPOSTRetorno 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

CampoTipoOblig.Descripción
lead_idstringSí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_idstringSíÚnico por encargo. Permite reintentos seguros. Un valor repetido debe ignorarse.
branch_codestringSíUnidad de destino. Determina el número de origen. El catálogo se entrega por implementación.
citystringNoReferencia legible, para reportes y contexto de la conversación.
contact.namestringSíNombre declarado por el contacto.
contact.phone_e164stringSíFormato E.164. Llave principal de contacto en ambas plataformas.
contact.emailstringNoPresente cuando el contacto lo proporciona.
contact.languagestringNoIdioma preferente. Por omisión, el del entorno.
originobjectNoProcedencia de la captación, para abrir la conversación en contexto.
brief.intentenumNoIntención detectada. Ver Anexo A.
brief.notesstringNoLo que el contacto solicitó, resumido por AES.
callback_urlstringSí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:

CampoPresenciaDescripción
eventObligatorioTipo del evento
event_idObligatorioIdentificador único del evento, hasta 120 caracteres
lead_idOpcionalEl identificador entregado en el encargo, sin modificar
provider_job_idOpcionalEl identificador propio del Proveedor
channelOpcionalCanal del mensaje; ver A.6
from_number_e164OpcionalNúmero de origen en E.164
directionOpcionalinbound o outbound
authorOpcionalQuién escribió; ver A.3
textOpcionalTexto del mensaje
occurred_atOpcionalCuá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ódigoSignificadoAcción sugerida
202Evento aceptado, o descartado por duplicadoNinguna
400Esquema inválidoNo reintentar. Revisar el cuerpo
401Firma inválida, fuera de ventana, proveedor no reconocido u origen no autorizadoNo reintentar. Verificar credencial, reloj y origen dado de alta
413Cuerpo mayor a 256 KBNo reintentar. Reducir el evento
429Tope de peticiones alcanzadoReintentar después del valor de Retry-After
5xxIndisponibilidad temporalReintento 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.

ElementoDefinición
Ventana de validez300 segundos, para acotar la exposición a reenvío.
CredencialEmitida por Proveedor y por entorno. Identificada mediante el encabezado X-CAI-Provider.
Direcciones de origenEl Proveedor comparte sus IP de salida y AES las registra como origen autorizado.
RotaciónCoordinada entre ambos equipos, con ventana de traslape para no interrumpir el servicio.
TransporteTLS 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.

ConceptoObjetivo
Primer contactoDentro de los 5 minutos de recibido el encargo, en horario de operación.
Entrega de mensajesDentro de los 60 segundos de ocurrido cada mensaje.
Entrega de citasAl momento de confirmar con el contacto.
Respuesta síncrona en web chatMenos de 5 segundos. AES mantiene una respuesta de continuidad para que ningún contacto quede sin atención si el servicio no está disponible.
ReintentosRetroceso exponencial hasta 24 horas de cualquiera de los dos lados.
Disponibilidad del endpoint99.5% mensual, en ambas direcciones.

11. Incorporación como Proveedor

  1. Confirmar el esquema de esta especificación.
  2. Entregar la documentación del endpoint de encargos y las IP de salida.
  3. Entregar los números o identidades de origen disponibles por región.
  4. Intercambiar secretos en el entorno de pruebas.
  5. Ejecutar pruebas de extremo a extremo contra un entorno de pruebas emitido por AES.
  6. Piloto en una sola unidad, durante dos semanas.
  7. 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ónFechaCambios
1.02026-08-27Versió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

ValorSignificado
no_answerNo respondió tras los intentos configurados
not_interestedManifestó no tener interés
wrong_numberEl número no corresponde al contacto
callback_laterSolicitó ser contactado en otro momento
opted_outPidió no ser contactado nuevamente

A.5 Formatos

TipoFormatoEjemplo
TeléfonoE.164+5218112345678
Fecha y horaISO 8601 con huso2026-08-27T14:02:11-06:00
IdiomaBCP 47es-MX
CodificaciónUTF-8application/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.