MailLandDocs
Webhooks

Lógica de Reintentos

Comprenda cómo Mail.Land reintenta las entregas de webhook fallidas

Cuando una entrega de webhook falla, MailLand reintenta automáticamente con retrasos crecientes. Esta página cubre el calendario de reintentos, los estados de entrega, el manejo de errores y cómo monitorear y reintentar entregas manualmente.

Calendario de Reintentos

Esta sección cubre todos los eventos que entrega el durable dispatcher: message.*, suppression.*, account.* e inbound.received. Lo específico de los eventos de entrada está en Entregas Entrantes más abajo.

MailLand reintenta una entrega fallida hasta 6 veces en total, con un retraso creciente antes de cada reintento:

IntentoRetraso antes de este intentoTiempo Total Transcurrido
1: (intento inicial)0
2Inmediato~0
31 minuto~1 minuto
45 minutos~6 minutos
515 minutos~21 minutos
61 hora~1 hora 21 minutos

Si el 6.º intento falla, la entrega se marca como fallida permanentemente: no hay más espera ni un 7.º intento.

Reintentable vs No Reintentable

Respuestas reintentables

Estos códigos de estado activan reintentos automáticos:

  • 408 Request Timeout
  • 429 Too Many Requests
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout
  • Errores de red (tiempos de espera, errores de socket, fallos de DNS)

Respuestas no reintentables

Estos códigos de estado se tratan como fallos permanentes, sin reintento:

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • Todos los demás errores 4xx (excepto 408 y 429)
  • Una respuesta de redirección que falla la validación (consulta Redirecciones) o supera el límite de saltos

Si tu endpoint devuelve un encabezado Retry-After en una respuesta reintentable, MailLand usa ese valor como retraso antes del siguiente intento en lugar del calendario anterior: para cualquier estado reintentable, no solo 429. No hay un límite superior ni jitter aplicado: respeta esto también de tu lado si lo envías, ya que un valor muy grande se respeta exactamente como se indica.

Redirecciones

MailLand no trata tu endpoint como lo haría un navegador. Las redirecciones se siguen manualmente, con un máximo de 3 saltos, y cada salto se revalida antes de enviar nada a él:

  • el destino debe ser https://: una redirección a http:// se rechaza, no se degrada;
  • el destino debe resolver a una dirección pública: una redirección a una dirección privada, loopback o link-local se rechaza, y la solicitud nunca se emite;
  • superar 3 saltos hace fallar la entrega.

Una redirección rechazada se reporta como un fallo de entrega sin código de estado. Si tu endpoint se movió, apunta el webhook a la nueva URL en lugar de depender de una redirección.

Configuración de Entrega

ConfiguraciónPredeterminadoDescripción
Tiempo de espera HTTP15 segundosTiempo de espera máximo por intento de entrega
Reintentos máximos6 intentosTotal de intentos de entrega incluyendo el inicial
Umbral de pausa automática10 fallos consecutivosEl webhook se pausa después de este número de fallos seguidos: usa el pauseThreshold propio del webhook cuando está configurado en un valor mayor que 0, y este valor por defecto en caso contrario
DeduplicaciónMientras exista el registro de entregaLos duplicados del mismo evento se suprimen mediante la restricción (WebhookId, EventId) mientras la fila exista: al menos 30 días para las entregas exitosas

Entregas Entrantes

inbound.received se entrega con el mismo durable dispatcher que cualquier otro evento, con el mismo calendario de reintentos, el mismo tratamiento de Retry-After, el mismo historial de entregas y la misma pausa automática descritos arriba.

  • Deduplique con event_id (igual a X-MLND-Event-Id), como en cualquier otro evento. Es estable por mensaje de entrada y webhook, así que cada intento para el mismo correo lleva el mismo id.
  • Un reenvío manual es un evento nuevo: un event_id nuevo, con el original en data.replay_of. data.idempotency_key no cambia.
  • La download_url de cada adjunto se firma en cada intento y vale 15 minutos desde ese momento; el id del adjunto es el mismo en cada intento. Consulte Webhooks de entrada.

Ver Historial de Entregas

Consulte las entregas anteriores para un webhook:

GET https://api.mail.land/v1/webhooks/{id}/deliveries
List delivery history
curl -X GET "https://api.mail.land/v1/webhooks/wh_abc123/deliveries?limit=20" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Parámetros de Consulta

ParámetroTipoPredeterminadoDescripción
cursorstring-Cursor opaco del nextCursor de la página anterior. Omitir para la primera página.
limitint20Elementos por página
statusstring-Filtro: success o failed
eventTypestring-Filtrar por tipo de evento (ej. message.delivered)
fromdatetime-Fecha de inicio
todatetime-Fecha de fin
Delivery history response
{
  "items": [
    {
      "publicId": "p8r2kx7m9wq4rtz",
      "eventType": "message.delivered",
      "messageId": "t_a1b2c3d4e5f6",
      "statusCode": 200,
      "responseTimeMs": 145,
      "success": true,
      "errorMessage": null,
      "createdAt": "2026-02-17T12:34:58.000Z",
      "attemptNumber": 1
    },
    {
      "publicId": "p8r2kx7m3nq1abc",
      "eventType": "message.bounced",
      "messageId": "t_d4e5f6a1b2c3",
      "statusCode": 503,
      "responseTimeMs": 15000,
      "success": false,
      "errorMessage": "Service Unavailable",
      "createdAt": "2026-02-17T12:30:00.000Z",
      "attemptNumber": 3
    }
  ],
  "nextCursor": "eyJ2IjoxLCJzIjoiY3JlYXRlZGF0OmRlc2MiLCJrIjoi...",
  "hasMore": true
}

Reintentar una Entrega Fallida

Reintente manualmente una entrega fallida específica:

POST https://api.mail.land/v1/webhooks/{id}/deliveries/{publicId}/retry
Retry a delivery
curl -X POST https://api.mail.land/v1/webhooks/wh_abc123/deliveries/p8r2kx7m3nq1abc/retry \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Devuelve 202 Accepted en caso de éxito. El reintento se pone en cola y usa la carga útil del evento original.

EstadoCódigoDescripción
202-Reintento en cola exitosamente
202-La entrega ya está en cola para reintento, no-op, no es un error
400ALREADY_SUCCEEDEDNo se puede reintentar una entrega que ya tuvo éxito
400INVALID_REQUESTLa entrega es anterior al seguimiento duradero de reintentos, o está actualmente en curso
404WEBHOOK_NOT_FOUNDEl webhook no existe
404DELIVERY_NOT_FOUNDEl ID de entrega no existe

Pausa Automática por Fallos

Cuando un webhook acumula suficientes intentos de entrega fallidos consecutivos, MailLand lo pausa automáticamente. El umbral es el pauseThreshold propio del webhook cuando está configurado en un valor mayor que 0, y en caso contrario el valor por defecto de 10 intentos de entrega fallidos consecutivos:

  1. El isActive del webhook se establece en false, y se rellenan pausedAt y pausedReason: pausedReason indica cuántos fallos hubo y cuál fue el último
  2. Se crea una notificación en la aplicación
  3. No se entregan más eventos hasta que se reanude el webhook

El contador es de intentos, no de eventos: un solo evento que agota toda su escalera de reintentos contribuye con varios fallos.

No hay una notificación de advertencia previa antes de alcanzar el umbral: revisa consecutiveFailures de forma proactiva (ver Buenas Prácticas más abajo) en lugar de esperar a que te avisen.

Reanudar un Webhook en Pausa

POST https://api.mail.land/v1/webhooks/{id}/resume
Resume a paused webhook
curl -X POST https://api.mail.land/v1/webhooks/wh_abc123/resume \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Esto reactiva el webhook: borra el estado de pausa, restablece el contador de fallos consecutivos a cero y lo vuelve a marcar como activo. El siguiente intento de entrega de eventos se realizará normalmente.

Cualquier entrega exitosa restablece automáticamente el contador de fallos consecutivos a cero. Un solo éxito después de 9 fallos evita que el webhook se pause.

Buenas Prácticas

  • Devuelva 200 rápidamente: procese las cargas útiles de webhook de forma asíncrona. Ponga el evento en cola y devuelva 200 inmediatamente. Los controladores de larga duración corren riesgo de tiempo de espera.
  • Use el ID de evento para el consumo idempotente: el encabezado X-MLND-Event-Id (y el campo event_id correspondiente en la carga útil) es estable a través de reintentos y reenvíos: el mismo evento subyacente siempre llega con el mismo ID, sin importar cuántas veces se reenvíe. Almacene los IDs procesados y omita los que ya manejó, de modo que una entrega duplicada sea un no-op de su lado.
  • Monitoree los fallos consecutivos: revise el campo consecutiveFailures al listar webhooks. Investigue antes de alcanzar el umbral de pausa automática.
  • Maneje correctamente el 429: si su punto de conexión está sobrecargado, devuelva 429 con un encabezado Retry-After. MailLand lo respetará.

Próximos Pasos

En esta página