Aller au contenu

Nouvelles tentatives et idempotence

Les réseaux tombent en panne – surtout sur mobile. Tous les SDK Frontmail relancent automatiquement les requêtes échouées, et ils le font en toute sécurité : un envoi relancé ne produit jamais d’e-mail en double ni de double facturation.

Situation Relancé ?
Erreur réseau (hors ligne, DNS, connexion réinitialisée) ✓
Délai dépassé (timeoutMs, 15 s par tentative par défaut) ✓
Réponses 5xx ✓
429 rate_limited ✓ – attend Retry-After (s’il vaut 60 s ou moins)
Erreurs 4xx de validation, d’authentification, d’origine, de CAPTCHA ✗ – réessayer n’y changerait rien
Blocages côté client (blockHeadless, blockList, limitRate) ✗

Politique par défaut : 3 nouvelles tentatives après la première, backoff exponentiel à partir de 300 ms avec jitter complet, au maximum 10 s entre deux tentatives. Configurez-la avec l’option retry :

init({ publicKey: 'pk_4f2a…', retry: { retries: 5, baseDelayMs: 500, maxDelayMs: 20_000 } });
init({ publicKey: 'pk_4f2a…', retry: false }); // désactivation

Chaque send() logique reçoit un UUID aléatoire comme Idempotency-Key, et toutes les nouvelles tentatives de cet envoi réutilisent la même clé. Côté serveur, Frontmail mémorise les clés pendant 24 heures :

  • la même clé avec le même corps renvoie la réponse d’origine (même message_id) sans renvoyer l’e-mail,
  • la même clé avec un corps différent échoue avec 409 idempotency_conflict.

Ainsi, si la première tentative a bien atteint Frontmail mais que la réponse s’est perdue, la nouvelle tentative obtient simplement le résultat d’origine.

Passez une clé explicite lorsque le déclencheur lui-même peut se répéter – un webhook livré deux fois, une tâche qui redémarre, un utilisateur qui soumet un formulaire dans deux onglets :

// @frontmail/node
await frontmail.send({ templateId: 'tpl_receipt', params, idempotencyKey: `receipt-${order.id}` });
// @frontmail/browser – les options sont le dernier argument
await send('svc_01J9…', 'tpl_receipt', params, { idempotencyKey: `receipt-${order.id}` });

Les clés peuvent compter jusqu’à 255 caractères. Utilisez une nouvelle clé pour chaque e-mail distinct – réutiliser une clé pour un autre e-mail renvoie une erreur au lieu de l’envoyer.

Avec l’API REST, envoyez l’en-tête vous-même :

Fenêtre de terminal
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" } }'

Pour les envois groupés, définissez idempotencyKey (idempotency_key dans l’API REST) pour chaque message.

Dès que l’API a renvoyé 202, les nouvelles tentatives de livraison sont l’affaire de Frontmail : l’expéditeur relance les erreurs temporaires du fournisseur avec backoff, bascule vers le service de secours en cas d’erreur d’authentification ou permanente, et retient les messages lorsqu’un service est défaillant. Votre code n’a rien à faire – consultez le résultat avec getStatus() ou dans l’Historique si besoin.