Skip to main content
POST
/
v1
/
webhooks
Crear webhook
curl --request POST \
  --url https://agents.studio.getsupervisor.ai/v1/webhooks \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'x-workspace-id: <x-workspace-id>' \
  --data '
{
  "url": "<string>",
  "agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "description": "<string>",
  "isActive": true,
  "headers": {},
  "secret": "<string>"
}
'
{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "url": "<string>",
  "isActive": true,
  "createdAt": "2023-11-07T05:31:56Z",
  "updatedAt": "2023-11-07T05:31:56Z",
  "agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "description": "<string>",
  "secretPreview": "<string>",
  "lastDeliveryAt": "2023-11-07T05:31:56Z",
  "headers": {},
  "successCount": 1,
  "failureCount": 1
}
Crea un webhook para recibir eventos de telefonía como call.status.updated, call.completed y call.error. La URL debe aceptar peticiones HTTPS.
Incluye X-API-Key y el header Workspace-Id al crear el webhook. El servicio puede firmar cada evento con X-Supervisor-Signature si proporcionas un secret.

Crear un webhook

import { createClient } from "@getsupervisor/agents-studio-sdk";

const client = createClient({
  baseUrl: "https://api-prod.studio.getsupervisor.ai/v1",
  workspaceId: process.env.WORKSPACE_ID!,
  apiKey: process.env.API_KEY!,
});

const webhook = await client.webhooks.create({
  url: "https://miapp.com/webhooks/supervisor",
  description: "Actualiza el CRM con el estado de la llamada",
  headers: {
    "X-Custom-Signature": "allowed",
  },
  isActive: true,
});

console.log(webhook.id, webhook.secretPreview);
Respuesta 201 Created
{
  "id": "wh_01J8XW1N9P2Q3R4S5T6U",
  "agentId": null,
  "url": "https://miapp.com/webhooks/supervisor",
  "description": "Actualiza el CRM con el estado de la llamada",
  "isActive": true,
  "secretPreview": "whsec_********************",
  "createdAt": "2025-08-19T16:00:00.000Z",
  "updatedAt": "2025-08-19T16:00:00.000Z",
  "lastDeliveryAt": null,
  "headers": {
    "X-Custom-Signature": "allowed"
  },
  "successCount": 0,
  "failureCount": 0
}
Si no envías secret, generaremos uno aleatorio de 32 caracteres. Para asociar el webhook a un agente de voz agrega agentId en el cuerpo.

Suscribirse a eventos

Una vez creado el webhook tienes que registrar las suscripciones que definen qué eventos se entregarán. Usa el endpoint POST /v1/webhooks//subscriptions con las claves del catálogo de eventos (por ejemplo call.status.updated, call.completed, call.error).
import { createClient } from "@getsupervisor/agents-studio-sdk";

const client = createClient({
  baseUrl: "https://api-prod.studio.getsupervisor.ai/v1",
  workspaceId: process.env.WORKSPACE_ID!,
  apiKey: process.env.API_KEY!,
});

const subscription = await client.webhooks.createSubscription(
  "wh_01J8XW1N9P2Q3R4S5T6U",
  {
    eventKey: "call.status.updated",
    isActive: true,
  }
);

console.log(subscription.id, subscription.eventKey);
Respuesta 201 Created
{
  "id": "sub_01J8XY7Z8A9B0C1D2E3F",
  "eventKey": "call.status.updated",
  "isActive": true,
  "webhookId": "wh_01J8XW1N9P2Q3R4S5T6U",
  "createdAt": "2025-08-19T16:00:05.000Z",
  "updatedAt": "2025-08-19T16:00:05.000Z"
}
Puedes crear varias suscripciones por webhook, una por eventKey. Si envías una clave no registrada en el catálogo recibirás 400. Usa GET /v1/webhooks//subscriptions para listar las suscripciones activas.

Notificaciones que enviaremos

Publicaremos eventos a tu URL en formato JSON. Incluimos ejemplos típicos:

call.status.updated — registrada

{
  "id": "evt_01J7W8A4XK0N5Y6Z7Q8P",
  "type": "call.status.updated",
  "created_at": "2025-08-19T16:01:00.000Z",
  "data": {
    "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
    "call_status": "registered",
    "direction": "outbound",
    "to_number": "+525538808448"
  }
}

call.status.updated — en curso

{
  "id": "evt_01J7W8A5A1B2C3D4E5F6",
  "type": "call.status.updated",
  "created_at": "2025-08-19T16:01:10.000Z",
  "data": {
    "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
    "call_status": "ongoing",
    "from_number": "+12137771234",
    "to_number": "+525538808448",
    "agent_id": "oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD"
  }
}

call.status.updated — finalizada

{
  "id": "evt_01J7W8A6G7H8I9J0K1L2",
  "type": "call.status.updated",
  "created_at": "2025-08-19T16:05:00.000Z",
  "data": {
    "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
    "call_status": "ended",
    "disconnection_reason": "agent_hangup",
    "duration_ms": 10000,
    "recording_url": "https://example.com/recording.wav",
    "public_log_url": "https://example.com/public_log.txt"
  }
}

call.status.updated — error

{
  "id": "evt_01J7W8A7M8N9O0P1Q2R3",
  "type": "call.status.updated",
  "created_at": "2025-08-19T16:02:00.000Z",
  "data": {
    "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
    "call_status": "error",
    "error_code": "telephony_provider_unavailable",
    "error_message": "Carrier unavailable"
  }
}

Validación de firmas (opcional)

Si configuras secret, firmaremos cada notificación con HMAC-SHA256 en el header X-Supervisor-Signature usando el formato sha256=HEX.

Reintentos y respuestas

  • Esperamos 2xx de tu servidor. Si no, reintentaremos con backoff.
  • Responde 200 OK lo antes posible (procesa de forma asíncrona si es necesario).

Buenas prácticas

  • Usa colas para procesar eventos.
  • Idempotencia: guarda id del evento para evitar duplicados.
  • Verifica la firma si definiste secret.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

x-workspace-id
string<uuid>
required

Identificador del workspace multi-tenant.

Body

application/json
url
string<uri>
required

Debe ser https.

agentId
string<uuid> | null

Identificador del agente asociado cuando aplica.

description
string | null
Maximum string length: 500
isActive
boolean
default:true
headers
object
secret
string

Secreto HMAC opcional proporcionado por el cliente. Si se omite, el backend genera uno.

Response

Created

id
string<uuid>
required
url
string<uri>
required

Debe ser https.

isActive
boolean
required
createdAt
string<date-time>
required
updatedAt
string<date-time>
required
agentId
string<uuid> | null

Identificador del agente asociado cuando aplica.

description
string | null
Maximum string length: 500
secretPreview
string | null

Vista previa enmascarada del secreto (prefix...suffix).

lastDeliveryAt
string<date-time> | null
headers
object

Headers permitidos (allowlist). Nunca incluir Authorization.

successCount
integer<int32>
Required range: x >= 0
failureCount
integer<int32>
Required range: x >= 0