Documentación para desarrolladores

Webhooks

Los webhooks son notificaciones firmadas que indican que una nota ha cambiado. Obtenga el contenido actualizado desde la REST API.

Eventos de webhook

EventoCuándo se dispara
note.endedUna sesión de grabación ha terminado y su transcripción final ya se puede obtener. Se dispara una vez por sesión de grabación: una nota con varias sesiones lo emite varias veces.
note.summary.generatedUn resumen ha terminado de generarse y ya se puede obtener.
note.updatedHan cambiado campos visibles externamente (título, contenido) después de que la nota terminara. Lleva debounce: las ediciones rápidas se agrupan en un solo evento.
note.deletedLa nota se eliminó (data.reason: "deleted") o salió del ámbito de visibilidad de su credencial (data.reason: "access_lost").

Existen además dos eventos de servicio: endpoint.verification (se envía al crear el endpoint y al cambiar su URL; responda con un 2xx para activarlo) y endpoint.test (se envía cuando pulsa "Enviar evento de prueba" en la consola o llama a la API de prueba).

Cuerpo de la solicitud

Los webhooks son notificaciones ligeras: transportan identificadores y estados, nunca el contenido de las transcripciones ni de los resúmenes. Obtenga el contenido desde la REST API usando el note_id.

JSON
{
  "event_id": "5f8c0a5e-...",
  "event_type": "note.ended",
  "occurred_at": "2026-08-12T05:20:00Z",
  "data": {
    "note_id": "note_abc123",
    "recording_session_id": "rec_456",
    "revision": 7,
    "transcript_status": "ready",
    "summary_status": "pending"
  }
}

Verificar firmas

Las entregas se firman siguiendo la especificación Standard Webhooks con el secreto whsec_... emitido al crear el endpoint:

HTTP
POST /webhooks/alt HTTP/1.1
Content-Type: application/json
webhook-id: 5f8c0a5e-...
webhook-timestamp: 1765515600
webhook-signature: v1,K5oZfzN95Z9UVu1EsPQmSmZQGGVfCM0jaZ0lPI4dvLU=
signature
signed_content = "{webhook-id}.{webhook-timestamp}.{raw request body}"
signature     = base64( HMAC-SHA256( base64url_decode(secret_after_whsec_), signed_content ) )
  • Verifique sobre el cuerpo de la petición sin procesar (raw body): no vuelva a serializar el JSON.
  • Compare las firmas con una comparación de tiempo constante.
  • Rechace las marcas de tiempo caducadas (recomendamos una tolerancia de ±5 minutos) para evitar ataques de repetición.
  • Rechace con un 4xx las peticiones cuya firma no coincida. Código de receptor funcional: paso 4 del inicio rápido.

Fallos de entrega y reintentos

  • Responda con un 2xx en menos de 10 segundos. Cualquier otra respuesta cuenta como fallo. Confirme primero y procese de forma asíncrona.
  • Las entregas fallidas se reintentan con backoff creciente (30 s → 5 min → 30 min → 2 h → 12 h → 12 h, hasta 7 intentos en total).
  • Un endpoint que acumula muchas entregas fallidas consecutivas se desactiva automáticamente.
  • No se siguen redirecciones; la URL del webhook debe responder directamente por HTTPS.

Gestionar eventos duplicados

La entrega es at-least-once: el mismo evento puede llegar más de una vez (reintentos, reenvíos desde la consola). Guarde durante un tiempo breve un registro de los event_id ya procesados y descarte los duplicados.

Gestionar eventos fuera de orden

Los eventos pueden llegar fuera de orden (reintentos, entregas en paralelo). No dé por hecho que lo último en llegar es el estado más reciente. Cada cambio visible externamente incrementa la revision de la nota (asignada por el servidor y monótona): guarde por nota la revisión que ya ha aplicado e ignore todo lo que llegue con una revisión igual o inferior. Ante la duda, vuelva a obtener la nota desde la REST API: siempre devuelve la revisión actual.

Comprobar cambios omitidos

  • Se pueden perder webhooks (caídas más largas que la ventana de reintentos, endpoints desactivados). Llame periódicamente a GET /v1/notes?updated_after=<last sync> para ponerse al día.
  • note.deleted con reason: "access_lost" significa que la nota salió del ámbito de su credencial (por ejemplo, una nota personal movida a un teamspace). Trátelo exactamente igual que una eliminación: borre su copia almacenada o bloquee el acceso a ella.
  • El polling incremental por sí solo no detecta eliminaciones ni pérdidas de acceso. Liste periódicamente todas las notas (con include_deleted=true para ver las tombstones): cualquier ID de nota que conserve y que ya no aparezca en el listado fue eliminada o salió de su ámbito.