Webhooks de nuevas multas: idempotencia, reintentos y trazabilidad
Un webhook confiable puede llegar más de una vez, demorarse o fallar después de ser procesado. El diseño debe deduplicar eventos, reintentar con límites y conservar evidencia de punta a punta.
Por Marco Ferreiro ·
Cuando una consulta de flota encuentra una nueva infracción, un webhook permite avisar sin obligar al cliente a preguntar continuamente. El problema difícil no es enviar un POST: es garantizar que una pérdida de conexión, una respuesta tardía o un proceso reiniciado no duplique tareas ni haga desaparecer el evento.
El diseño prudente parte de una expectativa: una misma notificación puede llegar más de una vez. La aplicación debe aceptar esa realidad y producir un único efecto lógico.
Identidad del evento antes que identidad de la llamada
Cada hallazgo necesita un identificador estable de evento. No debe confundirse con el identificador del intento HTTP: el mismo evento puede generar varios intentos.
CloudEvents define id y source como atributos obligatorios y establece que su combinación debe ser única para eventos distintos. También contempla que un duplicado reenviado por un error de red mantenga el mismo id. Esa semántica ofrece una clave clara de deduplicación.
El consumidor debería persistir (source, event_id) con una restricción única. Si vuelve a llegar, responde correctamente sin volver a crear una tarea, enviar un email o registrar dos veces la misma novedad.
Recepción rápida y procesamiento durable
El endpoint valida método, tamaño, tipo de contenido, autenticidad y esquema. Después guarda el evento y devuelve una respuesta de éxito. El trabajo pesado —enriquecer, asignar, notificar— se ejecuta fuera de la solicitud.
El orden importa. Responder éxito y guardar después abre una ventana de pérdida. Procesar todo antes de responder aumenta los timeouts y los reintentos. El patrón equilibrado es confirmar sólo cuando el mensaje ya está durablemente aceptado.
OpenAPI 3.1 permite describir webhooks como solicitudes iniciadas por el proveedor y documentar cuerpo y respuestas esperadas. El contrato debería enumerar versiones, eventos, códigos de éxito, errores permanentes y límites.
Reintentos que no amplifican el problema
Un timeout no revela si el receptor procesó la solicitud. Puede haber ejecutado el cambio y perdido la respuesta. Por eso el reintento debe usar el mismo identificador de evento.
RFC 9110 distingue métodos idempotentes y advierte sobre reintentar automáticamente operaciones no idempotentes sin mecanismos para conocer su semántica o detectar si fueron aplicadas. Aunque el transporte use POST, el contrato puede volver idempotente el efecto mediante la clave estable.
Aplicá espera creciente con dispersión aleatoria, un máximo de intentos y una cola de fallos revisable. Los errores de esquema o autenticación no deberían reintentarse indefinidamente. Los fallos temporales, como indisponibilidad o límites de capacidad, sí pueden justificar otro intento.
Estados que se puedan auditar
Conviene separar al menos:
accepted: persistido por el receptor;processing: tomado por un trabajador;processed: efecto aplicado;duplicate: evento ya conocido;failed: requiere nueva ejecución o intervención.
Por cada intento guardá hora, endpoint lógico, código HTTP, duración y categoría del error. Evitá almacenar secretos, firmas completas o cuerpos con datos que no sean necesarios.
Trazabilidad de punta a punta
W3C Trace Context estandariza traceparent y tracestate para correlacionar solicitudes distribuidas. Una traza puede unir la detección, creación del evento, entrega y procesamiento. No reemplaza el event_id: la traza describe un recorrido; el identificador describe el hecho lógico.
Los campos de traza deben ser opacos. La recomendación del W3C advierte que no contengan información personal. Una patente no debería viajar dentro de traceparent ni aparecer en nombres de métricas de alta cardinalidad.
Reconciliación cuando todo lo demás falla
Incluso con buenos reintentos hace falta una vía de reconciliación. El consumidor debería poder consultar eventos desde un cursor o período y comparar lo recibido. Esa ruta resuelve expiraciones de reintentos, errores de configuración y caídas prolongadas.
En una integración de multas, el evento también debe expresar el alcance: nueva infracción encontrada, fuente que cambió o consulta parcial. “Sin multas” no debe emitirse cuando una jurisdicción tuvo timeout.
Un webhook confiable no promete magia de exactamente una vez. Ofrece identidad estable, persistencia, efectos idempotentes, historial de intentos y una forma de reparar diferencias. Esas propiedades hacen que un aviso pueda convertirse en una operación verificable de flota.
Metodología
- Alcance
- Patrón de integración para notificar hallazgos sin suponer una infraestructura o garantía de entrega específica del proveedor.
- Unidad de análisis
- Cada evento lógico y cada intento HTTP, separados del resultado de negocio y correlacionados mediante identificadores opacos.
- Cobertura
- Recomendaciones derivadas de estándares oficiales de HTTP, CloudEvents, OpenAPI y W3C Trace Context consultados el 13 de agosto de 2026.
Limitaciones
- Los intervalos, cantidad de reintentos, algoritmos de firma y tiempos de retención deben definirse en el contrato concreto.
- Los estándares citados describen semántica e interoperabilidad, pero no garantizan por sí solos durabilidad ni exactamente una vez.
Fuentes
- RFC 9110 — HTTP Semantics — RFC Editor (consultada el )
- CloudEvents Specification 1.0 — Cloud Native Computing Foundation (consultada el )
- OpenAPI Specification 3.1.1 — OpenAPI Initiative (consultada el )
- W3C Trace Context Recommendation — World Wide Web Consortium (consultada el )
Preguntas frecuentes
¿Un webhook puede entregarse más de una vez aunque la primera vez haya funcionado?
Sí. Si el proveedor no recibe o no interpreta la confirmación, puede reintentar un evento ya procesado. El consumidor debe reconocer el identificador y no repetir el efecto de negocio.
¿Alcanza con devolver HTTP 200 antes de procesar?
Sólo si la recepción ya quedó persistida de forma durable. Confirmar antes de guardar crea una ventana en la que el proveedor deja de reintentar, pero el consumidor puede perder el evento.
¿Qué dato conviene usar para deduplicar?
Un identificador de evento estable dentro de un origen definido. CloudEvents establece que la combinación de source e id distingue eventos y puede mantenerse cuando se reenvía un duplicado.
¿La traza debe incluir patente o datos del conductor?
No. W3C Trace Context advierte que los campos de trazabilidad no deben contener información identificable o sensible. Usá identificadores opacos y aplicá retención limitada a los registros operativos.
Notas relacionadas
Timeout no significa “sin multas”: cómo informar resultados parciales en una integración
Cuando una fuente no responde, el resultado es parcial o indeterminado, nunca cero. Un contrato explícito permite reintentar, alertar y decidir sin producir falsos negativos.
Cómo verificamos que un portal de multas sea realmente oficial
Un diseño convincente, un candado HTTPS o aparecer primero en Google no prueban oficialidad. Verificamos dominio, cadena institucional, trámite publicado y canales antes de confiar datos.
Polling de consultas sin saturar la API: Retry-After, ETag y espera con jitter
Consultar el estado cada segundo no hace que una búsqueda termine antes. Un contrato con Retry-After, ETag y una espera aleatoria reduce solicitudes repetidas, bytes y picos de clientes sincronizados.