Aller au contenu

Guides

Erreurs

Chaque échec a la même forme, un code stable lisible par une machine, et un identifiant de requête que vous pouvez citer à l’assistance.

L’enveloppe

Les échecs sont encapsulés dans un objet error. Aiguillez sur code — jamais sur message, qui est écrit pour des humains et peut être reformulé à tout moment.

{
  "error": {
    "code": "INSUFFICIENT_FUNDS",
    "message": "Wallet balance 0 XOF is below the 23700 XOF required.",
    "retryable": false,
    "detail": {},
    "request_id": "01K3F7XQZ8V2N4M6P8R0T5CJWE"
  }
}
  • code — un identifiant stable. C’est là-dessus que votre intégration doit s’aiguiller.
  • message — lisible par un humain, et non stable. Pour les erreurs internes, il est toujours générique : aucun texte d’exception, aucun SQL et aucune trace d’appels ne franchit jamais la frontière.
  • retryable — indique si réessayer la requête identique pourrait plausiblement réussir. Publié pour vous éviter de deviner.
  • detail — contexte lisible par une machine, toujours un objet. Il est vide plutôt qu’absent quand il n’y a rien à ajouter.
  • request_id — identifie cette requête précise dans les journaux de SMSend. Présent sur chaque erreur, y compris les 4xx.

Faire le lien avec l’assistance

Le même identifiant est renvoyé dans un en-tête sur chaque réponse, réussie ou non. Journalisez-le. Le citer transforme une conversation d’assistance à propos d’un échec survenu hier en une simple recherche.

X-Request-Id: 01K3F7XQZ8V2N4M6P8R0T5CJWE

Ce qu’il faut réessayer

Seules trois erreurs sont marquées comme réessayables : une requête encore en vol sous la même clé d’idempotence, une limite de débit et une erreur interne. Tout le reste échouera exactement de la même façon, et le réessayer ne fait que consommer votre limite de débit.

Tous les codes d’erreur

Le vocabulaire publié au complet. De nouveaux codes peuvent être ajoutés : traitez un code non reconnu comme un échec générique plutôt que de planter.

CodeStatutRéessayableSignification
UNAUTHORIZED401NonAucune clé, une clé malformée, un mauvais secret, une clé révoquée ou expirée, ou un compte suspendu. Tous indiscernables par construction.
FORBIDDEN403NonLe compte ou l’appelant n’est pas autorisé à effectuer cette opération.
INSUFFICIENT_SCOPE403NonLa clé est valide mais ne porte pas la portée exigée par ce point de terminaison. La portée est nommée dans le detail.
ACCOUNT_SUSPENDED403NonLe compte est suspendu et ne peut pas utiliser l’API.
VALIDATION_FAILED422NonLa requête était malformée : un paramètre manquant ou invalide, une longueur de clé d’idempotence incorrecte, une URL de webhook rejetée, ou une méthode ou un type de contenu non pris en charge.
NOT_FOUND404NonRessource inexistante — y compris une ressource appartenant à un autre compte, délibérément indiscernable d’une ressource qui n’a jamais existé.
UNSUPPORTED_VERSION400NonLa version présente dans le chemin n’est pas prise en charge. Les versions prises en charge sont listées dans le detail.
IDEMPOTENCY_KEY_REQUIRED422NonUn lot a été soumis sans en-tête Idempotency-Key.
REQUEST_IN_PROGRESS409OuiUne autre requête portant cette clé d’idempotence est encore en vol. Attendez l’intervalle indiqué et réessayez.
IDEMPOTENCY_KEY_REUSED409NonCette clé d’idempotence a déjà servi pour une requête avec un corps différent. Utilisez une nouvelle clé.
INSUFFICIENT_FUNDS402NonLe portefeuille prépayé ne peut pas couvrir le montant annoncé.
CREDIT_LIMIT_EXCEEDED402NonL’encours postpayé dépasserait le plafond de crédit du compte.
WALLET_IN_DEBIT402NonLe portefeuille est débiteur et ne peut pas servir à dépenser.
BATCH_EMPTY422NonLe lot ne contient aucun destinataire.
BATCH_BODY_EMPTY422NonLe corps du message est vide une fois les espaces retirés.
SCHEDULE_INVALID422NonL’heure planifiée est dans le passé, ou le fuseau horaire n’est pas un identifiant IANA valide.
SENDER_NOT_APPROVED422NonL’expéditeur n’est pas approuvé pour ce compte.
RATE_LIMITED429OuiLa limite de requêtes de la clé a été dépassée. Attendez l’intervalle indiqué dans Retry-After.
CONFIGURATION_ERROR500NonLa tarification ou le routage n’est pas configuré pour cette requête. Contactez l’assistance ; réessayer n’y changera rien.
INTERNAL_ERROR500OuiUne défaillance inattendue du côté de SMSend. Citez l’identifiant de requête à l’assistance.

Pourquoi les ressources des autres donnent 404

Demander un lot, un message ou un webhook appartenant à un autre compte renvoie 404, pas 403 — la même réponse qu’une ressource qui n’a jamais existé. Un 403 confirmerait que l’identifiant est réel, ce qui transformerait le point de terminaison en moyen de tester l’existence de tel ou tel identifiant.