Pour vos développeurs

Une intégration, du premier appel au suivi.

Créez des messages depuis votre application et recevez leurs changements d’état. Retrouvez ici les formats, les limites et les précautions utiles.

Contrat API · schémas et réponses

Démarrer avec le bon environnement

Créez une clé dans API et webhooks. Copiez l’origine HTTPS indiquée dans votre exemple de démarrage : c’est l’adresse du service API, pas l’adresse du tableau de bord. Définissez-la dans SMSMAROCPRO_API_ORIGIN, sans barre finale.

Disponibilité actuelle

Les simulations sont disponibles. L’accès aux ressources réelles est limité aux comptes autorisés pour le pilote. Une réponse 202 confirme l’enregistrement, jamais un envoi physique. Celui-ci dépend de l’abonnement, des limites et de l’activation de l’infrastructure.

Clé de testClé live
smsp_test_…
Contacts de démonstration, résultats simulés, aucun SMS transmis.
smsp_live_…
Messages et campagnes durables de votre compte, selon les droits sélectionnés.

Les deux clés utilisent le même service, mais les formats de destinataire diffèrent. Ne remplacez pas simplement une clé de test par une clé live dans un exemple de simulation.

Premier message simulé

POST /v1/messages
Authorization: Bearer <clé de test>
Content-Type: application/json
Idempotency-Key: integration_test_2026_001

{"recipientFixtureId":"contact_demo_001","text":"Bonjour depuis votre application."}

Création : HTTP 201, mode: sandbox, state: simulated et transmittedCount: 0. Les exemples cURL, Node.js, Python et PHP sont disponibles dans votre espace.

Clés et autorisations

Envoyez Authorization: Bearer VOTRE_CLÉ à chaque appel, depuis votre serveur. Jamais de clé dans une URL, du JavaScript public ou un dépôt Git. Le nom d’une clé est un simple libellé, pas un niveau de permission.

Le propriétaire du compte crée et révoque les clés. Chaque environnement accepte cinq clés actives au maximum ; celles créées dans l’interface expirent après 90 jours. Le secret n’est affiché qu’une fois.

Droit liveUsage
messages:write / messages:readCréer / consulter un message.
campaigns:write / campaigns:readCréer, suspendre, reprendre, annuler / consulter une campagne.
contacts:write / contacts:readImporter et consulter des listes de destinataires chiffrées.
suppressions:write / suppressions:readBloquer / consulter les destinataires exclus.
usage:readConsulter le volume disponible et les limites.

Choisissez uniquement les droits nécessaires. Pour renouveler une clé : créez la suivante, déployez-la dans votre application, vérifiez un appel puis révoquez l’ancienne. Une clé perdue ne peut pas être récupérée.

Créer et consulter un message réel

curl --request POST "$SMSMAROCPRO_API_ORIGIN/v1/messages" \
  --header "Authorization: Bearer $SMSMAROCPRO_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: message_commande_2026_001" \
  --data '{"to":"+2126XXXXXXXX","trafficClass":"transactional","text":"Votre commande est prête."}'

Remplacez le numéro masqué par un destinataire marocain autorisé. Le pilote accepte le trafic transactional. to, trafficClass et text sont obligatoires.

Options : sendAt pour une date future ISO 8601 avec fuseau, jusqu’à 30 jours ; sendBy pour la dernière date d’envoi acceptable. Par défaut, le message est disponible immédiatement et expire après une heure. sendBy doit suivre sendAt de sept jours au maximum.

HTTP 202 retourne un identifiant msg_…, un état et quotaUnits. Consultez ensuite GET /v1/messages/{id}. La lecture retourne l’état et l’analyse disponible, sans numéro ni contenu du SMS.

Éviter les doublons

Chaque création et contrôle de campagne exige un Idempotency-Key : 16 à 100 lettres, chiffres, tirets ou caractères de soulignement. Réutilisez la même valeur et exactement le même contenu lors d’un nouvel essai après une coupure réseau. Un rejeu exact retourne HTTP 200 avec le même identifiant. Un contenu différent avec la même clé retourne 409. Utilisez une nouvelle valeur pour une nouvelle opération.

Préparer et piloter une campagne

POST /v1/campaigns
Authorization: Bearer <clé live>
Content-Type: application/json
Idempotency-Key: campagne_rappel_2026_001

{"name":"Rappel de rendez-vous","text":"Votre rendez-vous approche.","to":["+2126XXXXXXXX","+2127XXXXXXXX"]}

Le pilote est borné à 20 destinataires. Les destinataires et le message sont figés à la création : modifier une liste de contacts ne modifie pas les messages déjà préparés. Les champs de programmation sendAt et sendBy suivent les mêmes règles que pour un message.

GET /v1/campaigns liste les campagnes ; GET /v1/campaigns/{id} retourne l’état, la révision et les totaux. Les listes actuelles sont bornées au pilote ; le Contrat API décrit leurs limites.

OpérationEffet
POST /v1/campaigns/{id}/pauseSuspend les messages qui ne sont pas encore confiés à la passerelle.
POST /v1/campaigns/{id}/resumeReprend les messages encore éligibles après vérification des conditions du compte.
POST /v1/campaigns/{id}/cancelAnnule les messages en attente ; un SMS déjà transmis ne peut pas être rappelé.

Envoyez {"expectedRevision":1} et une nouvelle clé d’idempotence pour chaque opération. Reprenez la révision de la dernière lecture. Une révision ancienne retourne 409 : relisez l’état avant de décider de réessayer.

Suivre le volume et respecter les exclusions

GET /v1/usage expose les informations du forfait et du quota disponibles. Une allocation mensuelle ne supprime pas le maximum quotidien. Deux segments consomment deux unités ; une recharge ne supprime pas la limite quotidienne.

POST /v1/suppressions avec une clé d’idempotence et {"to":"+2126XXXXXXXX","reason":"opt_out"} exclut un destinataire. Motifs acceptés : opt_out, complaint, customer_request. GET /v1/suppressions permet de consulter les exclusions sans exposer les numéros complets.

L’exclusion est vérifiée à la préparation et de nouveau juste avant l’envoi. Ne réessayez pas automatiquement un destinataire exclu. La réception automatique des réponses STOP n’est pas proposée dans ce pilote : transmettez les demandes reçues à la liste d’exclusion.

Comprendre une erreur et réessayer correctement

Les erreurs utilisent application/problem+json, avec code, status et un identifiant de requête. Conservez cet identifiant pour le support, jamais le secret ni le corps d’un SMS.

HTTPAction
400 / 413 / 415 / 422Corriger les paramètres, la taille ou le format JSON. Ne pas réessayer à l’identique.
401Vérifier la clé, son expiration, sa révocation et ses droits. Une autorisation manquante peut aussi retourner 401.
403Vérifier le compte, l’abonnement et l’accès au pilote ; une nouvelle clé ne contourne pas ces conditions.
404Vérifier l’identifiant et le compte propriétaire.
409Lire le code : conflit d’idempotence, révision obsolète, exclusion ou capacité de stockage atteinte.
429Attendre le nombre de secondes de Retry-After.
503Réessayer progressivement avec la même clé d’idempotence, sans recréer une opération.

Débit actuel : 60 appels par minute par clé de test ; 120 par minute par clé live. Ce débit HTTP est distinct de votre plafond de SMS. Les requêtes live JSON sont limitées à 64 Kio.

SMS standard : 160 unités conseillées, 306 maximum. Unicode : 70 conseillées, 132 maximum. Certains caractères GSM occupent deux unités. Utilisez le testeur d’analyse avant l’envoi ; les caractères non pris en charge sont refusés.

Un message accepté n’est pas encore livré

ÉtatSignification
ready / scheduled / acceptedEn attente, programmé ou retenu en préparation.
dispatching / submittedTransmission en cours ou acceptée par la passerelle.
sentLe téléphone confirme l’envoi ; ce n’est pas une preuve de livraison au destinataire.
deliveredUn accusé de livraison a été reçu.
reconciling / manual_reviewRésultat incertain en cours de vérification ; ne pas renvoyer automatiquement.
failed / expired / cancelledÉchec, délai dépassé ou annulation.

Les SMS partent de numéros de téléphone variables, pas d’un Sender ID de marque fixe. Les accusés de livraison dépendent du réseau et peuvent arriver plus tard.

Recevoir les nouvelles sans interroger l’API

L’API est une demande de votre application à SMSmarocPro. Un webhook est le trajet inverse : SMSmarocPro appelle votre application lorsqu’un message change d’état.

  1. Préparez une URL HTTPS publique acceptant POST, sans redirection, identifiants dans l’URL ni port personnalisé.
  2. Dans votre espace développeur, ajoutez cette destination et choisissez un à trois événements.
  3. Copiez le secret affiché une seule fois dans la configuration serveur du récepteur.
  4. Validez la signature de endpoint.test et répondez 2xx. La destination devient active. Si le secret n’était pas encore configuré au premier essai, la notification est réessayée.
  5. Traitez chaque événement une seule fois, puis consultez le message par son identifiant si nécessaire.

Événements : message.submitted, message.sent, message.delivered, message.failed, message.reconciling. Les notifications contiennent un identifiant de ressource, pas le numéro ni le texte. Exemple de corps :

{"id":"evt_…","type":"message.delivered","occurredAt":"2026-09-05T10:00:00.000Z","data":{"id":"msg_…"}}

Valider la signature en Node.js

Le HMAC SHA-256 porte sur les octets bruts du corps, suivis du timestamp, sans séparateur. Le secret est utilisé tel qu’affiché, sans décodage Base64.

import { createHmac, timingSafeEqual } from "node:crypto";

// Conserver les octets reçus AVANT tout parseur JSON.
export function verifyWebhook(rawBody, headers, secret) {
  const timestamp = headers.get("x-smsmarocpro-timestamp") ?? "";
  const signature = headers.get("x-smsmarocpro-signature") ?? "";
  if (!/^\d{10,11}$/.test(timestamp) || !/^v1=[a-f0-9]{64}$/.test(signature)) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const expected = createHmac("sha256", secret)
    .update(rawBody).update(timestamp).digest();
  return timingSafeEqual(expected, Buffer.from(signature.slice(3), "hex"));
}

// Après validation : parser le JSON, vérifier que body.id correspond à
// x-smsmarocpro-event-id et dédupliquer durablement cet identifiant.
// Accepter dans une file durable puis répondre 2xx rapidement.
// Répondre 2xx également aux doublons déjà acceptés.

Les trois en-têtes sont X-SMSMarocPro-Event-Id, X-SMSMarocPro-Timestamp et X-SMSMarocPro-Signature. Tolérance de l’exemple : cinq minutes. Synchronisez l’horloge de votre serveur.

La livraison attend au maximum dix secondes. En cas d’échec, les essais sont espacés progressivement, à partir de 30 secondes ; huit tentatives maximum, puis la destination est désactivée. Les événements peuvent être dupliqués ou arriver dans un ordre différent. Un même identifiant conserve le même événement, mais chaque tentative a un timestamp et une signature actualisés.

La configuration exige le propriétaire connecté, pas une nouvelle configuration MFA. Le secret de signature prouve l’origine des notifications ; la clé API autorise vos demandes. Pour remplacer un secret perdu, ajoutez une nouvelle destination, validez-la puis désactivez l’ancienne. Un appel déjà en cours peut encore arriver après désactivation.

Avant d’intégrer dans votre produit

  • Commencez avec les clés de test et les exemples de démonstration.
  • Testez les réponses 401, 409 et 429, les coupures réseau et les notifications dupliquées.
  • Ne confondez pas confirmation d’enregistrement, envoi et livraison.
  • Gardez les clés et les secrets de signature côté serveur ; masquez-les dans vos journaux.
  • Vérifiez abonnement, quota, exclusions et date de validité avant chaque campagne.

Le Contrat API est la source unique des schémas machine. Il est accessible ici et dans l’application : ce ne sont pas deux copies distinctes.