AgentBuilderAgentBuilder/API Referencev1
Iniciar sesiónIr al panel →
Documentación

API Reference

La API REST de AgentBuilder permite enviar mensajes de WhatsApp, gestionar conversaciones, sincronizar contactos y recibir notificaciones en tiempo real desde tu CRM o backend. Todas las peticiones se autentican con un Bearer token y respetan los permisos (scopes) que asignes a cada API key.

Antes de empezar necesitas: (1) una API key creada desde el panel y (2) al menos unwa_number conectado a tu workspace. Las claves ak_test_… solo funcionan contra wa_numbers de sandbox y no consumen cuota de tu plan.

Autenticación

Envía tu API key en el header Authorization con el esquema Bearer. Las claves tienen el formato ak_live_… (producción) o ak_test_… (sandbox) y se generan una sola vez desde el panel — guárdalas en un gestor de secretos.

curl https://api.agentbuilder.cloud/v1/public/conversations \
  -H "Authorization: Bearer ak_live_xxxxxxxxxxxxxxxx"

Respuestas de error de autenticación

ParámetroTipoDescripción
401UNAUTHORIZEDToken ausente, inválido, mal formateado o revocado.
403FORBIDDENToken válido pero le falta uno de los scopes requeridos por el endpoint.
403PLAN_FORBIDDENTu plan no incluye acceso a la API pública (Free).

Errores y reintentos

Las respuestas no-2xx tienen siempre este formato:

Response
{
  "error": "QUOTA_EXCEEDED",
  "message": "Quota exceeded: messages.month"
}

Códigos de estado

ParámetroTipoDescripción
400Bad RequestEl cuerpo del request no pasó la validación (campo faltante, tipo incorrecto).
401UnauthorizedAPI key ausente o inválida.
403ForbiddenPermisos insuficientes (scope, plan o recurso de otro tenant).
404Not FoundEl recurso no existe — devolvemos 404 incluso si existiera para otro tenant, para no filtrar existencia.
409ConflictEstado inconsistente (ej: contacto ya existe con otro wa_id).
422UnprocessableRequest semánticamente inválido (ej: enviar a Baileys vía API pública).
429Too Many RequestsRate limit excedido. Incluye header Retry-After.
5xxServer ErrorError interno. Es seguro reintentar con back-off exponencial.
Los 5xx y los 429 son retryable. Recomendamos back-off exponencial con jitter (ej: 1s, 2s, 4s, 8s, 16s) y un máximo de 5 intentos. Los 4xx (excepto 408/429) son terminales: el request es inválido y reintentar no va a cambiar el resultado.

Rate limits

El límite se aplica por API key y depende del plan del tenant. Cada respuesta incluye headers para que puedas ajustar tu cliente sin sondear hasta el 429.

ParámetroTipoDescripción
FreeplanSin acceso a la API pública. Devuelve 403 PLAN_FORBIDDEN.
Starterplan60 requests/min por API key.
Proplan300 requests/min por API key.
Agencyplan~1000 requests/min por API key.

Headers de respuesta

ParámetroTipoDescripción
X-RateLimit-LimitintegerRequests permitidas por minuto en tu plan.
X-RateLimit-RemainingintegerCuántas requests aún quedan en la ventana actual.
X-RateLimit-ResetsecondsSegundos hasta que se resetea la ventana.
Retry-AftersecondsSolo en respuestas 429. Espera al menos este número de segundos antes de reintentar.
Sección

Endpoints

Enviar mensajePOST/v1/public/messages

Encola un mensaje de WhatsApp saliente. Requiere scope messages:send. Solo soporta números conectados vía Cloud API (no Baileys / sandbox).

Cuerpo

ParámetroTipoDescripción
torequeridostringNúmero de WhatsApp del destinatario en formato internacional sin el "+", solo dígitos (ej: 5215512345678).
waNumberIdrequeridostringID del número conectado de tu workspace desde el que se envía. Puedes obtenerlo en el dashboard → Mis bots.
typestringTipo de mensaje. Por ahora solo text.
textrequeridostringContenido del mensaje, máx 4096 caracteres.

Ejemplo

curl -X POST https://api.agentbuilder.cloud/v1/public/messages \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "5215512345678",
    "waNumberId": "wa_xxx",
    "type": "text",
    "text": "Hola desde la API"
  }'
Response
{
  "id": "msg_01JXAB7P4D3Z6T2HF9V0KQR5MN",
  "status": "queued"
}
El endpoint responde 202 Accepted tan pronto se encola el mensaje. El envío real sucede en background — para saber cuándo se entregó, suscríbete al webhookmessage.sent o consulta el endpoint GET /v1/public/messages/:id.

Consultar mensajeGET/v1/public/messages/:id

Devuelve el estado y contenido de un mensaje. Requiere scope messages:read.

curl https://api.agentbuilder.cloud/v1/public/messages/msg_01JXAB7... \
  -H "Authorization: Bearer ak_live_..."
Response
{
  "id": "msg_01JXAB7P4D3Z6T2HF9V0KQR5MN",
  "conversation_id": "conv_01JXAB6...",
  "direction": "out",
  "type": "text",
  "content": { "text": "Hola desde la API" },
  "status": "sent",
  "provider_message_id": "wamid.HBgN...",
  "sent_at": "2026-06-23T05:14:22.451Z"
}

Listar conversacionesGET/v1/public/conversations

Lista paginada de conversaciones del workspace. Scope: conversations:read.

Query params

ParámetroTipoDescripción
statusstringopen (default) o closed.
limitintegerMáx 100, default 50.
cursorstringULID del último item visto en la página anterior. Orden por id DESC.
curl "https://api.agentbuilder.cloud/v1/public/conversations?status=open&limit=20" \
  -H "Authorization: Bearer ak_live_..."
Response
{
  "data": [
    {
      "id": "conv_01JXAB6...",
      "bot_id": "bot_xxx",
      "wa_number_id": "wa_xxx",
      "contact_id": "ct_xxx",
      "status": "open",
      "assigned_user_id": null,
      "bot_enabled": true,
      "last_message_at": "2026-06-23T05:14:22.451Z",
      "contact_wa_id": "5215512345678",
      "contact_name": "Juan Pérez"
    }
  ],
  "nextCursor": "conv_01JXAB5..."
}

Detalle de conversaciónGET/v1/public/conversations/:id

Detalle completo. Scope: conversations:read.

curl https://api.agentbuilder.cloud/v1/public/conversations/conv_01JXAB6... \
  -H "Authorization: Bearer ak_live_..."

Hand-off a humanoPOST/v1/public/conversations/:id/handoff

Desactiva el bot en la conversación para que un agente humano la atienda. Dispara el webhookbot.handed_off. Scope: conversations:write.

curl -X POST https://api.agentbuilder.cloud/v1/public/conversations/conv_01JXAB6.../handoff \
  -H "Authorization: Bearer ak_live_..."
Response
{ "ok": true }

Crear o actualizar contactoPOST/v1/public/contacts

Crea el contacto si no existe, o actualiza nombre / atributos / tags si ya existe (búsqueda por waId). Scope: contacts:write.

Cuerpo

ParámetroTipoDescripción
waIdrequeridostringNúmero WhatsApp internacional sin "+", solo dígitos.
namestringNombre del contacto.
attributesobjectPares clave-valor libres para almacenar metadatos (CRM ID, fuente, etc).
tagsstring[]Etiquetas para segmentación.
curl -X POST https://api.agentbuilder.cloud/v1/public/contacts \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "waId": "5215512345678",
    "name": "Juan Pérez",
    "attributes": { "crm_id": "hubspot:12345" },
    "tags": ["lead-vip"]
  }'
Response
{ "id": "ct_01JXAB6...", "created": true }

Consultar contactoGET/v1/public/contacts/:waId

Scope: contacts:read.

curl https://api.agentbuilder.cloud/v1/public/contacts/5215512345678 \
  -H "Authorization: Bearer ak_live_..."

Actualizar atributosPATCH/v1/public/contacts/:waId

Permite actualizar nombre, atributos o tags sin tocar el resto. Scope: contacts:write.

curl -X PATCH https://api.agentbuilder.cloud/v1/public/contacts/5215512345678 \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "tags": ["cliente-activo"] }'
Sección

Webhooks

Cómo funcionan

Los webhooks son HTTP POSTs que enviamos a una URL tuya cada vez que ocurre un evento en tu workspace (mensaje entrante, cita agendada, etc.). Reemplazan la necesidad de hacer polling y son la forma recomendada de mantener tu CRM en sync.

Registra tu endpoint desde el panel → Webhooks o vía API (POST /v1/public/webhooks). Te entregamos un secret en claro UNA sola vez para que firmes verificaciones HMAC.

Estructura del payload

Todos los eventos comparten esta estructura:

Response
{
  "id": "evt_01JXAC2P...",
  "type": "message.received",
  "created_at": "2026-06-23T05:14:22.451Z",
  "data": {
    /* campos específicos del evento — ver catálogo abajo */
  }
}

Headers de cada request

ParámetroTipoDescripción
X-AgentBuilder-EventstringNombre del evento, ej: message.received.
X-AgentBuilder-Event-Idstring (ULID)ID del evento — mismo en todos los reintentos.
X-AgentBuilder-Deliverystring (ULID)ID único de este intento. Útil como clave de idempotencia en tu side.
X-AgentBuilder-SignaturestringFirma HMAC SHA-256. Formato: t=<unix>,v1=<hex>.
User-AgentstringSiempre AgentBuilder-Webhook/1.0.

Verificar la firma

Firmamos cada request para que puedas confirmar que viene de nosotros y que no fue manipulada. La firma se computa como HMAC_SHA256(secret, "<unix_ts>.<raw_body>").

Importante: usa el body en bruto exactamente como lo recibiste — sin re-serializar. Si parseas a JSON y vuelves a stringify, la firma puede no coincidir por diferencias de espaciado.

Ejemplos de verificación

import crypto from 'node:crypto';

function verifySignature(rawBody, header, secret, toleranceSec = 300) {
  const [t, v1] = header.split(',').map(p => p.split('=')[1]);
  const ts = parseInt(t, 10);
  if (Math.abs(Date.now() / 1000 - ts) > toleranceSec) return false; // anti-replay

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${ts}.${rawBody}`)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(v1, 'hex')
  );
}

// Express
app.post('/webhook', express.raw({type: '*/*'}), (req, res) => {
  const ok = verifySignature(
    req.body.toString('utf8'),
    req.headers['x-agentbuilder-signature'],
    process.env.WEBHOOK_SECRET,
  );
  if (!ok) return res.status(401).end();
  // ... procesar evento
  res.status(200).end();
});

Catálogo de eventos

Eventos que puedes suscribir al registrar un endpoint:

Response
{
  "message_id": "msg_01JX...",
  "conversation_id": "conv_01JX...",
  "contact": { "id": "ct_01JX...", "wa_id": "5215512345678", "name": "Juan" },
  "bot_id": "bot_xxx",
  "type": "text",
  "content": { "text": "Hola, necesito ayuda" },
  "received_at": "2026-06-23T05:14:22.451Z"
}

Reintentos

Si tu endpoint no responde 2xx, lo reintentamos con back-off exponencial. Después de 7 intentos sin éxito, marcamos el endpoint como failed y dejamos de enviar.

Calendario de reintentos

ParámetroTipoDescripción
Intento 1inmediatoAl emitirse el evento.
Intento 2+30s
Intento 3+2min
Intento 4+10min
Intento 5+30min
Intento 6+2h
Intento 7+6h
Intento 8+24hÚltimo intento. Total ~33h desde el evento original.

Reglas especiales

ParámetroTipoDescripción
2xxOKMarcamos como entregado y reseteamos failure_count.
410 GonePausarTu servidor nos avisa que ese endpoint ya no existe. Pausamos automáticamente.
4xx (otros)TerminalNo reintentamos (request inválido). Marcamos failed para esta entrega pero NO pausamos el endpoint.
5xx / timeoutRetryableAplicamos el calendario de back-off.

Gestionar endpoints vía API

Además del panel, puedes registrar/listar/eliminar endpoints programáticamente. Scope: webhooks:manage.

Registrar endpoint

curl -X POST https://api.agentbuilder.cloud/v1/public/webhooks \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "targetUrl": "https://api.tucrm.com/webhooks/agentbuilder",
    "events": ["message.received", "appointment.created"],
    "description": "Receptor del CRM de ventas"
  }'
Response
{
  "id": "wh_01JXAC...",
  "targetUrl": "https://api.tucrm.com/webhooks/agentbuilder",
  "events": ["message.received", "appointment.created"],
  "status": "active",
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxx",
  "createdAt": "2026-06-23T05:14:22.451Z"
}
El campo secret se devuelve UNA SOLA VEZ. Guárdalo inmediatamente — no podrás recuperarlo más adelante. Si lo pierdes, deberás eliminar el endpoint y crearlo de nuevo.

Listar endpoints

curl https://api.agentbuilder.cloud/v1/public/webhooks \
  -H "Authorization: Bearer ak_live_..."

Actualizar (pausar, cambiar eventos)

curl -X PATCH https://api.agentbuilder.cloud/v1/public/webhooks/wh_01JXAC... \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "status": "paused" }'

Eliminar

curl -X DELETE https://api.agentbuilder.cloud/v1/public/webhooks/wh_01JXAC... \
  -H "Authorization: Bearer ak_live_..."