
Tu agente, conectado a tu plataforma
Integra el conocimiento, las conversaciones y las acciones de Be Agent con los sistemas que utiliza tu negocio.
Conecta tu plataforma
Login, workspace y permisos con Be Agent Connect.
Sincroniza tus datos
Contactos, oportunidades, conversaciones, citas y tareas.
Conversa y ejecuta acciones
Mensajes naturales, solicitudes y resultados confirmados.
Primeros pasos
Construye sobre Be Agent
Conecta tu CRM, gestor de contenido o herramienta de redes sociales con los datos de tu workspace. La API REST v1 permite consultar agentes, contactos, oportunidades, conversaciones, citas y tareas; crear y actualizar contactos; registrar webhooks; invocar agentes publicados y ejecutar o recibir solicitudes de acciones.
Para tu propio servidor, crea una clave en Ajustes → API e integraciones. Para una plataforma con varios clientes, registra una aplicación y utiliza Be Agent Connect: cada cliente inicia sesión, elige su workspace y autoriza los permisos.
Los conectores específicos de plataformas externas, la publicación en redes, la importación de contenido y la publicación de agentes por API son futuras ampliaciones. La invocación de agentes publicados y el intercambio de acciones sí forman parte de v1. Las respuestas no incluyen secretos de canales ni la configuración interna de los agentes.
La URL base de producción es https://agents.begraffic.com; la API REST utiliza https://agents.begraffic.com/api/v1. Para pruebas locales, sustituye únicamente el origen por el de tu entorno de desarrollo. JSON y HTTPS son obligatorios en producción. Esta documentación describe la implementación; la disponibilidad en tu entorno depende del despliegue y de la configuración operativa.
Primeros pasos
Tu primera integración
1. Decide dónde deben quedar los datos: ejecuta acciones entrantes para trabajar con los contactos, agenda y tareas de Be Agent; utiliza un proveedor de acciones para operar sobre los datos de tu plataforma.
2. Autoriza el workspace mediante una clave de servidor o Be Agent Connect. Comprueba /me, conserva el workspace_id y verifica los scopes concedidos. 3. Consulta el catálogo del agente publicado para conocer acciones habilitadas y aprobaciones.
4. Para delegar, registra un webhook firmado, configura el proveedor y envía el primer mensaje natural. 5. Procesa solicitudes, confirma resultados y entrega reply mediante tu canal. Antes de producción, prueba duplicados, revocación y resultados inciertos.
const headers = { Authorization: `Bearer ${token}` };
const response = await fetch('https://agents.begraffic.com/api/v1/me', { headers });
if (!response.ok) throw new Error(`Conexión no disponible: ${response.status}`);
const { data: workspace } = await response.json();
// Conserva workspace.workspace_id y workspace.scopes en TU servidor.Primeros pasos
Qué puedes integrar
Disponible describe el contrato implementado; verifica que tu entorno lo tenga desplegado. Plataforma externa significa que tu sistema proporciona la capacidad y utiliza Be Agent para razonar. No existe un conector automático por registrar una aplicación.
| Capacidad | Disponibilidad | Cómo integrarla |
|---|---|---|
| Conexión y workspace | Disponible | OAuth, claves y /me |
| Agentes publicados y acciones | Disponible | Catálogo, runs y resultados |
| Contactos | Disponible | Lectura, creación y actualización |
| Leads, citas y tareas | Disponible | Lectura y acciones habilitadas |
| Conversaciones locales | Disponible | Metadatos y último mensaje |
| Historial completo y adjuntos | Plataforma externa | Tu CRM conserva y consulta los mensajes |
| WhatsApp, SMS, Telegram y correo | Plataforma externa | Tu backend recibe y entrega las respuestas |
| Llamadas y notas de voz | Plataforma externa | Transcripción entrante y síntesis de reply |
| Marca y conocimiento del negocio | Configuración del agente | Fuentes y comportamiento desde la ficha |
| Envío WhatsApp como acción del agente | No disponible | Las tres acciones WhatsApp del catálogo siguen deshabilitadas |
Operación
Derivaciones humanas y aprendizaje del dueño
En Agentes → Derivaciones, añade destinos humanos con persona responsable, condición, horario y respuesta fuera de horario. En mensajes, la IA se pausa y se asigna una tarea; la persona acepta desde la sección de solicitudes y contesta desde la bandeja. Una devolución de llamada es una solicitud pendiente de aceptación del equipo, no una reserva ni una llamada automática.
Activa Consultar al dueño cuando falte conocimiento y prepara su canal en Ajustes → Operación → Atención humana. El panel funciona sin mensajería externa. Telegram requiere conectar y confirmar la cuenta desde el bot oficial; WhatsApp requiere verificar el destino con un código. Ambos necesitan configuración del servidor; solo el dueño configurado y activo puede confirmar respuestas.
La consulta conserva pregunta y contexto. El dueño responde desde el panel, respondiendo al aviso recibido o con R seguido del identificador de consulta y su respuesta. Cuando el aprendizaje está activado, su confirmación se guarda en una fuente de conocimiento del agente; se entrega al cliente si todavía espera y la ventana de mensajería lo permite. Las pruebas no envían avisos externos y separan el conocimiento de ensayo del de producción.
Para Telegram, instala un bot en el servidor con TELEGRAM_BOT_TOKEN y TELEGRAM_WEBHOOK_SECRET y registra su webhook HTTPS en /api/webhooks/telegram con ese secret_token y los eventos message y callback_query. El dueño pulsa Conectar Telegram en ajustes, abre el bot oficial, pulsa Iniciar y confirma su cuenta en Be Agent. El enlace es temporal y de un solo uso. Cada miembro puede conectar su propio chat desde las solicitudes del agente; cada consulta conserva negocio, persona y referencia. Para WhatsApp, utiliza una conexión activa del negocio; el dueño inicia el chat para abrir la ventana de 24 horas o configura una plantilla aprobada de Meta con un parámetro de cuerpo.
La transferencia telefónica usa la herramienta nativa transfer_to_number en líneas Twilio o SIP compatibles. La prueba de micrófono del navegador no conecta con un teléfono. La consulta al dueño y las solicitudes de devolución de llamada aquí descritas funcionan en conversaciones por mensajes; no se exponen a herramientas de voz sin una conversación verificada.
Si caduca la consulta, falla un envío o una persona toma el control, la IA no reanuda automáticamente la conversación. Un envío ambiguo queda sin confirmar y no se reintenta automáticamente. El proceso programado /api/internal/integrations/tick debe estar activo para los envíos pendientes y la caducidad.
Conexión
Claves, permisos y caducidad
Un propietario o administrador crea una clave con nombre, permisos y caducidad de 1 a 90 días. El secreto bga_… se muestra una vez y se almacena únicamente como hash en Be Agent. Guárdalo en tu servidor; nunca en el navegador, una URL o un repositorio.
Incluye Authorization: Bearer <token>. Cada credencial queda ligada a un workspace; un parámetro enviado por el consumidor no cambia esa organización. La revocación, la caducidad o la pérdida del rol de administrador bloquean su acceso.
Permisos disponibles: workspace:read, agents:read, contacts:read, contacts:write, leads:read, conversations:read, calendar:read, tasks:read, webhooks:manage, agents:invoke, actions:execute, actions:manage, actions:results, actions:approve. Solicita solo los necesarios. La gestión de webhooks requiere webhooks:manage; recuperar el recurso de un evento requiere además su permiso de lectura.
GET /api/v1/me requiere workspace:read y devuelve data.workspace_id, name, timezone, scopes y connection_id. Permite comprobar la conexión antes de iniciar la sincronización. Las cookies del panel no autentican la API pública.
curl https://agents.begraffic.com/api/v1/me \ -H "Authorization: Bearer $BE_AGENT_TOKEN"
Conexión
Referencia de permisos
Cada petición exige su permiso específico. agents:invoke no concede actions:execute; contacts:write no autoriza las acciones de un agente. La conexión OAuth no amplía sus permisos al renovar: vuelve a autorizar si necesitas otros.
Para lectura y sincronización solicita solo los scopes de los recursos necesarios. Para conversación delegada solicita agents:invoke, agents:read, actions:manage, actions:results y webhooks:manage. Añade actions:approve solo al flujo de aprobación humana.
| Permiso | Autoriza |
|---|---|
| workspace:read | Consultar workspace |
| agents:read | Consultar agentes |
| contacts:read | Consultar contactos |
| contacts:write | Crear y actualizar contactos |
| leads:read | Consultar oportunidades |
| conversations:read | Consultar conversaciones |
| calendar:read | Consultar citas |
| tasks:read | Consultar tareas |
| webhooks:manage | Administrar webhooks de la conexión |
| agents:invoke | Conversar con agentes publicados mediante API |
| actions:execute | Ejecutar acciones habilitadas en Be Agent |
| actions:manage | Configurar acciones delegadas a esta plataforma |
| actions:results | Comunicar resultados de acciones delegadas |
| actions:approve | Aprobar acciones delegadas desde un flujo humano |
Conexión
Estado de la conexión y del agente
Consulta /me tras autorizar, al abrir la configuración y cuando el usuario pulse «Actualizar estado». Devuelve workspace_id, name, timezone, scopes y connection_id; no devuelve integraciones de mensajería, plan, saldo ni estado del proveedor de canales.
Muestra por separado la autorización guardada, el agente publicado y activo, las acciones habilitadas y el proveedor de acciones registrado. Una autorización válida no confirma que tu receptor webhook esté operativo.
Si una consulta falla muestra «Estado no disponible» y permite reintentar. Una respuesta 401 exige renovar si corresponde o reconectar; 403 exige revisar permisos. No conviertas estos errores en «No configurado».
/api/v1/meworkspace:read/api/v1/agents/{id}agents:read/api/v1/agents/{id}/actionsagents:read/api/v1/agents/{id}/action-provideractions:manageConexión
Recursos de marca y botón de conexión


Logotipo para fondo oscuro

Símbolo para fondo claro

Símbolo para fondo oscuro
Colores de la marca
Violeta Agent
#6D3CE8Color principal y botón de conexión.
Azul respuesta
#3D7BFAAcento secundario.
Ámbar acción
#FFB547Acento puntual.
Tinta
#18181BTexto sobre fondo claro.
Blanco
#FFFFFFLogotipo y texto sobre fondo oscuro.
Así se presenta la conexión
Vista de ejemplo. Tu aplicación conecta el botón con la ruta de su servidor que inicia Be Agent Connect.
Descarga el kit oficial para mostrar Be Agent en tu plataforma: logotipos y símbolos SVG y PNG transparentes, colores, reglas de composición, tokens de diseño y estilos del botón. Guía independiente: https://agents.begraffic.com/docs/be-agent-brand.md.
Escribe Be Agent, con espacio. En el logotipo, «Be» utiliza peso regular y «Agent» negrita. La firma es «por BeGraffic» y la promesa es «Conversa. Y resuelve.».
Conserva el lienzo completo: incluye un margen libre de un cuarto del ancho del símbolo. El símbolo visible mide como mínimo 16 px solo o 24 px junto al nombre; en impresión, 6 mm solo o 10 mm junto al nombre.
Usa la versión de color sobre fondos claros y la blanca sobre fondos oscuros. No deformes, recortes, gires ni recolorees el logotipo; evita sombras, degradados y fotografías sin contraste.
La tipografía de marca es Google Sans (400, 500, 600 y 700). JetBrains Mono se usa para cifras y código. Los SVG del logotipo contienen texto sin trazar: utiliza los PNG transparentes si no tienes Google Sans; para imprenta, traza el texto. Los símbolos SVG no dependen de fuentes. El kit no incluye archivos de fuentes.
Prioriza fondos claros y neutros: proporción orientativa de 60 % neutros, 25 % violeta, 10 % azul y 5 % ámbar. Usa tarjetas de radio 12 px y botones de radio 8 px. Mantén contraste de 4,5:1 para texto normal y 3:1 para texto grande y elementos gráficos.
Habla de forma atenta, precisa y resolutiva. Usa responder, resolver, confirmar y atender. Evita «estimado usuario», «procesando solicitud» e «IA de última generación». Las imágenes muestran conversaciones y personas reales; evita robots y destellos decorativos.
En el catálogo de integraciones muestra el logotipo y una descripción de las capacidades que realmente implementas. Tras autorizar, muestra el workspace conectado, su estado y las opciones para reconectar o desconectar. Usa «Conectado» solo tras la confirmación del servidor; si falta configuración, muestra «Configuración pendiente».
Estos materiales identifican la integración con Be Agent. Registrar una aplicación no implica verificación ni permite presentarla como producto oficial de BeGraffic.
Etiqueta recomendada: «Conectar con Be Agent». Copia los archivos y el CSS a tu dominio. Las rutas /assets/be-agent/ del ejemplo son ilustrativas. La variante clara añade be-agent-connect--outline y utiliza el símbolo de color; la oscura añade be-agent-connect--dark y conserva el símbolo blanco. Mantén una etiqueta visible y un área de clic mínima de 44 px; el CSS incluye hover, foco y disabled.
El botón abre una ruta de TU backend que comprueba la sesión e inicia OAuth con state y PKCE. La presentación por sí sola no completa la autorización. Implementa el callback y consulta el estado confirmado antes de mostrar «Conectado». No incluyas credenciales en el navegador.
<link rel="stylesheet" href="/assets/be-agent/be-agent-connect.css" />
<button type="button" class="be-agent-connect" id="connect-be-agent">
<img class="be-agent-connect__symbol"
src="/assets/be-agent/be-agent-symbol-white.svg" alt="" width="30" height="30" />
<span>Conectar con Be Agent</span>
</button>
<script>
document.querySelector('#connect-be-agent').addEventListener('click', () => {
window.location.assign('/api/be-agent/start'); // Ruta de TU backend.
});
</script>Conexión
Conector oficial de BeCRM
BeCRM forma parte del ecosistema Be. Los clientes conectan su workspace iniciando sesión y autorizando permisos; no necesitan registrar una aplicación ni generar o copiar claves. La aplicación oficial se administra una sola vez por entorno desde la plataforma.
Desde Integraciones → BeCRM, abre https://crm.begraffic.com/dashboard/settings/integrations/be-agent. BeCRM inicia OAuth con state y PKCE desde su servidor. Be Agent muestra la identidad oficial solo cuando coincide con su registro interno; el nombre y el dominio de una aplicación de autoservicio no le conceden esa identidad.
Cada autorización tiene tokens independientes y solo permite el workspace elegido. Autorizar no activa canales ni automatizaciones. En BeCRM debes elegir un agente publicado, las acciones y los canales, y confirmar la prueba firmada del webhook. Puedes revocar tu conexión desde Integraciones → BeCRM o Ajustes → API e integraciones.
Una renovación mantiene la autorización vigente; una nueva autorización puede reiniciar la configuración y requiere revisar qué automatizar. La conexión OAuth no acredita una llamada de voz en tiempo real. Si el conector está pendiente de activación, el equipo Be debe completar su configuración antes de conectar clientes.
Conexión
Be Agent Connect
1. Registra tu aplicación en Ajustes → API e integraciones → Aplicaciones registradas. Introduce un sitio HTTPS, retornos exactos y permisos máximos. Guarda clientId y clientSecret en el servidor. El registro es autoservicio y no implica verificación de la aplicación.
Los retornos deben usar HTTPS; HTTP solo se permite en localhost, 127.0.0.1 o ::1. No se permiten fragmentos, credenciales ni comodines. Puerto, ruta y consulta deben coincidir exactamente.
2. Desde «Conectar con Be Agent», abre una ruta de TU servidor. Valida allí la sesión y el rol de administrador de tu cliente. Genera state impredecible (16–512 caracteres) y PKCE S256. Guarda state, code_verifier y la organización local en una transacción de un solo uso ligada a la sesión, durante un máximo de diez minutos.
3. Redirige a /connect con response_type=code, client_id, redirect_uri, scope, state, code_challenge y code_challenge_method=S256. Be Agent muestra login, selección de workspace y permisos. La selección no cambia el workspace activo del panel. Si el usuario cancela, el callback recibe error=access_denied y state.
4. En tu callback, valida state y consume atómicamente la transacción local. Recomprueba el permiso de administrador local. Canjea el código desde tu servidor con POST /api/oauth/token, client_id, client_secret, grant_type=authorization_code, code, redirect_uri y code_verifier. El código caduca en cinco minutos y solo puede utilizarse una vez.
La respuesta contiene access_token, refresh_token, token_type=Bearer, expires_in, refresh_expires_in, scope, workspace_id y connection_id. El token de acceso dura hasta una hora; la autorización, 90 días. Cifra las credenciales y vincula el workspace recibido exclusivamente a la organización guardada en la transacción local. No envíes tokens al navegador ni registres el callback completo.
5. Renueva desde tu servidor con grant_type=refresh_token, client_id, client_secret y refresh_token. La renovación consume el refresh anterior e invalida el acceso anterior. Serializa renovaciones por conexión y guarda ambos tokens nuevos de forma atómica. Ante código consumido, renovación consumida o respuesta perdida, solicita reconectar.
6. Desconecta con POST /api/oauth/revoke: client_id, client_secret y token (acceso o renovación). También puede desconectar un administrador desde ajustes. Revocar la conexión o desactivar la aplicación bloquea acceso, renovaciones y futuros intentos de webhook. Una petición ya enviada no puede retirarse.
Consulta /.well-known/oauth-authorization-server para descubrir el protocolo. Canje y renovación admiten JSON o formulario URL encoded, sin CORS para aplicaciones sin backend. La pantalla de consentimiento muestra el nombre, dominio del sitio, dominio de retorno, workspace y permisos.
import { randomBytes, createHash } from 'node:crypto';
const state = randomBytes(32).toString('base64url');
const verifier = randomBytes(32).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
// Guarda state, verifier y tu organización local en TU servidor.
const url = new URL('https://agents.begraffic.com/connect');
url.search = new URLSearchParams({
response_type: 'code', client_id: process.env.BE_AGENT_CLIENT_ID,
redirect_uri: 'https://tu-app.com/api/be-agent/callback',
scope: 'workspace:read contacts:read webhooks:manage',
state, code_challenge: challenge, code_challenge_method: 'S256',
}).toString();
// Redirige al usuario a url. No envíes verifier al navegador.Datos y sincronización
Consulta y sincronización
GET /api/v1/{recurso} lista registros con data y next_cursor. Recursos: agents, contacts, leads, conversations, appointments y tasks. GET /api/v1/{recurso}/{id} devuelve { data: registro }. El acceso a IDs de otro workspace devuelve 404.
Paginación: limit de 1 a 100 (50 por defecto), cursor con el ID devuelto en next_cursor. Continúa hasta next_cursor=null, incluso si una página tiene data vacío. El orden es por ID, no por fecha. Registros simulados y eliminados no se publican. Las fechas se representan en ISO 8601 o null.
La importación inicial es opcional y la decide tu aplicación. Usa webhooks para cambios posteriores y una reconciliación periódica para detectar omisiones. La lista no es una instantánea: pueden producirse cambios durante su recorrido. Las conversaciones exponen metadatos y último mensaje, no el historial completo.
let cursor;
do {
const url = new URL('https://agents.begraffic.com/api/v1/contacts');
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const page = await res.json();
await saveByBeAgentId(page.data); // Implementa un upsert en TU servidor.
cursor = page.next_cursor;
} while (cursor);Datos y sincronización
Importar y sincronizar historiales
Tu plataforma puede ofrecer «Importar al conectar» desmarcado inicialmente, «Sincronizar ahora» y «Reanudar». La autorización OAuth no inicia una importación. Importa los seis recursos locales mediante las listas paginadas; conversaciones incluye únicamente metadatos y último mensaje.
No hay endpoint de mensajes completos, correos históricos, grabaciones ni adjuntos en Be Agent v1. Si necesitas el historial WhatsApp/SMS/Telegram/correo, léelo de la plataforma que administra esos canales. No uses /conversations como si contuviera todo el hilo.
Guarda cada página con upsert por organización local + conexión + recurso + id de Be Agent. Persiste el cursor después de confirmar los registros, en la misma transacción local. Reanuda con los mismos parámetros; continúa incluso con data vacío hasta next_cursor=null. No hay filtros por fecha, canal o contacto en estas listas.
Una sincronización nueva empieza sin cursor y reconcilia por ID. El recorrido no es una instantánea: repítelo para recoger cambios concurrentes. No borres datos locales por una ausencia ni envíes notificaciones o respuestas al importar registros históricos. Usa los eventos disponibles para cambios posteriores; no todos los cambios tienen un evento público.
Muestra recurso, progreso, registros guardados, última finalización y errores. Ante 429 respeta Retry-After; ante fallo del worker reanuda el último punto confirmado. No bloquees el callback OAuth mientras termina la importación.
Datos y sincronización
Consultar agentes
La lectura incluye agentes en borrador, activos o pausados; expone identidad básica, publishedVersion (número) y publishedVersionId (ID de la versión publicada); no incluye prompts, voces, documentos ni configuración privada. El estado de las acciones se consulta en /agents/{id}/actions. Crear, editar o publicar agentes por API no forma parte de v1.
Respuesta de lista: { data: [...], next_cursor: ID o null }. Respuesta individual: { data: registro }. Fechas ISO 8601 o null; campos ausentes null. Se excluyen registros simulados y eliminados. Los IDs de otra organización no son accesibles.
/api/v1/agentsagents:read/api/v1/agents/{id}agents:read| Campos publicados |
|---|
| id |
| name |
| status |
| publishedVersion |
| publishedVersionId |
| createdAt |
| updatedAt |
Datos y sincronización
Leads y oportunidades
Consulta oportunidades locales. Crear y actualizar se realiza mediante createLead y updateLead cuando estén habilitadas en el agente; no hay POST/PATCH directo de leads. Si delegas estas acciones, el recurso se guarda en tu CRM externo y no aparece automáticamente en las listas locales.
Respuesta de lista: { data: [...], next_cursor: ID o null }. Respuesta individual: { data: registro }. Fechas ISO 8601 o null; campos ausentes null. Se excluyen registros simulados y eliminados. Los IDs de otra organización no son accesibles.
/api/v1/leadsleads:read/api/v1/leads/{id}leads:read| Campos publicados |
|---|
| id |
| contactId |
| title |
| stage |
| score |
| value |
| source |
| createdAt |
| updatedAt |
Datos y sincronización
Conversaciones
Incluye contactId, agentId, channel, state y lastMessage. No hay ruta pública para enumerar todos los mensajes ni para enviar una respuesta al canal. context.conversation_id de un run externo pertenece a tu plataforma y no crea automáticamente una conversación local.
Respuesta de lista: { data: [...], next_cursor: ID o null }. Respuesta individual: { data: registro }. Fechas ISO 8601 o null; campos ausentes null. Se excluyen registros simulados y eliminados. Los IDs de otra organización no son accesibles.
/api/v1/conversationsconversations:read/api/v1/conversations/{id}conversations:read| Campos publicados |
|---|
| id |
| contactId |
| agentId |
| channel |
| state |
| lastMessage |
| lastMessageAt |
| createdAt |
| updatedAt |
Datos y sincronización
Agenda y citas
Consulta citas locales. checkAvailability, bookAppointment, rescheduleAppointment y cancelAppointment permiten actuar mediante el agente; no hay escritura directa del recurso por REST. Las acciones interpretan fecha y hora en la zona del workspace. Para tu calendario externo configura un proveedor y valida disponibilidad antes de confirmar.
Respuesta de lista: { data: [...], next_cursor: ID o null }. Respuesta individual: { data: registro }. Fechas ISO 8601 o null; campos ausentes null. Se excluyen registros simulados y eliminados. Los IDs de otra organización no son accesibles.
/api/v1/appointmentscalendar:read/api/v1/appointments/{id}calendar:read| Campos publicados |
|---|
| id |
| contactId |
| title |
| status |
| startAt |
| endAt |
| timezone |
| createdAt |
| updatedAt |
Datos y sincronización
Tareas y seguimiento
Consulta tareas locales. createTask registra seguimiento y notifyOwner crea una tarea interna prioritaria. No equivalen a enviar un correo, SMS o notificación externa. Una plataforma delegada implementa su propio seguimiento y devuelve el ID confirmado.
Respuesta de lista: { data: [...], next_cursor: ID o null }. Respuesta individual: { data: registro }. Fechas ISO 8601 o null; campos ausentes null. Se excluyen registros simulados y eliminados. Los IDs de otra organización no son accesibles.
/api/v1/taskstasks:read/api/v1/tasks/{id}tasks:read| Campos publicados |
|---|
| id |
| contactId |
| title |
| status |
| dueAt |
| createdAt |
| updatedAt |
Datos y sincronización
Crear y actualizar contactos
POST /api/v1/contacts crea un contacto (201). PATCH /api/v1/contacts/{id} actualiza exclusivamente los campos enviados (200). Requieren contacts:write. Campos admitidos: name, email, phone, company, tags, notes. Al crear, name es obligatorio; phone usa formato E.164 (+ y 7–15 dígitos). El cuerpo admite hasta 16 KB. Los campos desconocidos se rechazan.
Idempotency-Key es obligatorio, de 16 a 128 caracteres: letras, números, guion o guion bajo. Repite la misma clave, operación y cuerpo ante una respuesta perdida; devuelve el resultado guardado sin duplicar el contacto. Una clave reutilizada con otros datos devuelve 409. Se conserva el resultado hasta la limpieza operativa de la organización.
El ámbito de idempotencia es el workspace y su clave o conexión; una renovación OAuth conserva ese ámbito. Una nueva clave manual tiene otro ámbito. El correo o teléfono no deduplican automáticamente: guarda los IDs y utiliza PATCH para sincronizar registros existentes. tags sustituye la lista completa; no hay borrado por API ni envío de mensajes en v1.
/api/v1/contactscontacts:read/api/v1/contacts/{id}contacts:read/api/v1/contactscontacts:write · Idempotency-Key/api/v1/contacts/{id}contacts:write · Idempotency-Key| Campo | Formato de escritura |
|---|---|
| name | Texto de 1 a 120 caracteres; obligatorio al crear |
| Correo válido; máximo 254 caracteres | |
| phone | E.164: + seguido de 7 a 15 dígitos |
| company | Texto; máximo 120 caracteres |
| tags | Hasta 20 textos de 1 a 40 caracteres; reemplaza la lista |
| notes | Texto; máximo 4000 caracteres |
curl -X POST https://agents.begraffic.com/api/v1/contacts \
-H "Authorization: Bearer $BE_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: crm-contacto-20261002-001" \
-d '{"name":"Ana Pérez","email":"ana@example.com","tags":["CRM externo"]}'Agentes y acciones
Catálogo y acciones entrantes
GET /api/v1/actions y GET /api/v1/agents/{id}/actions requieren agents:read. Cada acción publica id, descripción, riesgo, mutates, available, can_delegate, input_schema y external_result_schema. El catálogo del agente muestra enabled, requires_approval y external_provider de su versión publicada. Hay 12 acciones implementadas; las tres acciones de WhatsApp siguen no disponibles y no se ofrecen al modelo.
POST /api/v1/agents/{id}/actions/{actionId} requiere actions:execute e Idempotency-Key. Envía input y, si corresponde, contact_id y conversation_id de Be Agent. Ejecuta la acción dentro de Be Agent: CRM, agenda, tareas y conocimiento locales. El agente debe estar publicado y activo; la acción debe estar habilitada en esa versión. Nunca acepta organization_id ni una aprobación en el cuerpo.
La respuesta 202 contiene data.id, status y result. status puede ser processing, success, failed, pending_approval, rejected, expired o unknown_outcome. Consulta GET /api/v1/action-executions/{id} con actions:execute. result conserva toolName, input, output, summary y status del ejecutor. pending_approval deja una propuesta en Supervisión; la API no evita esa aprobación. La respuesta incluye approval_id y el estado consultado se actualiza tras la decisión del equipo. Las ejecuciones se muestran también en Supervisión.
actions:execute autoriza las acciones habilitadas del agente, incluidas escrituras; concédelo expresamente. Los permisos contacts:write o agents:read por sí solos no permiten ejecutarlas. Los IDs locales deben pertenecer al workspace y a la persona verificada; IDs de otras organizaciones devuelven 404 o una acción failed sin efecto.
transferCall significa dejar la conversación pendiente de atención humana y parar la IA; no transfiere una llamada telefónica. notifyOwner crea una tarea interna prioritaria; no envía correo ni SMS. Las acciones de agenda requieren fechas AAAA-MM-DD y horas HH:mm interpretadas en la zona horaria del workspace.
Reutiliza la misma clave y cuerpo tras perder una respuesta. Un resultado processing o unknown_outcome no autoriza repetir con otra clave. Las claves se conservan por workspace y conexión, incluso al renovar OAuth. 409 idempotency_conflict indica una clave reutilizada para otra solicitud.
/api/v1/actionsagents:read/api/v1/agents/{id}/actionsagents:read/api/v1/agents/{id}/actions/{actionId}actions:execute · Idempotency-Key/api/v1/action-executions/{id}actions:executecurl -X POST https://agents.begraffic.com/api/v1/agents/AGENT_ID/actions/createTask \
-H "Authorization: Bearer $BE_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: tarea-seguimiento-20261002-001" \
-d '{"contact_id":"CONTACT_ID_LOCAL","input":{"title":"Revisar solicitud","priority":"high"}}'Agentes y acciones
Invocar al agente con datos de tu plataforma
Para que las acciones se ejecuten en tu propia plataforma, registra un webhook de esta misma conexión suscrito a agent.action.requested y agent.run.completed. Configura PUT /api/v1/agents/{id}/action-provider con webhook_id y actions. Requiere actions:manage y webhooks:manage. GET consulta el proveedor y DELETE lo revoca. Solo se delegan las 11 acciones implementadas distintas de searchKnowledge: el conocimiento del agente se consulta dentro de Be Agent.
El proveedor se configura por workspace, conexión y agente. Una conexión no puede recibir ni confirmar las solicitudes de otra. Habilita las acciones en la ficha y publica el agente antes de invocarlo. Registrar un proveedor no activa herramientas ni elimina aprobaciones. Una renovación OAuth conserva el proveedor; una nueva clave manual constituye otra conexión.
POST /api/v1/agents/{id}/runs requiere agents:invoke e Idempotency-Key. Envía text con las palabras naturales del cliente y context.conversation_id de TU plataforma. Puedes incluir contact_id, contact_name, channel (text, call, voice_note, email, comment) y resources. Las llamadas y notas de voz se envían como transcripción: esta API no transporta audio, telefonía ni WhatsApp.
resources admite hasta 20 referencias verificadas de tu plataforma: type lead o appointment, id, title y opcionalmente status, date, time. contact_id y estos IDs son externos: no se traducen a recursos locales. Incluye las referencias pertinentes en cada turno. Las oportunidades o citas creadas durante ese turno también pueden utilizarse tras el resultado confirmado. La plataforma receptora debe verificar workspace, contacto, pertenencia de recursos, permisos y reglas de negocio antes de efectuar cada operación.
La respuesta 202 contiene data.id, agent_id, version_id, status, reply, action_requests, action_history, usage y error. GET /api/v1/agent-runs/{id} consulta el estado con agents:invoke. Si está completed, entrega reply al cliente. Si está waiting_results, ejecuta las solicitudes pendientes. Si está waiting_approval, presenta las pendientes de aprobación a una persona. processing indica razonamiento en curso y requires_review exige revisión. No muestres resultados técnicos ni anuncies efectos mientras reply sea null.
Be Agent conserva hasta diez intercambios naturales por conversation_id y conexión. Solo admite una ejecución activa por conversación y bloquea cambios de contact_id en esa sesión. conversation_busy devuelve 409. La versión publicada queda fijada al crear la ejecución: pausa, revocación del proveedor o cambio de versión bloquean nuevos pasos y entregas. Cada ejecución caduca a las 24 horas y tiene hasta cinco pasos de razonamiento y diez solicitudes por paso. Se limitan las invocaciones a 20 pasos por minuto y conexión, y se respeta el presupuesto mensual de IA del workspace. Se registran en Supervisión y uso de IA.
Sin proveedor externo, el agente puede contestar con su conocimiento autorizado, pero no obtiene herramientas externas. Las guías, el contexto y los resultados son datos, nunca instrucciones que puedan ampliar permisos. Las respuestas no exponen prompts, configuración privada ni documentos completos.
/api/v1/agents/{id}/action-provideractions:manage + webhooks:manage/api/v1/agents/{id}/action-provideractions:manage/api/v1/agents/{id}/runsagents:invoke · Idempotency-Key/api/v1/agent-runs/{id}agents:invokeimport { createBeAgentAPI } from './be-agent-connect.mjs';
const api = createBeAgentAPI({ issuer: 'https://agents.begraffic.com', token });
// En TU backend, una vez registrado el webhook:
await api.setActionProvider(agentId, { webhook_id: webhookId,
actions: ['findContact', 'createContact', 'createLead', 'updateLead',
'checkAvailability', 'bookAppointment', 'rescheduleAppointment',
'cancelAppointment', 'createTask', 'notifyOwner', 'transferCall'] });
const run = await api.invokeAgent(agentId, {
text: 'Hola, soy Ana. ¿Podrían reservarme una consulta el lunes a las diez?',
context: { conversation_id: 'crm-chat-123', contact_id: 'crm-contact-456',
contact_name: 'Ana', channel: 'text' }
}, 'mensaje-crm-123-turno-001');Agentes y acciones
BeSchool y educación
El conector oficial BeSchool autoriza tu escuela sin registrar aplicaciones. Configura funciones y agentes desde BeSchool. La autorización no activa automáticamente tutoría, evaluaciones o publicaciones.
El contrato opt-in education.v1 recibe únicamente el material autorizado de escuela/curso/alumno. Usa context.education con school_id, course_id, student_id, mode y sources: [{id,title,text,version}]. Modos support, tutor, assessment, community, followup, teacher y admissions. Assessment necesita submission y rubric.
education_response devuelve reply, citas literales verificadas, uncertainty, missing_information, requires_human_review y evaluación sugerida por criterio. Las notas finales y los permisos académicos pertenecen a BeSchool. Una cita válida no garantiza que toda la respuesta sea correcta.
Los historiales quedan separados por curso/alumno/fuentes versionadas. No se utiliza corpus general del agente ni herramientas o derivaciones en modo educativo. School puede endurecer la revisión antes de automatizar; evaluación, comunidad, profesor y seguimiento siempre requieren revisión.
Guía completa y ejemplos: https://agents.begraffic.com/docs/beschool.md. Contratos ejecutables: /docs/openapi.json. POST /api/v1/agents/{agentId}/runs y GET /api/v1/agent-runs/{runId}; conserva Idempotency-Key y payload exactos ante timeout.
Agentes y acciones
Las 15 acciones del catálogo
Consulta input_schema y external_result_schema en el catálogo JSON antes de construir una petición. Esta tabla distingue disponibilidad implementada y delegación; la configuración publicada del agente determina además enabled y requires_approval. Un riesgo bajo no elimina la validación de identidad o permisos.
Una acción entrante utiliza IDs locales de Be Agent. Una solicitud delegada utiliza IDs externos verificados en context y resources. No intercambies ambos tipos. El resultado externo describe un efecto confirmado; no basta con repetir la intención del cliente.
| Acción | Uso | Disponible / delegable |
|---|---|---|
| searchKnowledge | Consulta la base de conocimiento del agente para responder con información del negocio. | Sí / No: conocimiento local |
| findContact | Identifica a la persona por teléfono o correo. | Sí / Sí |
| createContact | Registra un contacto o corrige el nombre del contacto de la conversación. | Sí / Sí |
| createLead | Abre una oportunidad a partir de la conversación. | Sí / Sí |
| updateLead | Cambia la etapa o añade una nota de seguimiento a una oportunidad. | Sí / Sí |
| checkAvailability | Consulta los huecos libres de la agenda de esta plataforma. | Sí / Sí |
| bookAppointment | Reserva una cita en la agenda de esta plataforma. | Sí / Sí |
| rescheduleAppointment | Mueve una cita existente a otro horario. | Sí / Sí |
| cancelAppointment | Cancela una cita existente. | Sí / Sí |
| createTask | Deja una tarea de seguimiento al equipo. | Sí / Sí |
| sendWhatsApp | Envía un mensaje al contacto por WhatsApp. | No / No |
| requestWhatsAppCallPermission | Solicita al contacto autorización para llamarle por WhatsApp. | No / No |
| makeWhatsAppCall | Inicia una llamada saliente. Requiere permiso vigente del contacto. | No / No |
| notifyOwner | Crea una tarea interna prioritaria para el equipo. | Sí / Sí |
| transferCall | Deja la conversación pendiente de atención humana y detiene la IA. No transfiere una llamada telefónica. | Sí / Sí |
Agentes y acciones
Ciclo de una conversación delegada
Ejemplo: Ana pregunta por una cita. Envía su mensaje natural, su ID externo y la conversación; el modelo puede solicitar checkAvailability. Tu calendario comprueba el horario y comunica available. Si después solicita bookAppointment, crea la reserva una sola vez por request_id y confirma el ID real de la cita. Be Agent continúa y genera la respuesta al cliente.
Un turno puede necesitar varios ciclos de solicitudes y resultados. No supongas que la primera respuesta 202 contiene un texto final, ni ejecutes acciones esperando solo agent.run.completed. Procesa agent.action.requested y consulta el run para recuperarte de entregas perdidas.
| Estado del run | Qué hace tu plataforma |
|---|---|
| processing | Esperar o consultar; no iniciar otra ejecución de esa conversación |
| waiting_results | Procesar solicitudes autorizadas y confirmar resultados |
| waiting_approval | Solicitar decisión humana; no ejecutar antes de aprobar |
| completed | Entregar reply una vez por run.id |
| requires_review | Revisar la causa y reconciliar efectos inciertos |
| cancelled / expired | Informar el cierre; conservar la auditoría y los efectos completados |
// Resultado de TU calendario: el efecto ya está comprobado.
const nextRun = await api.submitResults(runId, { results: [{
request_id: requestId,
status: 'succeeded',
summary: 'La cita se guardó en el calendario.',
data: { id: 'calendario-cita-1042' }
}] });
// Puede haber nuevas action_requests: continúa el ciclo.
if (nextRun.status === 'completed' && nextRun.reply) {
await deliverOnce(nextRun.id, originalChannel, nextRun.reply);
}Agentes y acciones
Derivación a agentes especialistas
Cada cuenta conserva un agente de entrada. Configura sus destinos y condiciones en Derivación de Be Agent y publica la configuración. El agente puede usar transferToAgent internamente; esta acción no se delega al proveedor externo ni necesita activar otro canal.
agent_id y version_id siempre identifican al agente de entrada. responding_agent_id y responding_version_id identifican al agente que atiende. handoffs contiene from_agent_id, to_agent_id, version_id, reason y summary. Estos campos aparecen en GET /agent-runs/{id} y en agent.run.completed. Para ejecuciones antiguas sin estos campos usa el agente de entrada como responder.
El especialista usa su propia versión publicada y conocimiento, conserva el historial y continúa en el mismo context.conversation_id. Los turnos siguientes mantienen el especialista sin modificar la asignación de la cuenta. Reiniciar una conversación requiere un conversation_id nuevo; conserva la separación por cuenta y canal.
Solo se permiten destinos activos y publicados del mismo workspace incluidos en las reglas del agente que deriva. Se revalidan todos los participantes antes de completar. Los ciclos o el límite de derivaciones requieren revisión. Si cambia una versión durante la conversación derivada, revisa el hilo antes de iniciar una sesión nueva.
Las acciones externas siguen limitadas por el proveedor del agente de entrada y las herramientas habilitadas en el especialista; una derivación no concede acciones adicionales. Conserva la identidad raíz al validar cuenta, conexión y ejecución. Verifica también el estado y versión del especialista antes de enviar al canal. Los resúmenes de derivación son contexto interno; no los publiques al cliente.
BeSocial conserva cuenta, canal y modalidad de revisión/envío. Una derivación entre agentes no equivale a pasar la atención a una persona ni a transferir una llamada telefónica.
Agentes y acciones
Marca y conocimiento del negocio
Configura el resumen de la empresa, servicios, precios confirmados, horarios, preguntas frecuentes y políticas en las fuentes de conocimiento del agente. Su rol, objetivos, personalidad y objeciones comerciales pertenecen a su configuración. Publica los cambios antes de invocar su nueva versión.
searchKnowledge consulta dentro de Be Agent las fuentes autorizadas: no se delega al CRM. Los datos dinámicos del sistema externo se obtienen mediante las acciones disponibles y sus resultados confirmados; un documento estático no garantiza stock o disponibilidad.
GET /me ofrece el nombre y zona horaria del workspace, no un resumen completo de marca. La API no importa documentos ni modifica el conocimiento o la personalidad. No existe una acción genérica para consultar cualquier URL o inventario: un catálogo dinámico especializado requiere ampliar el contrato de herramientas.
Canales externos
WhatsApp, SMS y Telegram
La plataforma conectada conserva sus números, bots, credenciales, consentimiento y reglas de envío. Recibe el mensaje en su propio canal y llama a /agents/{id}/runs con el texto natural y channel: text. El valor channel describe la modalidad; no admite whatsapp, sms ni telegram. Guarda ese proveedor en tu propio registro de conversación.
El agente puede solicitar una acción autorizada en tu plataforma. Confirma los efectos por /results; cuando el run sea completed, entrega reply usando el canal de origen. Mantén una deduplicación independiente para entradas, acciones y envío de respuestas.
Comprueba el estado y las capacidades del canal en tu proveedor antes de entregar la respuesta. OAuth con Be Agent no configura canales ni garantiza entrega. Las reglas de ventana, plantillas, saldo y baja las resuelve la plataforma de mensajería.
sendWhatsApp, requestWhatsAppCallPermission y makeWhatsAppCall no están disponibles ni pueden registrarse como acciones delegadas. No hay rutas Be Agent /messaging/messages, /messaging/channels ni /conversations/{id}/reply.
// TU backend ya verificó el mensaje recibido y su pertenencia al cliente.
const run = await api.invokeAgent(agentId, {
text: incoming.text,
context: { conversation_id: incoming.conversationId,
contact_id: incoming.contactId, channel: 'text' }
}, incoming.operationKey);
if (run.status === 'completed' && run.reply) {
// Implementa entrega idempotente en el proveedor del canal de origen.
await deliverOnce(run.id, incoming.channel, run.reply);
}Canales externos
Llamadas y mensajes de voz
Tu plataforma realiza reconocimiento de voz y envía la transcripción en text con channel: call o voice_note. Be Agent utiliza el mismo contrato de herramientas y resultados que para texto. Tu sistema convierte reply a audio si necesita una respuesta hablada.
Esta API no acepta audio, abre llamadas, transporta sonido en tiempo real ni ofrece un enlace de sesión de voz. La voz configurada en la ficha no se devuelve como audio mediante /runs. La telefonía y el ciclo de escucha, interrupciones y reproducción pertenecen al adaptador externo.
transferCall delegada requiere data.human_control: true después de detener la respuesta automática y dejar la conversación bajo atención humana. No significa transferir una llamada telefónica a un número. El equipo debe aprobar resume-conversation antes de devolver el control al agente.
Agentes y acciones
Derivaciones entre agentes
En Agentes → selecciona el agente → Derivaciones, añade destinos activos y publicados del mismo negocio. Define cuándo derivar y el mensaje que escuchará o leerá el cliente. Guarda, prueba y publica la configuración.
Ejemplo: Recepción deriva a Soporte cuando el cliente solicita resolver un fallo; Soporte deriva a Ventas cuando quiere contratar un plan. El receptor conserva la conversación, la identidad del contacto y un resumen de lo resuelto y pendiente. Continúa con su propio conocimiento y acciones, sin heredar permisos del agente anterior.
En mensajes de WhatsApp se conserva el número original y el agente receptor continúa inmediatamente. Las pruebas de texto y de llamada por guion ejercitan el motor de derivaciones. Las sesiones de voz preparan las transferencias nativas del proveedor con las versiones publicadas y un presupuesto decreciente de saltos.
El límite configurable es de 1 a 5 derivaciones por conversación (3 por defecto). En voz, el último nivel no ofrece más transferencias. Resolver una gestión no termina la llamada automáticamente: primero se pregunta si el cliente necesita algo más.
La atención humana es una acción distinta. Las ejecuciones externas de la API también admiten especialistas autorizados. Conservan agent_id como agente de entrada y exponen responding_agent_id y handoffs para identificar al receptor; consulta «Derivación a agentes especialistas» para el contrato externo y sus límites de permisos.
Agentes y acciones
Resultados, aprobaciones y recuperación
agent.action.requested contiene data.run_id, agent_id, context, id (identificador de solicitud), action, input, status y requires_approval. Verifica la firma sobre el cuerpo original antes de leerlo y deduplica por data.id. Un 2xx al webhook solo confirma recepción; nunca significa que la acción se ejecutó. Puedes consultar action_requests mediante GET del run si una entrega falla.
Después de ejecutar, POST /api/v1/agent-runs/{id}/results con results: [{request_id, status, summary, data}]. Requiere actions:results y agents:invoke. status es succeeded, failed o unknown_outcome; summary es texto confirmado, y data un objeto que debe cumplir external_result_schema al confirmar succeeded. findContact requiere found y, si existe, id; checkAvailability requiere available; transferCall requiere human_control: true. Para recursos creados o modificados devuelve data.id con su identificador externo, de modo que el agente pueda referirse a ellos. Usa succeeded únicamente tras verificar el efecto; failed solo si sabes que no ocurrió. Si se perdió una respuesta después de enviar una operación, usa unknown_outcome y comprueba la plataforma antes de volver a actuar.
El agente continúa cuando todas las solicitudes del paso tienen resultado o rechazo. Las respuestas idénticas pueden reenviarse; otra respuesta para una solicitud ya resuelta devuelve 409 result_conflict. Nunca confirmes otro request_id, otra conexión ni una acción pendiente de aprobación. Conserva un registro duradero en tu plataforma que relacione request_id con efecto y resultado para evitar duplicados incluso ante entregas simultáneas o reinicios.
POST /api/v1/agent-runs/{id}/requests/{requestId}/decision requiere actions:approve y agents:invoke; cuerpo {decision: approve o reject, reason: motivo}. Debe proceder de una decisión humana autenticada en la plataforma. Una aprobación se audita y recién entonces encola la solicitud; un rechazo nunca la ejecuta. No concedas actions:approve a un agente que pueda autoaprobarse.
unknown_outcome congela la ejecución como requires_review. Tras comprobar los efectos, POST /api/v1/agent-runs/{id}/reconcile requiere actions:approve, actions:results y agents:invoke; acepta el mismo formato results con succeeded o failed confirmados. No vuelve a ejecutar operaciones. POST /api/v1/agent-runs/{id}/retry solo reintenta razonamiento sin efectos pendientes ni ambiguos, requiere agents:invoke. También recupera un processing interrumpido tras cinco minutos; no reenvía automáticamente acciones.
Si el modelo intenta repetir una escritura ya completada en el mismo run, se bloquea con repeated_effect. Tras un transferCall confirmado, Be Agent congela esa conversación bajo control humano. POST /api/v1/agent-runs/{id}/resume-conversation, con actions:approve y agents:invoke y cuerpo {decision: approve, reason: motivo}, permite al equipo devolver el control. El receptor debe implementar la atención humana real; no es una transferencia telefónica.
agent.run.completed entrega run_id, agent_id, reply y context al webhook suscrito. Puedes enviar esa respuesta al cliente usando los canales de tu plataforma. Los webhooks de acciones y respuestas son privados de la conexión que invocó al agente; no se difunden a otras integraciones.
Para cerrar un razonamiento bloqueado sin efectos pendientes o ambiguos, POST /api/v1/agent-runs/{id}/close requiere actions:approve y agents:invoke y cuerpo {decision: reject, reason: motivo}. Audita el cierre y devuelve cancelled, liberando la conversación para un turno nuevo. No revierte los efectos completados ni permite cerrar una solicitud pendiente.
El SDK de servidor expone createBeAgentAPI y verifyBeAgentWebhook además de OAuth. No reintenta escrituras automáticamente. Configura los nuevos scopes al conectar: los tokens existentes no ganan permisos al renovarse; pide una nueva autorización si les faltan.
/api/v1/agent-runs/{id}/resultsactions:results + agents:invoke/api/v1/agent-runs/{id}/requests/{requestId}/decisionactions:approve + agents:invoke/api/v1/agent-runs/{id}/reconcileactions:approve + actions:results + agents:invoke/api/v1/agent-runs/{id}/retryagents:invoke/api/v1/agent-runs/{id}/closeactions:approve + agents:invoke/api/v1/agent-runs/{id}/resume-conversationactions:approve + agents:invokeimport { createBeAgentAPI, verifyBeAgentWebhook } from './be-agent-connect.mjs';
const api = createBeAgentAPI({ issuer: 'https://agents.begraffic.com', token });
// body debe ser el cuerpo original sin reformatear; header es Be-Agent-Signature.
const event = verifyBeAgentWebhook(body, header, signingSecret);
if (event.type === 'agent.action.requested') {
const request = event.data;
// TU plataforma implementa autorización, idempotencia duradera y ejecución.
const result = await executeOnce(request.id, request.action, request.input, request.context);
const run = await api.submitResults(request.run_id, { results: [{
request_id: request.id, status: result.status,
summary: result.summary, data: result.data
}] });
if (run.status === 'completed') await sendReplyToCustomer(run.reply);
}Operación
Webhooks firmados
Registra un destino desde ajustes seleccionando una clave con webhooks:manage, o con POST /api/v1/webhooks usando tu token. Envía name, url y events. La respuesta muestra signingSecret una vez; Be Agent guarda el secreto cifrado. GET /api/v1/webhooks lista solo destinos de esa clave o conexión. DELETE /api/v1/webhooks/{id} los desactiva. POST /api/v1/webhooks/{id}/test encola una prueba (202).
Eventos disponibles: contact.created, contact.updated, lead.created, appointment.created, appointment.cancelled, conversation.ended, task.overdue, agent.action.requested, agent.run.completed. integration.test se utiliza para pruebas. Los eventos de contacto cubren altas y cambios desde el panel y la API; los demás corresponden a los eventos de dominio emitidos por la plataforma. Los eventos simulados no se entregan. No hay eventos de llamadas ni publicaciones sociales en esta versión.
Cada POST incluye Be-Agent-Event-Id y Be-Agent-Signature: t=<segundos Unix>,v1=<HMAC SHA-256 hexadecimal>. La firma se calcula sobre timestamp + punto + cuerpo JSON crudo, con signingSecret. Valida la firma en tiempo constante, tolerancia máxima de cinco minutos y el ID del evento antes de procesarlo. No reconstruyas el cuerpo JSON para verificarlo.
El payload contiene id, type, api_version, workspace_id, created_at y data con resource, id y contact_id. Para recuperar los datos actuales utiliza GET /api/v1/{resource}/{id} con el permiso de lectura correspondiente. Un recurso puede haber cambiado o haberse eliminado al consultar.
El receptor debe guardar el ID y su cambio de negocio atómicamente, devolver 2xx rápidamente y procesar trabajo largo en su propia cola. Las entregas pueden repetirse y llegar fuera de orden. Los reintentos conservan el ID y cuerpo, con una firma nueva.
Hay hasta cinco intentos: reintentos tras 1, 2, 4 y 8 minutos para fallos de red, HTTP 408/429 o 5xx. Otros 4xx y las redirecciones son fallos definitivos. Un timeout es un resultado desconocido; el receptor puede haber procesado el evento. Cada intento tiene un timeout de diez segundos.
Se aceptan destinos HTTPS públicos, puerto 443 y resolución IPv4 pública. Se bloquean redes privadas, direcciones especiales y redirecciones. Revocar una clave, desconectar una aplicación o perder el rol de administrador detiene sus intentos futuros. Ajustes muestra hasta 50 entregas recientes; una prueba queda pendiente hasta que el proceso de entregas esté operativo.
/api/v1/webhookswebhooks:manage/api/v1/webhookswebhooks:manage/api/v1/webhooks/{id}webhooks:manage/api/v1/webhooks/{id}/testwebhooks:manageimport { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody, signatureHeader, signingSecret) {
const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(signatureHeader ?? '');
if (!match || Math.abs(Date.now() / 1000 - Number(match[1])) > 300) return false;
const expected = createHmac('sha256', signingSecret)
.update(match[1] + '.').update(rawBody).digest();
const received = Buffer.from(match[2], 'hex');
return received.length === expected.length && timingSafeEqual(received, expected);
}
// Usa el cuerpo crudo, antes de JSON.parse, y deduplica por payload.id.Operación
Errores y límites
La API v1 devuelve { error: { code, message } }. 400: datos inválidos; 401: credencial inválida, revocada o caducada; 403: permiso ausente; 404: recurso no disponible en tu workspace; 405: método no admitido; 409: conflicto de idempotencia; 413: cuerpo demasiado grande; 429: límite temporal; 500/503: fallo o configuración del servidor.
Límite de 120 solicitudes por minuto por clave o conexión; las renovaciones conservan el ámbito. OAuth permite 30 canjes o revocaciones por minuto por client_id. Un 429 incluye Retry-After: 60. Aplica espera progresiva y respeta Retry-After. No repitas escrituras con una nueva clave de idempotencia ante incertidumbre.
OAuth utiliza el formato estándar { error, error_description }: invalid_request, invalid_client, invalid_grant y unsupported_grant_type. Ante invalid_grant solicita reconectar; no repitas un código o refresh token consumido.
Ante 401 intenta renovar una vez si corresponde; si la autorización no está vigente, muestra «Volver a conectar». Ante 403 solicita una autorización que incluya el permiso. No reintentes indefinidamente los errores de configuración.
Operación
Preparación y prueba de la integración
Antes de ofrecer una integración a clientes, confirma el despliegue de las rutas, el dominio HTTPS, los permisos de base de datos y el proceso de entregas. El contrato no garantiza que un canal de WhatsApp o voz esté conectado o que un agente pueda operar; comprueba su configuración por separado.
Comprueba: clave con permisos mínimos, caducidad y revocación; aislamiento entre dos workspaces; administrador con membresía retirada; cancelación; retorno no registrado; state y PKCE incorrectos; doble canje; renovación simultánea; desconexión; repetición de una escritura; firma alterada; destino privado; webhook repetido y receptor caído.
La configuración del servidor y la programación del proceso de entregas están descritas en docs/operations/external-integrations.md del proyecto. No registres secretos, códigos ni payloads completos en logs. Define retención y eliminación de los registros de integración según tu política operativa antes de producción.
Utiliza credenciales solo en tu servidor. Consulta la especificación OpenAPI para los esquemas y valida tu integración en el entorno donde estará desplegada.