Proyectos y fases
Referencia del webhook: eventos, encabezados, firma y reintentos
El contrato de cada entrega: eventos del catálogo, encabezados x-aproova-*, cómo verificar la firma y cuándo Aproova reintenta.
Revisado el 14 de noviembre de 2026
Antes de empezar
- Un webhook creado en Configuración > Integraciones (propietario del espacio, Flujo o superior) y el secreto de firma que muestra el formulario.
Vista rápida de la tarea
Empieza por estas etapas. Si la tarea tiene más pasos, aparecen justo debajo.
- Paso 1
Eventos del catálogo: review.created (revisión creada), review.version_uploaded (versión enviada), review.comment_created (comentario creado), review.verdict_submitted (decisión enviada por un participante), review.approved (revisión aprobada), review.rejected (revisión rechazada), review.changes_requested (cambios solicitados), review.approval_reopened (aprobación reabierta), review.unlocked (revisión desbloqueada). Aprobación reabierta y revisión desbloqueada solo llegan a los webhooks que los marquen; las suscripciones existentes siguen recibiendo solo los eventos que ya tenían. El botón Probar envía el evento webhook.test.
- Paso 2
Encabezados de cada entrega: x-aproova-event (tipo de evento), x-aproova-delivery (identificador de la entrega), x-aproova-timestamp (segundos desde 1970, UTC) y x-aproova-signature. También se envían user-agent Aproova-Webhooks/1.0 y, si hay cuerpo, content-type application/json. Los encabezados personalizados no sustituyen estos nombres.
- Paso 3
Firma: x-aproova-signature = "sha256=" seguido del HMAC-SHA256 en hexadecimal, calculado con el secreto del webhook sobre el texto "${timestamp}.${body}", donde timestamp es el valor de x-aproova-timestamp y body es el cuerpo bruto recibido (texto vacío en GET, DELETE o sin cuerpo). Calcúlalo sobre los bytes recibidos, antes de convertir el JSON, y compara en tiempo constante.
Paso a paso
- 4Cuerpo predeterminado (JSON): event, event_id, created_at, workspace_id, locale y, cuando existan, proof, version, folder, teams, comment, decision, actor y whatsapp. Los campos vacíos se omiten. El texto de los comentarios internos nunca se envía.
- 5Campos opcionales de decisión: verification_method (authenticated_user, email_otp o declared) y actor_verified (true solo para authenticated_user y email_otp). Solo aparecen en eventos de decisión con esa evidencia; en un cuerpo personalizado, usa {{data.verification_method}} y {{data.actor_verified}}.
- 6Respuesta: cualquier estado 2xx cuenta como entregado. Aproova espera hasta 6 segundos por la respuesta.
- 7Reintentos: errores de red, tiempo agotado y los estados 408, 425, 429 y 5xx se reintentan; otros 4xx no. Hay como máximo 4 intentos: el 2.º unos 5 minutos después del 1.er fallo, el 3.º unos 30 minutos después y el 4.º unos 120 minutos después. Tras el 4.º, la entrega queda como fallo definitivo en el historial.
- 8Cada reintento repite el mismo event_id y el mismo x-aproova-delivery. Úsalo para ignorar repeticiones en el destino. Si el espacio deja de tener un plan con webhooks, la entrega falla sin reintento.
Qué debe ocurrir
Tu servicio verifica la firma, reconoce repeticiones por event_id y responde 2xx rápidamente.
Problemas frecuentes
- La firma no coincide: calcúlala sobre el cuerpo bruto, sin reformatear el JSON, y usa el secreto actual (generar uno nuevo invalida el anterior).
- Acción duplicada en el destino: una respuesta lenta o un 5xx provoca un reintento. Guarda el event_id ya procesado.
- Un evento nuevo no llega: marca aprobación reabierta o revisión desbloqueada en la lista de eventos del webhook.