API y webhooks
Versión 1.0 · 10 de noviembre de 2026
Disponibles en el plan Business. Las claves y los webhooks se gestionan en la plataforma, en Integraciones.
Autenticación
Envía tu clave en la cabecera Authorization: Bearer vo_live_…. Cada clave tiene permisos acotados y pertenece a una sola organización. Límite: 120 peticiones por minuto y clave (429 al superarlo). La clave se muestra una vez al crearla; puedes rotarla o revocarla en cualquier momento. Las claves no pueden gestionar usuarios ni escuchar grabaciones.
curl https://voiceopsai.cybernetix.es/api/v1/calls?limit=20 \ -H "Authorization: Bearer vo_live_XXXXXXXX"
Endpoints
| Método | Ruta | Permiso | Qué hace |
|---|---|---|---|
GET | /api/v1/calls | calls.read | Lista llamadas (filtros status, direction; paginación con before) |
GET | /api/v1/calls/{uuid} | calls.read | Detalle: conversación, resumen, métricas por turno, transferencias |
GET | /api/v1/agents | agents.read | Lista de agentes |
GET | /api/v1/appointments | appointments.read | Citas por rango (from, to en AAAA-MM-DD) |
GET | /api/v1/appointments/availability?date= | appointments.read | Huecos libres de un día |
POST | /api/v1/appointments | appointments.manage | Crea una cita (date, time, name, phone, service) |
GET | /api/v1/contacts | appointments.read | Contactos |
POST | /api/v1/contacts | appointments.manage | Crea un contacto |
GET | /api/v1/tickets | appointments.read | Bandeja: incidencias, recados y devoluciones |
GET | /api/v1/automations | automations.read | Automatizaciones |
POST | /api/v1/automations/{uuid}/run | automations.manage | Ejecuta una automatización (mode: test | real) |
Los errores siguen el formato {"error":{"code","message","details"}}. Las fechas van en ISO 8601 (UTC) salvo que se indique lo contrario.
Webhooks
Recibes un POST con cuerpo JSON { id, type, created_at, tenant, data } y estas cabeceras:
X-VoiceOps-Event: tipo de evento.X-VoiceOps-Event-Id: identificador único; úsalo para ser idempotente (un reintento lleva el mismo).X-VoiceOps-Signature:t=<segundos>,v1=<hex>, donde v1 es el HMAC-SHA256 de"{t}.{cuerpo}"con tu secreto.
Responde con un 2xx en menos de 10 segundos. Si no, se reintenta a 1 min, 5 min, 30 min, 2 h y 12 h. Tras 10 eventos sin entregar el webhook se desactiva. Solo se admiten direcciones https públicas y no se siguen redirecciones.
// Node.js: verificar la firma
import crypto from 'node:crypto';
function verify(rawBody, header, secret) {
const [t, v1] = header.split(',').map((p) => p.split('=')[1]);
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // rechaza peticiones antiguas
const expected = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}Eventos
call.started | Empieza una llamada (entrante o saliente) |
call.answered | Se atiende la llamada |
call.completed | Termina con normalidad |
call.failed | No se completa (fallo, sin respuesta, rechazada) |
transcript.completed | Resumen e intención listos |
agent.transferred | El agente transfiere a una persona |
appointment.created | Se crea una cita |
appointment.cancelled | Se cancela una cita |
automation.executed | Termina la ejecución de un flujo |