Estados de una entrega
Cada entrega es una fila enwebhook_dispatch. Su status evoluciona así:
attempts, last_http_status y last_error se actualizan en cada intento,
de modo que el libro mayor se explica solo. attempts es el recuento de
POST de toda la vida de esa fila: un replay del operador no lo pone a cero.
Matriz de resultados
Solo los resultados terminales y exhausted incrementan
consecutive_failures. Un 503 que se recupera en el siguiente reintento
no es una entrega perdida y no mueve el cortacircuitos.Calendario de backoff
Los fallos reintentables se reenvían con un calendario fijo, visible para el suscriptor (WEBHOOK_OUT_MAX_ATTEMPTS = 5):
next_retry_at en la fila del libro mayor muestra la hora exacta del
próximo intento. El campo attempt del cuerpo se incrementa mientras id
permanece igual.
Desactivación automática
Un endpoint muerto no debe consumir capacidad de cola indefinidamente. Cuando un webhook acumula 20 entregas consecutivas terminales o exhausted:is_activedpasa afalse,- se estampa
disabled_atydisabled_reason = "consecutive-failures", - la etapa route deja de escribir filas de dispatch para él,
- el componente de salud
webhook-outy el resumen del dashboard lo cuentan endisabled_auto.
Reactivar
- Arregla el endpoint (o su URL mediante
PATCH). - Envía una entrega de prueba:
POST /api/v3/webhook/webhook/{id}/test. - Activa:
PATCH /api/v3/webhook/webhook/{id}/activecon{ "is_actived": true }. Esto limpiaconsecutive_failures,disabled_atydisabled_reason. - Reenvía lo que se perdió (abajo).
disabled_reason: legacy-secret-rotation-required. Los
webhooks anteriores a este release fueron desactivados por la migración
0237 porque sus secretos son previos al contrato de firma; rota el secreto
y después activa.
Replay
POST /api/v3/webhook/dispatch/{id}/replay reencola una fila del libro mayor
(status = pending, último error y next_retry_at limpiados) sin
reiniciar attempts. El siguiente POST incrementa el mismo contador, así
que la fila conserva el historial completo de entregas. El suscriptor recibe
el mismo id, event y data; attempt es el siguiente número secuencial.
- Reenviar una fila
erroroexhaustedno necesita cuerpo. - Reenviar una fila
successdevuelve409 Conflictsalvo que el cuerpo incluya{ "confirm_duplicate": true }, porque el suscriptor verá el evento dos veces. Los endpoints que deduplican poridlo gestionan de forma transparente.
WEBHOOK_OUT_MAX_ATTEMPTS). Un replay del operador sobre una fila
exhausted hace un POST adicional; si ese POST es reintentable, la fila
vuelve a exhausted (sin nueva programación automática).
Horizon Enterprise expone la misma acción por fila en la pantalla de detalle
del webhook, con filtros por estado, evento y fecha.