Passa al contenuto principale

Gestione errori

Questa guida mappa gli errori che puoi incontrare chiamando la SMS API di Agile Telecom in azioni di recovery chiare. Gli errori emergono in tre punti: HTTP di submission, codici di stato per messaggio in submission e stati finali del DLR.

1. Errori a livello HTTP (Submission)

HTTPSignificatoCosa fare
200Submission accettata (verifica accepted e statusCode per messaggio)Continua; aspetta i DLR
400Richiesta malformataCorreggi il payload; non ritentare così com'è
401Credenziali non valideVerifica API key / Basic Auth
403IP non in whitelistAggiungi l'IP chiamante alla whitelist
404Endpoint o URL account-type erratoUsa l'URL del tuo tipo di account (legacy vs new)
408Timeout della richiestaRitenta con back-off
413Payload troppo grandeSuddividi l'array messages in batch più piccoli
415Content-Type erratoImposta Content-Type: application/json
429Rate limit superatoBack-off esponenziale, vedi Best Practice
5xxErrore di piattaformaRitenta con back-off; allerta se persiste

Una risposta 200 non significa che ogni singola destinazione sia stata accettata — controlla il statusCode per messaggio in results.

2. Codici di submission per messaggio

In una risposta 200, ogni voce in results[] porta il proprio accepted e statusCode.

CodiceSignificatoAzione
200Messaggio accettatoAspetta il DLR
400Destinazione o body invalidiCorreggi e re-invia
401Sender ID non autorizzato per questa destinazione/paeseUsa un altro sender ID o pre-registralo
402Credito insufficienteRicarica dal portale wholesale
403Destinazione blacklisted o opt-outRimuovila dalla lista, non ritentare
429Throttling per account/routeRallenta gli invii su quella route
500Errore internoRitenta con back-off

3. Stati finali DLR

Una volta inviato, l'operatore restituisce un delivery report. Il mapping completo è nella guida Delivery Report; ecco la visione di recovery:

StatoCodiceRecovery
DELIVERED0Nessuna — successo
BUFFERED1Attendi — l'operatore consegnerà o farà scadere
EXPIRED2Opzionale: ritenta una volta dopo un ritardo se il messaggio è ancora utile
REJECTED3Investiga sender ID / contenuti; non ritentare alla cieca
UNDELIVERABLE4Marca il numero come errato; mai ritentare
UNKNOWN5Trattalo come delivered o expired in base alla tolleranza ai falsi negativi
FAILED6Ritenta una volta con back-off; se persiste, allerta

Errori comuni

"Tutto va in 401 dopo mezzanotte." Hai ruotato le key ma il cron job usa ancora quella vecchia. Fix: carica le key da env ad ogni restart e ruotale via deployment.

"Alcune destinazioni vengono silenziosamente scartate." Spesso il sender ID non è registrato per quel paese (Italia e India sono i casi più comuni). Verifica i DLR REJECTED e il statusCode per messaggio nella risposta di submission.

"I clienti lamentano SMS arrivati 6 ore dopo." Il telefono era spento e l'operatore ha bufferizzato il messaggio fino all'accensione. Lo stato era BUFFERED → DELIVERED. Abbassa il validity (se disponibile sul tuo account) per send time-sensitive.

"429 casuali a basso carico." Verifica la granularità — i limiti si applicano per API key e a volte per route. SMPP evita la maggior parte di questi casi; vedi SMPP.

"Il webhook continua a essere rilanciato." Il tuo endpoint DLR non sta tornando 200 (o il tuo endpoint inbound non sta tornando +OK) entro 10–30 secondi. Sposta i lavori pesanti dietro una coda.

Strategia di retry in codice

import time, requests

def send_with_retry(payload, headers, max_attempts=3):
backoff = 1.0
for attempt in range(1, max_attempts + 1):
r = requests.post(
"https://wholesale.agiletelecom.com/services/sms/send",
json=payload, headers=headers, timeout=10,
)
if r.status_code == 200:
return r.json()
if r.status_code in (408, 429) or 500 <= r.status_code < 600:
time.sleep(backoff)
backoff *= 2
continue
# 4xx diversi da 408/429 — non ritentare, la richiesta è errata.
r.raise_for_status()
raise RuntimeError("send_with_retry: retry esauriti")

Prossimi passi