Guide

Idempotenza e retry sicuri

Un timeout non significa "non inviato". Come usare l'header Idempotency-Key per fare retry senza mai raddoppiare invii e addebiti.

Perché il retry cieco è pericoloso

Con gli SMS un retry non è gratis. Se la richiesta va in timeout, il client non sa nulla dell'esito: forse la richiesta non è mai arrivata, forse l'SMS è già partito. Ripetere la chiamata "per sicurezza" nel secondo caso significa due SMS al destinatario e due addebiti sul saldo.

Il caso classico non è nemmeno un retry scritto a mano: è la libreria HTTP con i retry automatici attivi di default. Verso un'API che muove denaro, ogni retry deve essere esplicito e idempotente.

L'header Idempotency-Key

La soluzione è un header: Idempotency-Key, con un valore scelto da te che identifica quel singolo invio logico. Nient'altro cambia nella richiesta.

curl

curl -X POST https://sms-jet.com/api/v1/sms/transactional \
  -H "Authorization: Bearer gsms_…" \
  -H "Idempotency-Key: order-1042" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+393331234567", "text": "…", "sender_type": "system" }'

La semantica del replay

Al primo invio la chiave viene registrata insieme all'impronta del corpo della richiesta. Da lì in poi: stessa chiave e stesso corpo → viene restituita di nuovo la risposta originale, senza nuovo invio e senza nuovo addebito. Vale anche per gli errori definitivi: si ripresentano identici.

Stessa chiave con un corpo diverso → 409 IDEMPOTENCY_CONFLICT. È una protezione, non un fastidio: una chiave identifica un messaggio, non uno slot riutilizzabile.

409 Conflict

409 Conflict

{
  "code": "IDEMPOTENCY_CONFLICT",
  "message": "This Idempotency-Key was already used with a different request body"
}

SEND_OUTCOME_UNKNOWN: l'esito è in sospeso

C'è un terzo caso: un tentativo precedente con quella chiave è partito ma non si è mai risolto (timeout o crash a metà). L'API non conosce l'esito e si rifiuta di indovinare: risponde 503 SEND_OUTCOME_UNKNOWN.

Cosa fare: non fare retry alla cieca e non cambiare chiave — con una chiave nuova il doppio invio torna possibile. Controlla il registro messaggi, oppure riprova più tardi con la stessa chiave: quando l'esito si risolve, il retry lo ottiene in replay.

503 Service Unavailable

503 Service Unavailable

{
  "code": "SEND_OUTCOME_UNKNOWN",
  "message": "A previous attempt with this Idempotency-Key has not been resolved yet. Do not retry blindly — poll the message log or retry later with the same key."
}

Come scegliere le chiavi

La chiave giusta di solito esiste già nel tuo sistema:

  • Una chiave per messaggio logico, non per tentativo: order-1042 per la conferma dell'ordine 1042, identica a ogni retry.
  • Mai valori casuali generati a ogni tentativo: una chiave nuova a ogni retry disattiva l'idempotenza proprio quando serve.
  • Derivala da un identificatore che possiedi già: l'id dell'ordine, della riga di coda, dell'evento.
  • Le chiavi sono per-app: due app diverse possono usare lo stesso valore senza interferire.
Account attivati dal nostro team

Pronto a inviare il primo SMS?

Niente self-signup, niente carta di credito: scrivici, ti attiviamo l'account e la prima consegna è a una POST di distanza.

Credito prepagato, ricariche con fattura — nessuna carta richiesta.