API SMSPro

Envoyez des SMS depuis votre application. Une clé API se génère en 2 clics depuis Hub Développeur une fois connecté.

URL de base

URL de base
https://v2.smspro.cm

À préfixer devant tous les chemins ci-dessous. Exemple complet : https://v2.smspro.cm/api/v1/messages.

Authentification

Incluez votre clé dans chaque requête :

Header
Authorization: Bearer smspro_votre_cle_api

Si votre logiciel ne permet pas de poser un en-tête personnalisé (certains connecteurs "SMS gateway"), la clé est aussi acceptée en paramètre : ?api_key=smspro_... — le header reste la méthode recommandée dès que possible.

Limitation de débit

5 000 SMS/jour par défaut par clé API — ajustable par clé depuis Hub Développeur → Clés API. Au-delà, chaque appel répond 429 Too Many Requests. Le compteur se réinitialise à minuit UTC.

POST

Envoyer un SMS

POST /api/v1/messages
{
  "to": "+237699000001",
  "message": "Votre code OTP : 847291",
  "from": "MONAPP"
}

from doit être un identifiant d'expéditeur déjà déclaré sur votre compte.

Un Sender ID en attente de validation opérateur (whitelisting, jusqu'à 14 jours) reste utilisable dès la demande enregistrée — mais l'opérateur peut refuser d'acheminer certains messages tant qu'il n'est pas validé, sans remboursement automatique dans ce cas. Le statut de votre Sender ID est visible sur Mes Sender ID, ou via GET /api/v1/sender-ids.

Anciens connecteurs : recipient, text et sender sont acceptés comme équivalents de to, message et from si ces derniers sont absents.

GET

Envoyer un SMS — matériel limité au GET

Pour les connecteurs "SMS gateway" qui ne permettent pas de choisir POST (paramètres uniquement dans l'URL) :

GET
https://v2.smspro.cm/api/v1/messages/send?api_key=smspro_...&sender=MONAPP&recipient=%2B237699000001&text=Votre+code+OTP+:+847291
Le suffixe /send est obligatoire. Sans lui, GET /api/v1/messages est la route qui liste vos messages : aucun SMS n'est envoyé.
Le contenu du message et le numéro du destinataire se retrouvent dans l'URL — donc potentiellement dans des journaux de serveur, proxys ou historiques de navigateur en cas de test manuel. Préférez le POST ci-dessus dès que votre logiciel le permet.
POST

Envoi OTP

Même endpoint que l'envoi simple ci-dessus — il n'existe pas de route dédiée. Ce qui distingue un OTP, c'est le from utilisé : déclarez-le en usage "OTP" (pas "Marketing") lors de la demande de Sender ID, dans Mes SenderIDs — c'est ce qui permet à l'opérateur de l'acheminer correctement.

POST /api/v1/messages
{
  "to": "+237699000001",
  "message": "Votre code de vérification est 847291. Valable 5 minutes.",
  "from": "MONAPP-OTP"
}

Réponse immédiate (201) dès que le message est accepté pour envoi — pas d'attente de livraison. Suivez le statut réel via GET /api/v1/messages/:id ou l'événement webhook message.delivered ci-dessous.

POST

Envoyer en masse

POST /api/v1/messages/bulk
{
  "to": ["+237699000001", "+237699000002"],
  "message": "Votre code OTP : 847291",
  "from": "MONAPP"
}

1000 destinataires maximum par appel.

GET

Lister vos messages

GET
/api/v1/messages\n/api/v1/messages/:id

Suivi de livraison

Chaque message porte provider_message_id (identifiant chez l'opérateur, absent si l'envoi a été refusé), delivery_confirmed (true uniquement sur accusé de réception de l'opérateur) et delivery_state :

delivery_state Signification
pending En file, pas encore transmis à l'opérateur.
awaiting_confirmation Accepté par l'opérateur, accusé de réception attendu (jusqu'à 48 h).
delivered Reçu sur le téléphone, confirmé par l'opérateur.
transmitted Accepté par l'opérateur, aucun accusé après 48 h. État final : la réception n'est pas confirmée, mais le SMS est en général reçu.
failed Échec : voir error_code. Jamais facturé.
GET

Vos identifiants d'expéditeur

GET /api/v1/sender-ids
/api/v1/sender-ids
GET

Vérifier le solde

GET /api/v1/balance
/api/v1/balance

Codes d'erreur

Toute erreur répond avec ce code HTTP et {"error", "message"} en JSON :

Code Signification Cause typique
400 Bad Request Paramètre requis manquant (to, message, from) ; ou, en masse, liste to vide ou de plus de 1000 destinataires. Également renvoyé si vous appelez GET /api/v1/messages avec des paramètres d'envoi : il manque /send à l'URL.
401 Unauthorized Clé API absente, invalide ou révoquée.
402 Payment Required Solde insuffisant, ou compte sans wallet.
404 Not Found Deux causes possibles, à distinguer par le champ message de la réponse :
  • "Sender ID introuvable ou rejeté" — l'identifiant d'expéditeur (from) n'existe pas sur votre compte, ou a été refusé par l'opérateur. Un expéditeur en attente de whitelisting, lui, reste utilisable.
  • Réponse sans ce message (ou en HTML) — l'URL elle-même n'existe pas. Vérifiez l'URL de base ci-dessus et le chemin exact, /send compris.
422 Unprocessable Le message n'a pas pu être créé (destinataire invalide, etc.).
429 Too Many Requests Quota journalier de cette clé API dépassé.

Motifs d'échec d'un message

Un message accepté par l'API peut échouer ensuite chez l'opérateur. Son statut passe à failed, avec error_code (stable, à tester dans votre code) et error_message (texte lisible, qui peut évoluer). Un message en échec n'est jamais facturé.

error_code error_message
account_suspended Service temporairement indisponible, réessayez plus tard
auth_error Erreur de configuration, contactez le support
duplicate_message Ce message a déjà été envoyé
empty_message Le message est vide
http_error Réponse inattendue de l'opérateur — réessayez ; si l'erreur persiste, contactez le support
insufficient_balance Solde insuffisant
insufficient_credit Service temporairement indisponible, réessayez plus tard
invalid_sender_id Identifiant d'expéditeur invalide
monthly_limit_reached Service temporairement indisponible, réessayez plus tard
network_error Opérateur injoignable (délai de connexion dépassé) — réessayez dans quelques minutes
not_implemented Fonctionnalité indisponible pour le moment
provider_conflict Envoi en double refusé par l'opérateur — ce message est peut-être déjà parti
provider_error Erreur de l'opérateur pendant l'envoi — réessayez ; si l'erreur persiste, contactez le support
provider_rate_limited Trop d'envois simultanés vers l'opérateur — réessayez dans une minute
provider_unavailable Réseau de l'opérateur momentanément indisponible — réessayez dans quelques minutes
request_rejected Envoi refusé par l'opérateur — vérifiez le numéro, l'expéditeur et le contenu du message
reserved_sender_name Expéditeur interdit : ce nom est réservé à une institution ou une entreprise connue
routing_error Destinataire injoignable
sender_not_registered Expéditeur pas encore validé par l'opérateur — envoyez avec un expéditeur validé
sub_account_error Erreur de configuration, contactez le support
topup_limit_reached Service temporairement indisponible, réessayez plus tard
unauthorized Erreur de configuration, contactez le support
unknown_provider_error Erreur inattendue, contactez le support
unknown_topic Erreur de configuration, contactez le support

Événements Webhook

Déclarez une URL de rappel depuis Hub Développeur → Webhooks pour recevoir ces événements en temps réel, signés (en-tête X-Signature).

Vérifier la signature. Chaque requête contient X-Signature, le HMAC-SHA256 (hexadécimal, minuscules) du corps brut de la requête, calculé avec le secret affiché sur Hub Développeur → Webhooks (bouton à côté de chaque endpoint). Recalculez ce HMAC sur le corps exact reçu et comparez-le en temps constant avant de traiter l'événement — sinon n'importe qui connaissant votre URL peut vous envoyer de faux événements.

Un secret régénéré invalide immédiatement les signatures calculées avec l'ancien.

campaign.started Campagne démarrée
campaign.completed Campagne terminée
message.delivered Message livré
message.failed Message échoué
message.sent Message envoyé