Reintentos e idempotencia
Las redes fallan, sobre todo en el móvil. Todos los SDK de Frontmail reintentan automáticamente las solicitudes fallidas, y lo hacen de forma segura: un envío reintentado nunca da lugar a un correo duplicado ni a un doble cargo.
Qué se reintenta
Sección titulada «Qué se reintenta»| Situación | ¿Se reintenta? |
|---|---|
| Error de red (sin conexión, DNS, conexión restablecida) | ✓ |
Tiempo de espera agotado (timeoutMs, 15 s por intento por defecto) |
✓ |
Respuestas 5xx |
✓ |
429 rate_limited |
✓: espera lo que indique Retry-After (si son 60 s o menos) |
Errores 4xx de validación, autenticación, origen o CAPTCHA |
✗: reintentar no serviría de nada |
Bloqueos del lado del cliente (blockHeadless, blockList, limitRate) |
✗ |
Política por defecto: 3 reintentos después del primer intento, con espera exponencial que empieza
en 300 ms con jitter completo y como máximo 10 s entre intentos. Configúrala con la opción
retry:
init({ publicKey: 'pk_4f2a…', retry: { retries: 5, baseDelayMs: 500, maxDelayMs: 20_000 } });init({ publicKey: 'pk_4f2a…', retry: false }); // desactivarClaves de idempotencia
Sección titulada «Claves de idempotencia»Cada send() lógico recibe un UUID aleatorio como Idempotency-Key, y todos los reintentos de ese
envío reutilizan la misma clave. En el servidor, Frontmail recuerda las claves durante
24 horas:
- la misma clave con el mismo cuerpo devuelve la respuesta original (el mismo
message_id) sin volver a enviar, - la misma clave con un cuerpo distinto falla con
409 idempotency_conflict.
Así, si el primer intento llegó realmente a Frontmail pero la respuesta se perdió, el reintento simplemente obtiene el resultado original.
Tus propias claves
Sección titulada «Tus propias claves»Pasa una clave explícita cuando lo que desencadena el envío puede repetirse: un webhook entregado dos veces, una tarea que se reinicia, un usuario que envía un formulario dos veces en dos pestañas:
// @frontmail/nodeawait frontmail.send({ templateId: 'tpl_receipt', params, idempotencyKey: `receipt-${order.id}` });
// @frontmail/browser: las opciones son el último argumentoawait send('svc_01J9…', 'tpl_receipt', params, { idempotencyKey: `receipt-${order.id}` });Las claves pueden tener hasta 255 caracteres. Usa una clave nueva para cada correo distinto: si reutilizas una para otro correo, obtendrás un error en lugar de enviarlo.
Con la API REST, envía tú la cabecera:
curl https://api.frontmail.dev/v1/send \ -H 'Idempotency-Key: receipt-A-1042' \ -H 'Authorization: Bearer sk_…' \ -H 'Content-Type: application/json' \ -d '{ "template_id": "tpl_receipt", "template_params": { "order_id": "A-1042" } }'En los envíos por lotes, establece idempotencyKey (idempotency_key en la API REST) en cada
mensaje.
Cuando la API ya ha aceptado el mensaje
Sección titulada «Cuando la API ya ha aceptado el mensaje»Una vez que la API ha devuelto 202, los reintentos de entrega son cosa de Frontmail: el proceso de
envío reintenta los errores temporales del proveedor con espera progresiva, cambia al servicio de
respaldo ante errores de autenticación o permanentes y retiene los mensajes cuando un servicio no
funciona. Tu código no tiene que hacer nada; si lo necesitas, comprueba el resultado con
getStatus() o en el Historial.