Un webhook es una petición POST que la API envía al endpoint registrado cuando ocurre un evento suscrito. La entrega es asíncrona: la operación que origina el evento no espera a que el receptor responda.

Cada endpoint se registra con POST /v1/webhooks, que devuelve el secreto de firma. La suscripción admite entre 1 y 10 eventos por endpoint.

Firma de las entregas

El cuerpo de cada entrega se firma con HMAC-SHA256 usando el secreto del endpoint. La firma viaja en hexadecimal, prefijada por el algoritmo:

X-{Brand}-Signature: sha256=<hex>

La verificación consiste en calcular el HMAC-SHA256 del cuerpo recibido tal como llegó, sin reserializar el JSON, y compararlo con el valor de la cabecera. Una comparación en tiempo constante evita filtrar información por el tiempo de respuesta.

Cabeceras de una entrega

cabeceracontenido
X-{Brand}-Signaturesha256= seguido del HMAC en hexadecimal
X-{Brand}-EventTipo de evento que originó la entrega, por ejemplo validation.completed
X-{Brand}-Delivery-IdIdentificador de la entrega, útil para deduplicar reintentos
X-{Brand}-TimestampMomento del envío, en ISO 8601 con sufijo Z
Content-Typeapplication/json; charset=utf-8

El Delivery-Id se mantiene estable entre los reintentos de una misma entrega: es el valor que permite descartar duplicados en el receptor.

Tiempos de espera y reintentos

La conexión dispone de 5 segundos y la petición completa de 10 segundos. Agotado ese margen, la entrega se considera fallida.

Una entrega fallida se reintenta hasta 5 veces, con esperas crecientes:

intentoespera desde el anterior
1.º reintento1 minuto
2.º reintento5 minutos
3.º reintento30 minutos
4.º reintento2 horas
5.º reintento6 horas

No todas las respuestas se reintentan. La distinción es si el fallo puede resolverse con el tiempo:

respuesta del receptortratamiento
2xxEntrega correcta
5xx, error de red o tiempo agotadoSe reintenta
408 y 429Se reintentan: indican saturación temporal
Resto de 4xxNo se reintenta. Un 400 o un 404 señalan un receptor mal configurado, y repetir la petición no lo corrige

El cuerpo de la respuesta del receptor se conserva truncado a 2 048 bytes para el historial de entregas, consultable en GET /v1/webhooks/{id}/deliveries.

Las entregas salientes están limitadas a 10 por dominio y por minuto: un receptor con muchos eventos simultáneos los recibe escalonados, no en ráfaga.

Desactivación automática

El endpoint acumula un contador de fallos consecutivos. Una entrega correcta lo devuelve a cero.

Al alcanzar 3 fallos consecutivos, el endpoint pasa a estado auto_disabled y deja de recibir entregas. El estado se consulta en GET /v1/webhooks junto con el contador consecutive_failures.

La reactivación es manual: se hace con PUT /v1/webhooks/{id} fijando el estado en active. El valor auto_disabled no puede asignarse desde la API — solo lo establece el sistema.

Estados de una entrega

estadosignificado
pendingEncolada, todavía sin intentar
retryingFalló y tiene reintentos pendientes
successEl receptor respondió 2xx
failedAgotó los reintentos o recibió un 4xx no reintentable

Recomendaciones para el receptor

  1. Responder 2xx en cuanto el cuerpo esté recibido y validado, y procesarlo después. Un receptor que procesa antes de responder consume el margen de 10 segundos y provoca reintentos innecesarios.
  2. Deduplicar por X-{Brand}-Delivery-Id: un reintento repite la misma entrega.
  3. Verificar la firma antes de leer el contenido.