Webhooks: Buenas prácticas
El contrato en números
Antes de los detalles, los tres parámetros que condicionan el diseño de un endpoint receptor
10seg para responder
7 intentos con backoff exponencial
14 días de historial para análisis
Seguridad del endpoint
1. Servir el endpoint sobre https://
https://El endpoint configurado en la suscripción debe servirse sobre TLS. Esto protege el contenido del evento y las credenciales de autenticación en tránsito. No exponer endpoints sobre http:// salvo en entornos de prueba aislados.
2. Usar un esquema de autenticación
Configurar uno de los esquemas soportados (Basic, API Key u OAuth). El esquema "No seguro" deja el endpoint abierto: cualquiera que conozca la URL puede simular webhooks. En producción, tratar la autenticación como un requisito, no como algo opcional.
No usarcustomHeaderspara credenciales.Los headers personalizados sirven para metadata de routing o correlación, no para secretos. A diferencia de los parámetros sensibles de los esquemas de seguridad (contraseñas, llaves,
clientSecret), que se ocultan al consultar la configuración, loscustomHeadersse muestran completos en el detalle de la suscripción. Poner ahí un token equivale a exponerlo a cualquiera con acceso de lectura.
Idempotencia y orden
3. Garantizar idempotencia
Cada entrega incluye el header x-janis-message-id. Si el mismo mensaje llega dos veces (por un reintento luego de un timeout en el que el endpoint igual procesó el evento), procesarlo de nuevo puede generar duplicados en el sistema externo: doble orden creada, doble notificación, etc.
- Guardar el
x-janis-message-idde cada evento procesado y descartarlo si se recibe de nuevo. - Usar esa llave para deduplicar al escribir en base de datos (por ejemplo, con una clave única).
- No deduplicar por contenido: dos eventos distintos pueden tener contenido idéntico.
4. Tolerar reentregas y orden fuera de secuencia
Con hasta 7 reintentos y backoff exponencial, ante un corte del endpoint los mensajes pueden llegar duplicados (si se procesó el primer intento pero no se respondió 2xx a tiempo) o fuera de orden (si un intento falla y se reintenta más tarde mientras otros eventos posteriores ya entraron).
- Resolver los duplicados con idempotencia (punto 3).
- Para el ordenamiento, comparar la eventDate incluida en el payload antes de aplicar un cambio: si llega una actualización más vieja que la última procesada, descartarla o reconciliar según corresponda.
Responder rápido
5. Responder rápido y procesar en segundo plano
El sistema aplica un timeout de 10 segundos por intento. Si el endpoint tarda más, se considera fallido y se reintenta, aunque el endpoint haya alcanzado a procesar parte del evento. Eso puede generar duplicados y reintentos innecesarios que saturan al endpoint.
El patrón correcto:
- Recibir el POST.
- Validar la autenticación y la estructura mínima del payload.
- Persistir el evento en un almacenamiento propio (cola de mensajes, tabla de pendientes, etc.) antes de responder.
- Responder 2xx apenas esté persistido.
- Procesar el evento en segundo plano, al ritmo que el sistema pueda sostener.
Responder 2xx significa "me hago cargo del evento".Si se responde 2xx sin persistir y luego el proceso interno falla, el sistema de Webhooks ya dará por entregado el mensaje y no lo reintentará.
La sonda de conectividad
6. Manejar explícitamente el payload {"setup": true}
Cada vez que una suscripción se guarda en estado activo, el sistema envía un POST al endpoint con cuerpo {"setup": true} como sonda de conectividad. Si esa prueba no responde 2xx dentro de los 10 segundos, la suscripción no se guarda.
- Detectar este payload antes de pasar al procesamiento normal.
- Responder rápido con 200 o 204.
- No crear registros, no enviar notificaciones, no disparar lógica de negocio para este payload.
- Aplicar la misma validación de autenticación que para un webhook real: confirma que el esquema de seguridad esté bien configurado de ambos lados.
La validación puede repetirse más adelanteLa validación del endpoint se realizará al momento de configurar la suscripción, ante cualquier actualización pero también puede suceder proactivamente para validar el estado de la misma. Es importante que siempre valides autenticación y devuelvas OK ante una request de setup.
Filtros y forma del payload
7. Filtrar en el servidor, no en el cliente
Si la integración solo se interesa por una fracción de los eventos de un trigger (por ejemplo, solo órdenes de una plataforma de ventas específica), configurar el filtro de la suscripción en vez de recibir todo y descartar del lado del cliente.
- Menos ancho de banda y menos carga en el endpoint receptor.
- Menos entradas en el historial, lo que facilita el diagnóstico.
- Menos riesgo de timeouts cuando el endpoint está ocupado descartando eventos que no le importan.
8. Ser tolerante a campos nuevos en el payload
Los servicios de Janis pueden agregar campos a la metadata de los eventos sin aviso previo. Un cliente que valide con esquemas estrictos ("rechazá si aparece algo que no conozco") va a empezar a rechazar mensajes después de cambios benignos en origen.
- Validar solo los campos que se usan, no la ausencia de otros.
- Ignorar silenciosamente atributos desconocidos en lugar de devolver error.
Monitoreo
9. Revisar periódicamente el historial de mensajes
El historial de mensajes permite auditar todas las entregas. Conviene revisar de forma periódica:
- Mensajes en estado failed: entregas que agotaron los reintentos.
- Mensajes con muchos intentos pero finalmente delivered: indican lentitud o fragilidad del endpoint.
- Picos de mensajes fallidos concentrados en el tiempo: suelen apuntar a un corte o cambio en el endpoint.
Detectar estos patrones temprano permite accionar antes de que el sistema externo pierda datos importantes y antes de que venza la retención de 14 días.