Codes d'erreur
Le serveur émet 39 codes, et pas un de plus. Ils sont listés ici par famille de statut HTTP, avec la conduite à tenir pour chacun. Un code absent de cette page n'est pas émis : si ton intégration en attend un autre, elle attend quelque chose qui n'arrivera jamais.
La forme d'une erreur
Toute erreur est un objet JSON de deux champs : un code stable et un message explicatif, destiné au développeur.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"code": "TEXT_TOO_LONG",
"message": "Le texte dépasse 1600 caractères"
}- Branche ton code sur
code, jamais surmessage: le texte peut être reformulé sans préavis, le code non. - N'affiche pas
messagetel quel à un utilisateur final : il est écrit pour celui qui intègre, pas pour celui qui attend son SMS. - Prévois un cas par défaut. Un code inconnu doit se traiter par son statut HTTP plutôt que de faire tomber l'intégration.
409 renvoyé quand un clientReference a déjà servi. Son corps est le message existant, sans code ni message — voir l'idempotence. La colonne « Portée » distingue ce qui peut survenir sur l'API publique /v1 de ce qui appartient aux parcours de la console (compte, recharge, applications, administration).
400 Bad Request
La requête est mal formée ou une valeur est refusée. Réessayer à l'identique donnera le même résultat : il faut corriger.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
BAD_REQUEST | Corps JSON illisible, ou paramètre d'un type inattendu (identifiant, date, statut inconnu). | Vérifier la sérialisation et le type des paramètres d'URL. | API /v1 |
VALIDATION_ERROR | Une contrainte de champ est violée. Le message nomme le champ fautif — le plus souvent un clientReference de plus de 64 caractères. | Corriger le champ signalé. | API /v1 |
TEXT_EMPTY | text est absent, vide ou ne contient que des espaces. | Ne pas appeler l'API tant que le contenu n'est pas construit. | API /v1 |
TEXT_TOO_LONG | text dépasse 1600 caractères. | Raccourcir le texte ou le répartir sur plusieurs envois. | API /v1 |
INVALID_NUMBER | Le numéro n'est pas un mobile camerounais valide : 9 chiffres commençant par 6. | Nettoyer le numéro en amont ; +2376…, 2376… et 6… sont tous acceptés. | API /v1 |
PRICE_NOT_CONFIGURED | Aucun tarif n'est configuré pour l'opérateur résolu. | Rien à corriger côté client : nous signaler le numéro concerné. | API /v1 |
INVALID_PERIOD | La date de début est postérieure à la date de fin. | Inverser les bornes de la période. | Console |
INVALID_EMAIL | L'adresse e-mail est absente ou vide. | Saisir une adresse. | Console |
PASSWORD_TOO_SHORT | Le mot de passe fait moins de 8 caractères. | Allonger le mot de passe. | Console |
OTP_INVALID | Le code de vérification ne correspond pas. | Ressaisir le code reçu par SMS. | Console |
OTP_EXPIRED | Le code de vérification a dépassé sa durée de validité. | Demander un nouveau code. | Console |
OTP_MAX_ATTEMPTS | Trop de tentatives sur le même code. | Demander un nouveau code plutôt que de continuer à essayer. | Console |
ACCOUNT_ALREADY_ACTIVE | Le compte est déjà vérifié. | Se connecter directement. | Console |
INVALID_AMOUNT | Montant de recharge sous le minimum, ou crédit non strictement positif. | Reprendre le montant. | Console |
INVALID_SLUG | Le slug d'application ne respecte pas le format : minuscules, chiffres et tirets, de 2 à 50 caractères. | Corriger le slug. | Console |
INVALID_URL | L'URL d'un endpoint webhook ne commence pas par http:// ou https://. | Saisir une URL absolue joignable depuis l'extérieur. | Console |
UNSUPPORTED_EVENT | Un événement inconnu a été demandé pour un endpoint webhook. | Le seul événement existant est sms.sent. | Console |
INVALID_OPERATOR | Une règle de préfixe vise DEFAULT, qui est la route de secours et ne se cible pas. | Choisir un opérateur réel. | Console (admin) |
INVALID_PREFIX | Un préfixe contient autre chose que des chiffres, ou ne commence pas par 6. | Corriger le préfixe. | Console (admin) |
INVALID_PRICE | Un tarif négatif a été soumis. | Saisir un montant positif ou nul. | Console (admin) |
INVALID_STATUS | Un statut de compte non autorisé a été demandé (seuls ACTIVE et SUSPENDED le sont). | Choisir un statut valide. | Console (admin) |
DUPLICATE_OPERATOR | Le même opérateur figure deux fois dans la liste soumise. | Dédupliquer la liste. | Console (admin) |
DUPLICATE_PREFIX | Le même préfixe figure deux fois dans la liste soumise. | Dédupliquer la liste. | Console (admin) |
401 Unauthorized
L'appelant n'est pas identifié. Aucun traitement n'a eu lieu.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
INVALID_API_KEY | Clé absente de l'en-tête Authorization, inconnue, ou révoquée. | Vérifier l'en-tête « Authorization: Bearer gsk_… ». Une clé révoquée ne redevient jamais valide : en créer une autre. | API /v1 |
INVALID_CREDENTIALS | Couple e-mail / mot de passe incorrect. | Reprendre la saisie ou lancer une réinitialisation. | Console |
402 Payment Required
La requête est valide, mais le compte ne peut pas la payer.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
INSUFFICIENT_BALANCE | Le solde ne couvre pas le prix de l'envoi. Aucun message n'a été créé. | Recharger le compte. Surveiller GET /v1/balance permet d'anticiper plutôt que de subir. | API /v1 |
403 Forbidden
L'appelant est identifié, mais son compte n'est pas en état d'agir.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
ACCOUNT_SUSPENDED | Le compte porteur de la clé n'est pas actif. | Nous écrire pour rétablir le compte. Les réessais sont inutiles. | API /v1 |
ACCOUNT_PENDING | Le compte n'a pas encore été vérifié par code SMS. | Terminer la vérification dans la console. | Console |
404 Not Found
La ressource demandée n'existe pas — ou n'appartient pas à l'appelant.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
NOT_FOUND | Message, application, clé, endpoint ou livraison introuvable. Un message appartenant à une autre application donne aussi 404, jamais 403. | Vérifier l'identifiant, et qu'il a bien été créé avec la même clé. | API /v1 |
409 Conflict
Une ressource équivalente existe déjà. Attention : sur POST /v1/sms, le 409 d'un clientReference déjà utilisé ne suit pas la forme { code, message } — il renvoie le message existant.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
EMAIL_TAKEN | Un compte existe déjà avec cette adresse e-mail. | Se connecter, ou réinitialiser le mot de passe. | Console |
PHONE_TAKEN | Un compte existe déjà avec ce numéro. | Utiliser un autre numéro, ou récupérer le compte existant. | Console |
SLUG_TAKEN | Ce slug est déjà porté par une autre application. | Choisir un autre slug. | Console |
TOPUP_PENDING | Une recharge est déjà en cours sur ce compte. | Attendre son dénouement avant d'en lancer une autre. | Console |
429 Too Many Requests
Le rythme ou le volume autorisé est dépassé. Le réessai est légitime, après attente.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
RATE_LIMITED | Plus de 10 requêtes par seconde sur la même clé API. S'applique aussi au renvoi trop rapproché d'un code de vérification. | Attendre la durée indiquée par l'en-tête Retry-After (1 seconde pour l'API), puis réessayer. | API /v1 |
QUOTA_EXCEEDED | Le quota journalier du compte est atteint (jour calendaire UTC). Ce quota est désactivé par défaut. | Reprendre le lendemain, ou demander un relèvement. Aucun en-tête Retry-After n'accompagne ce code. | API /v1 |
503 Service Unavailable
Une dépendance est indisponible. Rien n'a été débité.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
OPERATOR_DISABLED | Les envois vers l'opérateur visé sont suspendus. Le refus intervient avant tout débit. | Retry-After vaut 3600 : reprendre dans une heure, ou router l'envoi autrement. | API /v1 |
TOPUP_DISABLED | La recharge en ligne est désactivée. | Nous contacter pour un crédit manuel. | Console |
CAMPAY_UNAVAILABLE | Le prestataire de paiement mobile n'a pas répondu. | Réessayer dans quelques minutes. | Console |
500 Internal Server Error
Le défaut est de notre côté, et il est journalisé.
| Code | Signification | Que faire | Portée |
|---|---|---|---|
INTERNAL_ERROR | Erreur interne non prévue. Le message ne contient jamais de détail technique. | Réessayer plus tard. Si cela persiste, nous transmettre l'heure de l'appel. | API /v1 |
L'en-tête Retry-After
Deux situations l'accompagnent d'une durée en secondes, et il faut la respecter plutôt que d'inventer un délai :
429 RATE_LIMITEDsur l'API —Retry-After: 1. Sur un renvoi de code de vérification, la valeur est le temps restant avant le prochain envoi autorisé.503 OPERATOR_DISABLED—Retry-After: 3600, soit une heure.
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
{
"code": "OPERATOR_DISABLED",
"message": "Envois vers CAMTEL indisponibles pour le moment, réessayez plus tard"
} Les autres réponses n'en portent pas : 429 QUOTA_EXCEEDED, 503 TOPUP_DISABLED et 503 CAMPAY_UNAVAILABLE se traitent par une reprise différée décidée côté client. La façon propre de gérer un 429 est détaillée dans quotas et limites.
Depuis un navigateur, l'en-tête est explicitement exposé par la politique CORS : il reste lisible par un client JavaScript.
Prêt à envoyer ton premier SMS ?
Crée un compte, reçois 100 F de crédit et une clé API immédiate.