Zum Inhalt springen

Wiederholungen und Idempotenz

Netzwerke fallen aus – besonders mobil. Alle Frontmail-SDKs wiederholen fehlgeschlagene Anfragen automatisch, und zwar sicher: Eine wiederholte Sendung führt nie zu einer doppelten E-Mail oder einer doppelten Abrechnung.

Situation Wiederholt?
Netzwerkfehler (offline, DNS, Verbindungsabbruch) ✓
Timeout (timeoutMs, Standard 15 s pro Versuch) ✓
Antworten mit 5xx ✓
429 rate_limited ✓ – wartet Retry-After ab (sofern höchstens 60 s)
4xx-Fehler bei Validierung, Authentifizierung, Origin, CAPTCHA ✗ – eine Wiederholung würde nicht helfen
Blockierungen im Browser (blockHeadless, blockList, limitRate) ✗

Standardverhalten: 3 Wiederholungen nach dem ersten Versuch, exponentielles Backoff ab 300 ms mit Full Jitter, höchstens 10 s zwischen den Versuchen. Einstellbar über die Option retry:

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

Jeder logische Aufruf von send() erhält eine zufällige UUID als Idempotency-Key, und alle Wiederholungen dieser Sendung verwenden denselben Schlüssel. Frontmail merkt sich die Schlüssel auf dem Server 24 Stunden lang:

  • derselbe Schlüssel mit demselben Body liefert die ursprüngliche Antwort (dieselbe message_id), ohne erneut zu senden,
  • derselbe Schlüssel mit anderem Body schlägt mit 409 idempotency_conflict fehl.

Hat der erste Versuch Frontmail also tatsächlich erreicht, ging aber die Antwort verloren, erhält die Wiederholung einfach das ursprüngliche Ergebnis.

Übergeben Sie einen eigenen Schlüssel, wenn sich schon der Auslöser wiederholen kann – ein doppelt zugestellter Webhook, ein neu startender Job, ein Nutzer, der ein Formular in zwei Tabs abschickt:

// @frontmail/node
await frontmail.send({ templateId: 'tpl_receipt', params, idempotencyKey: `receipt-${order.id}` });
// @frontmail/browser – Optionen sind das letzte Argument
await send('svc_01J9…', 'tpl_receipt', params, { idempotencyKey: `receipt-${order.id}` });

Schlüssel dürfen bis zu 255 Zeichen lang sein. Verwenden Sie für jede eigenständige E-Mail einen neuen Schlüssel – wird einer für eine andere E-Mail wiederverwendet, gibt es einen Fehler statt eines Versands.

Bei der REST-API senden Sie den Header selbst:

Terminal-Fenster
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" } }'

Beim Batch-Versand setzen Sie idempotencyKey (idempotency_key in der REST-API) pro Nachricht.

Sobald die API 202 zurückgegeben hat, sind Zustellversuche Sache von Frontmail: Der Versand wiederholt vorübergehende Fehler des Anbieters mit Backoff, schaltet bei Authentifizierungs- oder dauerhaften Fehlern auf den Ersatzdienst um und hält Nachrichten zurück, wenn ein E-Mail-Dienst defekt ist. Ihr Code muss nichts tun – bei Bedarf prüfen Sie das Ergebnis mit getStatus() oder im Verlauf.