openapi.json openapi.yaml Postman Collection
🧪 Mode Sandbox (Test sans frais)Clé API active :
env_test_demo_2026
Les requêtes de la console interactive et du Swagger UI sont exécutées en direct sur https://api.envoisms.ma.

Start here

Démarrage rapide : API SMS Maroc & Passerelle SMS

EnvoiSMS.ma est une infrastructure de messagerie programmable conçue pour le Maroc. Nos routes locales vers IAM, Inwi et Orange, avec bascule automatique entre routes, visent une latence minimale pour vos envois SMS.

URL de basehttps://api.envoisms.ma
Version API/v1 (Stable)
Format des donnéesapplication/json; charset=utf-8
AuthentificationAuthorization: Bearer smr_xxx
Limite par défaut60 à 1 200 requêtes / minute par clé selon le palier
Format numéroE.164 (ex: +212612345678)
Canaux actifsSMS vers les opérateurs marocains (routes locales), WhatsApp Business API (AtlasAI™)
Moteur IA propriétaireAtlasAI™ — le moteur derrière Ghita, votre assistant WhatsApp (Conversational Engine, Voice, Vision — intégré WABA)
LocalisationHébergée au Maroc — Cloud Edge EnvoiSMS 🇲🇦
01

Générez votre clé API "smr_..." depuis votre Console EnvoiSMS.ma.

02

Utilisez l'authentification Bearer dans vos headers HTTP pour chaque requête.

03

Testez votre intégration via des clés Sandbox (env_test_...) sur l'URL live pour valider vos appels sans consommer de crédit réel.

04

Intégrez le WhatsApp Business API pour diviser vos coûts OTP par 10.

05

Configurez un Webhook signé pour recevoir les accusés de réception en temps réel.

06

Suivez votre consommation et vos factures MAD directement sur votre Dashboard.

Envoyer votre premier message via l'API
// config/services.php
'envoisms' => [
    'key' => env('ENVOISMS_API_KEY'),
],

// Usage
Http::withToken(config('services.envoisms.key'))
    ->post('https://api.envoisms.ma/v1/messages', [
        'to' => '+212612345678',
        'message' => 'Votre commande est en cours de livraison 🚚',
        'from' => 'MaBoutique'
    ]);
OpenAPI Spec

Authentification

Authentification & Clés API SMS sécurisées

Chaque endpoint /v1 nécessite une clé API valide transmise dans le header Authorization sous forme de jeton Bearer. Les clés de test (sandbox) et de production peuvent être générées ou révoquées depuis votre console.

Authorization

Authorization: Bearer smr_xxx

Headers de limite

X-RateLimit-Limit et X-RateLimit-Remaining retournés à chaque appel.

Allowlists IP

Les requêtes provenant d'adresses IP non configurées retournent un statut 401.

CORS supporté

JSON, Authorization, X-EnvoiSMS.ma-Signature, et X-EnvoiSMS.ma-Version sont supportés.

Exemple d'en-têtes HTTP
POST /v1/messages HTTP/1.1
Host: api.envoisms.ma
Authorization: Bearer smr_xxxxxxxx
Content-Type: application/json
Accept: application/json

Open Source

SDKs API SMS officiels (PHP, Node.js, Python, Laravel)

Incorporez l'API SMS EnvoiSMS en quelques lignes de code grâce à nos SDKs open-source officiels.

NPM PackageTypeScript & JavaScript
Node.js / TypeScript
npm install envoisms
GitHub Repository
Composer PackagePHP 8.0+
PHP Client
composer require envoisms/envoisms-php
GitHub Repository
PyPI PackagePython 3.8+
Python Client
pip install envoisms
GitHub Repository
Notification ChannelLaravel 9 - 11
Laravel OTP Package
composer require envoisms/laravel-otp
GitHub Repository
Go ModuleGo 1.20+
Go Client
go get github.com/n4ouri/envoisms-go
GitHub Repository
Model Context ProtocolClaude, Cursor, AI Agents
MCP Server
npx -y @envoisms/mcp-server
GitHub Repository
DocsMessages/messages
POSThttps://api.envoisms.ma/v1/messages
Bearer Auth

Envoyer un message

Envoie un SMS ou un message WhatsApp Business à un destinataire unique.

Corps de la requête (JSON)
ChampTypeStatutDescription
tostringRequisNuméro de téléphone au format E.164 (+212...).
messagestringRequisContenu textuel (max 1600 caractères). Également accepté sous le nom "body".
fromstringOptionnelSender ID personnalisé (ex: NOM_MARQUE). Par défaut "EnvoiSMS".
channelstringOptionnel"sms" ou "whatsapp". Par défaut "sms". "whatsapp" envoie depuis votre propre numéro WhatsApp Business connecté (sinon 403 WHATSAPP_NOT_CONNECTED). Hors modèle, un message WhatsApp n'est accepté que si le contact vous a écrit dans les dernières 24 h — sinon 400 OUT_OF_24H_WINDOW, sans aucun débit (avec cascade, WhatsApp est sauté au profit du canal suivant).
cascadebooleanOptionnelSi activé, tente WhatsApp puis bascule sur SMS : immédiatement si WhatsApp refuse ou signale l'échec du message (non inscrit sur WhatsApp, fenêtre de 24 h fermée…), ou si aucun accusé de réception n'arrive dans le délai cascade_timeout (120 s par défaut). Seul l'envoi réellement parti est facturé : un WhatsApp refusé ou en échec ne l'est pas, et vous ne payez que le SMS. Un WhatsApp resté sans accusé de réception est parti (il peut encore être livré quand le téléphone se reconnecte) : il est facturé avec son SMS de repli, et remboursé si WhatsApp signale ensuite son échec. Conseil : donnez à votre modèle WhatsApp une durée de vie (TTL) inférieure ou égale à cascade_timeout, pour qu'un téléphone qui revient en ligne ne reçoive pas les deux.
cascade_timeoutintegerOptionnelAvec cascade : secondes d'attente d'un accusé de réception avant le canal suivant, de 30 à 43200 (12 h). Défaut : 120. Plus court = repli plus rapide mais plus de doubles envois facturés ; plus long = moins de doublons.
metadataobjectOptionnelClés-valeurs personnalisées stockées avec le message et transmises dans les webhooks (elles ne sont pas renvoyées par les endpoints GET /v1/messages). Une clé a un sens pour la plateforme : purpose: "otp" signale un code à usage unique que vous générez vous-même et active la relivraison automatique (voir notes).
buttonsarrayOptionnelTableau d'objets boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
interactiveobjectOptionnelObjet de message interactif WhatsApp riche : menus listes déroulants ("list"), boutons de réponse rapide ("button"), formulaires natifs ("flow"), bouton lien ("cta_url" : action {"name":"cta_url","parameters":{"display_text","url"}}) ou demande de localisation ("location_request_message").
templateobjectOptionnel(WhatsApp) Modèle approuvé de votre compte : {"name", "language"}, valeurs dans metadata.variables. Seul type de message autorisé hors fenêtre de 24 h ; tarifé selon la catégorie du modèle.
image | video | audio | document | stickerobjectOptionnel(WhatsApp) Média par "id" (média déjà téléversé) OU par "link" (URL https), jamais les deux. "caption" pour image, vidéo et document ; "filename" pour document.
reactionobjectOptionnel(WhatsApp) {"message_id": wamid, "emoji": "👍"} — réagit à un message de la conversation ; emoji vide pour retirer la réaction. Non facturé.
contactsarrayOptionnel(WhatsApp) Fiches contact (max 20) : name.formatted_name obligatoire ; phones, emails, urls, addresses, org, birthday facultatifs.
locationobjectOptionnel(WhatsApp) Épingle de localisation : {"latitude", "longitude", "name"?, "address"?}.
contextobjectOptionnel(WhatsApp) {"message_id": wamid} — répond en citant un message précédent. Valable sur tous les types sauf reaction.
phone_number_idstringOptionnel(WhatsApp) Numéro connecté qui envoie ; par défaut votre numéro par défaut.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Vous envoyez des codes OTP ? Deux approches. /v1/verify/send gère tout le cycle (génération, livraison, validation, expiration) et reste la voie recommandée. Si vous générez vos propres codes et les envoyez ici, ajoutez metadata: {"purpose": "otp"} : en cas d'échec de livraison confirmé par le réseau sur un numéro marocain alors que le code est encore frais (moins de 10 minutes), la plateforme le renvoie automatiquement une fois par une route SMS alternative — même identifiant de message, aucun coût supplémentaire. Sans ce tag, le message est traité comme un SMS ordinaire.
  • WhatsApp : hors modèle, un message (texte, média, réaction, contacts, localisation, interactif) ne part que vers un contact qui a écrit à votre numéro dans les dernières 24 h ; sinon la requête est refusée en 400 OUT_OF_24H_WINDOW avant tout débit. Avec une clé sandbox, l'envoi reste simulé et la réponse signale le refus dans "warnings". Pour afficher « en train d'écrire » pendant que vous préparez la réponse, voir POST /v1/messages/typing.
  • Les sauts de ligne (\n) sont pleinement pris en charge sur tous les canaux et s'affichent correctement chez le destinataire.
  • Le formatage de texte enrichi (gras, italique, etc.) n'est pas supporté par le canal SMS (texte brut uniquement).
  • Le canal WhatsApp prend en charge le formatage de texte avec la syntaxe standard (*gras*, _italique_, ~barré~).
POSThttps://api.envoisms.ma/v1/messages
curl -X POST "https://api.envoisms.ma/v1/messages" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+212612345678",
    "message": "Votre code de validation est 849204",
    "from": "MaBoutique",
    "channel": "whatsapp"
  }'
{
  "id": "msg_8f2d...",
  "to": "+212612345678",
  "channel": "whatsapp",
  "cascade": false,
  "status": "queued",
  "cost": {
    "eur": 0.03,
    "mad": 0.33
  },
  "segments": 1,
  "created_at": "2026-05-15T10:30:00Z"
}
DocsMessages/messages/bulk
POSThttps://api.envoisms.ma/v1/messages/bulk
Bearer Auth

Envoi groupé (Bulk)

Envoie jusqu'à 10 000 messages en un seul appel API avec des destinataires ou des contenus uniques.

Corps de la requête (JSON)
ChampTypeStatutDescription
messagesarrayRequisTableau d'objets contenant "to", "message" (ou "body"), et un objet facultatif "metadata".
fromstringOptionnelSender ID global pour tout le lot.
channelstringOptionnelCanal global ("sms" ou "whatsapp"). Par défaut "sms".
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Les sauts de ligne (\n) sont pleinement pris en charge dans les corps des messages groupés.
  • Le formatage de texte enrichi (gras, italique, etc.) n'est pas supporté par le canal SMS (texte brut uniquement).
  • Le canal WhatsApp prend en charge le formatage de texte avec la syntaxe standard (*gras*, _italique_, ~barré~).
POSThttps://api.envoisms.ma/v1/messages/bulk
curl -X POST "https://api.envoisms.ma/v1/messages/bulk" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "to": "+212611111111",
        "message": "Hello Client 1"
      },
      {
        "to": "+212622222222",
        "message": "Hello Client 2"
      }
    ],
    "from": "ENVOISMS",
    "channel": "sms"
  }'
{
  "batch_id": "batch_9a3c...",
  "total": 2,
  "channel": "sms",
  "estimated_cost": {
    "eur": 0.056,
    "mad": 0.62
  },
  "messages": [
    {
      "id": "msg_1a2b...",
      "to": "+212611111111",
      "status": "queued"
    },
    {
      "id": "msg_3c4d...",
      "to": "+212622222222",
      "status": "queued"
    }
  ]
}
DocsMessages/messages/typing
POSThttps://api.envoisms.ma/v1/messages/typing
Bearer Auth

Indicateur de saisie WhatsApp

Marque comme lu un message WhatsApp reçu et affiche « en train d'écrire » à son auteur pendant que vous préparez la réponse (disparaît à la réponse ou après environ 25 s). Ce n'est pas un message : rien n'est stocké ni facturé.

Corps de la requête (JSON)
ChampTypeStatutDescription
message_idstringRequisIdentifiant WhatsApp (wamid) du message reçu auquel vous répondez.
typing_indicatorbooleanOptionnelfalse envoie seulement l'accusé de lecture. Défaut: true.
phone_number_idstringOptionnelNuméro connecté qui a reçu le message ; par défaut votre numéro par défaut.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/messages/typing
curl -X POST "https://api.envoisms.ma/v1/messages/typing" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "status": "ok",
  "message_id": "wamid.HBgLMjEyNjEyMzQ1Njc4FQIAEhgg",
  "typing_indicator": true
}
DocsMessages/messages
GEThttps://api.envoisms.ma/v1/messages
Bearer Auth

Lister les messages

Récupère une liste paginée de tous les messages envoyés depuis le compte.

Paramètres Query
ParamètreTypeStatutDescription
limitintegerOptionnelNombre de résultats à retourner (1-200, défaut: 50).
offsetintegerOptionnelNombre de résultats à ignorer pour la pagination (défaut: 0).
statusstringOptionnelFiltrer par statut (queued, sent, delivered, failed, undeliverable, unconfirmed).
channelstringOptionnelFiltrer par canal (sms, whatsapp).
from_datestringOptionnelFiltrer par date de début (format ISO 8601).
to_datestringOptionnelFiltrer par date de fin (format ISO 8601).
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/messages
curl -X GET "https://api.envoisms.ma/v1/messages?limit=50&offset=0" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "msg_8f2d...",
      "to": "+212612345678",
      "channel": "whatsapp",
      "body": "Votre code de validation est 849204",
      "sender_id": "MaBanque",
      "status": "delivered",
      "cost_mad": 0.13,
      "created_at": "2026-05-15T10:30:00Z"
    }
  ],
  "limit": 50,
  "offset": 0,
  "total": 1
}
DocsMessages/messages/:id
GEThttps://api.envoisms.ma/v1/messages/:id
Bearer Auth

Statut du message

Consulte les détails et l'état de livraison en temps réel d'un message spécifique.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Statuts possibles : queued, sent, delivered, failed, undeliverable, unconfirmed. "unconfirmed" signifie que l'opérateur n'a jamais confirmé ni infirmé la livraison — un accusé arrivant plus tard peut encore le remplacer.
  • Le champ metadata fourni à l'envoi n'est pas renvoyé ici ; il est transmis dans les webhooks.
GEThttps://api.envoisms.ma/v1/messages/:id
curl -X GET "https://api.envoisms.ma/v1/messages/:id" \
  -H "Authorization: Bearer smr_xxx"
{
  "id": "msg_8f2d...",
  "campaign_id": null,
  "to": "+212612345678",
  "channel": "sms",
  "body": "Votre code de validation est 849204",
  "sender_id": "MaBanque",
  "unicode": 0,
  "segments": 1,
  "status": "delivered",
  "error_code": null,
  "error_message": null,
  "cost_eur": 0.0436,
  "cost_mad": 0.48,
  "scheduled_at": null,
  "sent_at": "2026-05-15T10:30:02Z",
  "delivered_at": "2026-05-15T10:30:05Z",
  "failed_at": null,
  "operator": "Maroc Telecom",
  "sandbox": 0,
  "created_at": "2026-05-15T10:30:00Z"
}
DocsMessages/templates
GEThttps://api.envoisms.ma/v1/templates
Bearer Auth

Lister les templates

Récupère tous les templates WhatsApp et SMS approuvés de votre compte.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/templates
curl -X GET "https://api.envoisms.ma/v1/templates" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "tpl_1234...",
      "name": "otp_verification",
      "channel": "whatsapp",
      "body": "Votre code de validation est {{1}}",
      "status": "approved",
      "category": "otp",
      "created_at": "2026-05-15T10:30:00Z"
    }
  ],
  "total": 1
}
DocsMessages/templates
POSThttps://api.envoisms.ma/v1/templates
Bearer Auth

Créer un template

Soumet un nouveau template pour approbation par les opérateurs ou WhatsApp.

Corps de la requête (JSON)
ChampTypeStatutDescription
namestringRequisNom interne du template.
channelstringRequis"sms" ou "whatsapp".
bodystringRequisContenu du message avec variables (ex: {{1}}).
categorystringOptionnelCatégorie du template (ex: "otp", "marketing").
languagestringOptionnelWhatsApp : code langue Meta (ex: "fr", "ar", "en_US"). Par défaut "fr".
sample_valuesobject | string[]OptionnelWhatsApp : une valeur d'exemple par variable, obligatoire pour la revue Meta (ex: {"1": "Amine"} ou ["Amine"]).
header_example_urlstringOptionnelWhatsApp, en-tête image/vidéo/document : lien https public vers un fichier d'exemple, transmis à Meta pour la revue.
add_security_recommendationbooleanOptionnelWhatsApp, catégorie "authentication" : ajoute la mention de sécurité de Meta. Le texte du corps est fixé par Meta ; code_expiration_minutes (1-90) est aussi accepté.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Un template WhatsApp passe d'abord la revue EnvoiSMS (pending_admin), puis est soumis à Meta sur votre propre compte WhatsApp Business (pending_meta). Seule Meta l'approuve (approved) ; sa catégorie finale est celle que Meta attribue.
POSThttps://api.envoisms.ma/v1/templates
curl -X POST "https://api.envoisms.ma/v1/templates" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "tpl_1234...",
  "name": "order_confirmation",
  "channel": "whatsapp",
  "language": "fr",
  "status": "pending_admin"
}
DocsMessages/templates/sync
POSThttps://api.envoisms.ma/v1/templates/sync
Bearer Auth

Synchroniser les templates depuis Meta

Importe tous les templates de votre compte WhatsApp Business (statut, catégorie, qualité). Un template absent chez Meta passe en deleted_on_meta.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/templates/sync
curl -X POST "https://api.envoisms.ma/v1/templates/sync" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "ok": true,
  "wabas": ["1234567890"],
  "fetched": 12,
  "updated": 9,
  "inserted": 3,
  "marked_deleted": 1,
  "complete": true,
  "errors": []
}
DocsMessages/sender-ids
GEThttps://api.envoisms.ma/v1/sender-ids
Bearer Auth

Lister les Sender IDs

Récupère la liste de vos Sender IDs avec leur statut d'approbation.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/sender-ids
curl -X GET "https://api.envoisms.ma/v1/sender-ids" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "sid_9a8b...",
      "sender_id": "MABANQUE",
      "status": "approved",
      "requested_at": "2026-05-10T09:00:00Z"
    }
  ]
}
DocsMessages/sender-ids
POSThttps://api.envoisms.ma/v1/sender-ids
Bearer Auth

Demander un Sender ID

Soumet un nouveau Sender ID pour approbation (requis pour le Maroc).

Corps de la requête (JSON)
ChampTypeStatutDescription
sender_idstringRequisLe nom d'expéditeur souhaité (max 11 caractères).
rc_urlstringOptionnelLien vers le Registre de Commerce pour vérification.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/sender-ids
curl -X POST "https://api.envoisms.ma/v1/sender-ids" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "sid_9a8b...",
  "sender_id": "MABANQUE",
  "status": "pending"
}
DocsVerify/verify/send
POSThttps://api.envoisms.ma/v1/verify/send
Bearer Auth

Générer un OTP

Envoie un code de vérification à usage unique. Deux modes au choix : "whatsapp" — vérification gérée, le plus simple (EnvoiSMS génère le code et le livre sur WhatsApp depuis un expéditeur vérifié ; si Meta refuse l'envoi WhatsApp, le code part par SMS ; avec une application Verify configurée en auto_cascade, le SMS part aussi à l'expiration du délai du canal, 30 s par défaut ; aucun code à stocker de votre côté) — ou "sms" — vous gardez le contrôle total du code, du modèle et de l'expéditeur. Dans les deux cas, la validation se fait avec le même appel /v1/verify/check. Vous souhaitez votre propre marque sur le repli SMS de la vérification gérée ? Disponible sur demande : [email protected].

Corps de la requête (JSON)
ChampTypeStatutDescription
tostringRequisDestinataire au format E.164.
channelstringOptionnel"whatsapp" (vérification gérée : WhatsApp, repli SMS si Meta refuse l'envoi ou, avec auto_cascade, après le délai du canal ; code valide 10 min, 3 essais, facturée par vérification au tarif WhatsApp OTP) ou "sms" (code généré pour vous, envoyé avec votre marque). Défaut: "sms".
app_idstringOptionnelID de l'application Verify configurée sur le tableau de bord (ex: vra_...). Applique automatiquement les paramètres de code, de délais et la cascade de canaux.
brandstringOptionnel(Canal sms) Nom de la marque affiché (ex: MonApp, max 32 car.). Par défaut "EnvoiSMS".
code_lengthintegerOptionnel(Canal sms) Longueur du code généré (de 4 à 8 chiffres, défaut: 6).
expiryintegerOptionnelDurée de validité du code en secondes (de 60 à 1800, défaut: 600). Sur le canal whatsapp, plafonnée à 600 (limite du modèle d'authentification).
cascadearrayOptionnel(Canal sms) Liste ordonnée de canaux pour le basculement automatique en cascade (ex: ["whatsapp", "sms"]).
templatestringOptionnel(Canal sms) Texte personnalisé avec les variables {{code}} et {{brand}}. En mode whatsapp, le message localisé (fr/en/es) est géré pour vous.
otp_button_textstringOptionnel(Canal whatsapp) Libellé personnalisé pour le bouton de copie automatique WhatsApp (max 25 car.).
web_otp_domainstringOptionnel(Optionnel, canal sms) Domaine web pour le remplissage automatique W3C WebOTP (ex: "https://monsite.ma"). Ajoute le tag @domaine #code à la fin du SMS.
app_hashstringOptionnel(Optionnel, canal sms) Hash de signature d'application Android de 11 caractères (SMS Retriever API) pour détection automatique du code sur Android.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Autofill OTP (iOS & Android) : Pour permettre à vos utilisateurs de remplir automatiquement le code reçu en 1 clic au-dessus de leur clavier, ajoutez simplement autocomplete="one-time-code" et inputmode="numeric" sur le champ <input> de votre site.
  • Temporisation anti-spam (cooldown) : Le champ "resend_after_seconds" indique la temporisation exacte avant réessai (60 s pour WhatsApp conformément aux normes Meta, 30 s pour SMS). Un plafond journalier de 10 vérifications par numéro s'applique.
POSThttps://api.envoisms.ma/v1/verify/send
curl -X POST "https://api.envoisms.ma/v1/verify/send" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+212612345678",
    "brand": "MonApp",
    "channel": "whatsapp",
    "code_length": 6,
    "expiry": 600
  }'
{
  "session_id": "vrf_7e2a...",
  "to": "+212612345678",
  "channel": "whatsapp",
  "resend_after_seconds": 60,
  "fallback_channels": ["sms", "whatsapp"],
  "expires_at": "2026-05-15T10:35:00Z",
  "status": "sent",
  "cost": { "eur": 0.05, "mad": 0.55 }
}
DocsVerify/verify/resend
POSThttps://api.envoisms.ma/v1/verify/resend
Bearer Auth

Renvoyer un code OTP (SMS ou WhatsApp)

Renvoie le même code OTP actif via SMS ou WhatsApp une fois le délai de temporisation écoulé (30 s pour SMS, 60 s pour WhatsApp). Aucun nouveau code n'est généré, évitant les erreurs de saisie.

Corps de la requête (JSON)
ChampTypeStatutDescription
session_idstringRequisIdentifiant de session reçu lors de l'appel initial à /v1/verify/send.
channelstringOptionnelCanal de renvoi cible ("sms" | "whatsapp"). Par défaut : "sms".
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Disponible sur toutes les offres, Starter comprise : /v1/verify/resend exige la même permission "verify" que /v1/verify/send, rien de plus.
  • D'où part le décompte : la temporisation court depuis le dernier envoi effectif, pas depuis votre appel — 60 s après une remise WhatsApp, 30 s après un SMS. GET /v1/verify/{session_id} renvoie le décompte en cours ("resend_available_in_seconds") et l'en-tête Retry-After du 429 porte le nombre exact de secondes restantes. La fenêtre est propre à votre compte et au numéro : le trafic d'un autre client vers le même numéro ne vous bloque jamais.
  • Clés sandbox (env_test_) : rien n'est délivré et rien n'est facturé. La réponse porte alors "sandbox": true et "sandbox_code", pour qu'un renvoi simulé ne soit jamais confondu avec un renvoi réellement délivré. Une clé sandbox ne peut renvoyer que les sessions qu'elle a créées, et une clé live que des sessions live.
POSThttps://api.envoisms.ma/v1/verify/resend
curl -X POST "https://api.envoisms.ma/v1/verify/resend" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "session_id": "vrf_7e2a...",
  "message_id": "wamid.HBgMMjEy...",
  "to": "+212612345678",
  "channel": "whatsapp",
  "status": "sent",
  "resend_after_seconds": 60,
  "expires_at": "2026-05-15T10:35:00Z"
}
DocsVerify/verify/check
POSThttps://api.envoisms.ma/v1/verify/check
Bearer Auth

Vérifier un OTP

Valide le code fourni par l'utilisateur pour une session de vérification donnée.

Corps de la requête (JSON)
ChampTypeStatutDescription
session_idstringRequisID de session reçu lors de l'appel à /v1/verify/send.
codestringRequisLe code reçu et saisi par l'utilisateur.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/verify/check
curl -X POST "https://api.envoisms.ma/v1/verify/check" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "vrf_7e2a...",
    "code": "849204"
  }'
{
  "session_id": "vrf_7e2a...",
  "verified": true,
  "verified_at": "2026-05-15T10:35:12Z"
}
DocsVerify/verify/:id
GEThttps://api.envoisms.ma/v1/verify/:id
Bearer Auth

Statut de session OTP

Consulte l'état (validé ou expiré) d'une session de vérification spécifique.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/verify/:id
curl -X GET "https://api.envoisms.ma/v1/verify/:id" \
  -H "Authorization: Bearer smr_xxx"
{
  "id": "vrf_7e2a...",
  "to": "+212612345678",
  "channel": "whatsapp",
  "expires_at": "2026-05-15T10:40:00Z",
  "verified_at": "2026-05-15T10:35:12Z",
  "created_at": "2026-05-15T10:30:00Z"
}
DocsVerify/verify/lookup
POSThttps://api.envoisms.ma/v1/verify/lookup
Bearer Auth

Validation de numéro

Valide le format, l'opérateur (carrier), le type de ligne et la localisation géographique d'un numéro de téléphone.

Corps de la requête (JSON)
ChampTypeStatutDescription
numberstringRequisLe numéro de téléphone à valider (format local ou international).
country_codestringOptionnelCode pays ISO à 2 lettres (ex: MA, FR). Recommandé si le numéro est au format local.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/verify/lookup
curl -X POST "https://api.envoisms.ma/v1/verify/lookup" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "number": "+212612345678",
    "country_code": "MA"
  }'
{
  "valid": true,
  "number": "212612345678",
  "local_format": "0612345678",
  "international_format": "+212612345678",
  "country_prefix": "212",
  "country_code": "MA",
  "country_name": "Morocco",
  "location": "Casablanca",
  "carrier": "Maroc Telecom (IAM)",
  "line_type": "mobile"
}
DocsContacts/contacts
GEThttps://api.envoisms.ma/v1/contacts
Bearer Auth

Lister les contacts

Récupère tous les contacts de votre compte, avec filtrage par mot-clé ou par liste.

Paramètres Query
ParamètreTypeStatutDescription
limitintegerOptionnelRésultats par page (1-500, défaut: 100).
offsetintegerOptionnelDécalage de pagination (défaut: 0).
qstringOptionnelRecherche par nom, téléphone ou email.
list_idstringOptionnelFiltrer uniquement les membres d'une liste de contacts spécifique.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/contacts
curl -X GET "https://api.envoisms.ma/v1/contacts?limit=50&offset=0" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "ctc_a2b3...",
      "phone": "+212612345678",
      "name": "Karim Bennani",
      "email": "[email protected]",
      "custom1": "VIP",
      "custom2": null,
      "custom3": null,
      "created_at": "2026-05-10T14:20:00Z"
    }
  ],
  "limit": 100,
  "offset": 0,
  "total": 1
}
DocsContacts/contacts
POSThttps://api.envoisms.ma/v1/contacts
Bearer Auth

Créer / Modifier un contact

Ajoute un contact ou met à jour les informations d'un contact existant (détection par numéro).

Corps de la requête (JSON)
ChampTypeStatutDescription
phonestringRequisNuméro de téléphone au format E.164.
namestringOptionnelNom complet du contact.
emailstringOptionnelAdresse email.
list_idstringOptionnelAssocier immédiatement le contact à une liste existante.
custom_fieldsobjectOptionnelObjet contenant jusqu'à 3 champs personnalisés ("custom1", "custom2", "custom3").
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/contacts
curl -X POST "https://api.envoisms.ma/v1/contacts" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+212612345678",
    "name": "Karim Bennani",
    "email": "[email protected]",
    "list_id": "lst_f84b..."
  }'
{
  "id": "ctc_a2b3...",
  "phone": "+212612345678",
  "name": "Karim Bennani",
  "email": "[email protected]",
  "custom1": "VIP",
  "custom2": null,
  "custom3": null,
  "created_at": "2026-05-10T14:20:00Z"
}
DocsContacts/contacts/import
POSThttps://api.envoisms.ma/v1/contacts/import
Bearer Auth

Importer des contacts

Importe massivement jusqu'à 5 000 contacts en un seul appel.

Corps de la requête (JSON)
ChampTypeStatutDescription
contactsarrayRequisTableau d'objets contenant "phone", "name" (optionnel) et "email" (optionnel).
list_idstringOptionnelID de la liste dans laquelle importer le groupe.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/contacts/import
curl -X POST "https://api.envoisms.ma/v1/contacts/import" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "phone": "+212611111111",
        "name": "Karim"
      },
      {
        "phone": "+212622222222",
        "name": "Youssef"
      }
    ],
    "list_id": "lst_f84b..."
  }'
{
  "imported": 150,
  "skipped": 3
}
DocsContacts/contacts/:id
DELETEhttps://api.envoisms.ma/v1/contacts/:id
Bearer Auth

Supprimer un contact

Supprime définitivement un contact à partir de son identifiant unique.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
DELETEhttps://api.envoisms.ma/v1/contacts/:id
curl -X DELETE "https://api.envoisms.ma/v1/contacts/:id" \
  -H "Authorization: Bearer smr_xxx"
{
  "deleted": true,
  "id": "ctc_a2b3..."
}
DocsContacts/contacts/lists
GEThttps://api.envoisms.ma/v1/contacts/lists
Bearer Auth

Lister les listes

Récupère toutes les listes de contacts créées pour les campagnes de diffusion.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/contacts/lists
curl -X GET "https://api.envoisms.ma/v1/contacts/lists" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "lst_f84b...",
      "name": "Newsletter Clients",
      "description": "Clients inscrits à notre lettre d'information",
      "count": 1420,
      "created_at": "2026-04-15T09:00:00Z"
    }
  ]
}
DocsContacts/contacts/lists
POSThttps://api.envoisms.ma/v1/contacts/lists
Bearer Auth

Créer une liste

Crée un nouveau groupe (liste de contacts) vide destiné aux campagnes.

Corps de la requête (JSON)
ChampTypeStatutDescription
namestringRequisNom de la liste.
descriptionstringOptionnelDescription de la liste.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/contacts/lists
curl -X POST "https://api.envoisms.ma/v1/contacts/lists" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Newsletter Clients",
    "description": "Clients inscrits"
  }'
{
  "id": "lst_f84b...",
  "name": "Newsletter Clients",
  "description": "Clients inscrits",
  "count": 0
}
DocsContacts/optouts
GEThttps://api.envoisms.ma/v1/optouts
Bearer Auth

Lister les désinscriptions

Récupère la liste des numéros qui se sont désinscrits (STOP) de vos communications.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/optouts
curl -X GET "https://api.envoisms.ma/v1/optouts" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "phone": "+212611111111",
      "opted_out_at": "2026-06-01T12:00:00Z"
    }
  ],
  "total": 1
}
DocsContacts/optouts
POSThttps://api.envoisms.ma/v1/optouts
Bearer Auth

Ajouter une désinscription

Ajoute manuellement un numéro à votre liste de désinscription (blacklist globale).

Corps de la requête (JSON)
ChampTypeStatutDescription
phonestringRequisNuméro de téléphone au format E.164.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/optouts
curl -X POST "https://api.envoisms.ma/v1/optouts" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "success": true,
  "phone": "+212611111111",
  "opted_out_at": "2026-06-01T12:00:00Z"
}
DocsContacts/optouts/:phone
DELETEhttps://api.envoisms.ma/v1/optouts/:phone
Bearer Auth

Retirer une désinscription

Retire un numéro de la liste de désinscription.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
DELETEhttps://api.envoisms.ma/v1/optouts/:phone
curl -X DELETE "https://api.envoisms.ma/v1/optouts/:phone" \
  -H "Authorization: Bearer smr_xxx"
{
  "deleted": true,
  "phone": "+212611111111"
}
DocsContacts/consents
GEThttps://api.envoisms.ma/v1/consents
Bearer Auth

Lister les consentements

Registre de consentements en ajout seul (loi 09-08, art. 10) : chaque accord et chaque retrait est un événement horodaté avec sa source et sa preuve. La plateforme y écrit elle-même les mots-clés STOP/START reçus sur WhatsApp et SMS et la première conversation ouverte par le client. Ajoutez format=csv pour exporter tout le jeu filtré.

Paramètres Query
ParamètreTypeStatutDescription
phonestringOptionnelNuméro E.164 à filtrer.
purposestringOptionnelmarketing, transactional, otp ou service.
statusstringOptionnelgranted ou withdrawn.
fromstringOptionnelÉvénements enregistrés à partir de cette date ISO 8601.
formatstringOptionnelcsv pour télécharger le jeu complet en fichier.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/consents
curl -X GET "https://api.envoisms.ma/v1/consents?limit=50&offset=0" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "cns_9f2a...",
      "phone": "+212612345678",
      "channel": "whatsapp",
      "purpose": "marketing",
      "status": "withdrawn",
      "source": "whatsapp_keyword",
      "evidence": { "keyword": "stop", "lang": "fr" },
      "recorded_at": "2026-09-05T09:00:00.000Z",
      "created_at": "2026-09-05T09:00:00.000Z"
    }
  ],
  "total": 1,
  "limit": 100,
  "offset": 0
}
DocsContacts/consents
POSThttps://api.envoisms.ma/v1/consents
Bearer Auth

Enregistrer un consentement

Consigne qu'une personne a donné ou retiré son consentement, avec la preuve que vous détenez (texte affiché, URL, IP, référence). recorded_at peut être antidaté pour un consentement importé, jamais dans le futur. Un retrait marketing est placé immédiatement sur la liste d'exclusion.

Corps de la requête (JSON)
ChampTypeStatutDescription
phonestringRequisNuméro au format E.164.
purposestringRequismarketing, transactional, otp ou service.
statusstringOptionnelgranted (défaut) ou withdrawn.
channelstringOptionnelwhatsapp, sms ou any (défaut).
sourcestringOptionnelapi (défaut), form, import ou dashboard. Les sources par mot-clé sont réservées à la plateforme.
evidenceobjectOptionnelObjet JSON libre (< 4 Ko) : texte présenté, url, ip, référence.
recorded_atstringOptionnelDate ISO 8601 de l'acte de la personne (défaut : maintenant).
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/consents
curl -X POST "https://api.envoisms.ma/v1/consents" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "cns_9f2a...",
  "phone": "+212612345678",
  "channel": "any",
  "purpose": "marketing",
  "status": "granted",
  "source": "form",
  "evidence": { "text": "J'accepte de recevoir les offres par WhatsApp", "url": "https://example.ma/inscription" },
  "recorded_at": "2026-09-01T10:00:00.000Z",
  "created_at": "2026-09-09T12:00:00.000Z"
}
DocsContacts/consents/:phone
GEThttps://api.envoisms.ma/v1/consents/:phone
Bearer Auth

État et historique d'un numéro

La réponse à « montrez-moi le consentement de cette personne » : l'état courant par finalité (dérivé de l'événement le plus récent, unknown sans historique, jamais présumé accordé), la présence sur la liste d'exclusion et l'historique complet.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/consents/:phone
curl -X GET "https://api.envoisms.ma/v1/consents/:phone" \
  -H "Authorization: Bearer smr_xxx"
{
  "phone": "+212612345678",
  "opted_out": true,
  "opted_out_at": "2026-09-05T09:00:00Z",
  "state": {
    "marketing": { "status": "withdrawn", "channel": "whatsapp", "source": "whatsapp_keyword", "recorded_at": "2026-09-05T09:00:00.000Z", "record_id": "cns_3" },
    "transactional": { "status": "unknown" },
    "otp": { "status": "unknown" },
    "service": { "status": "granted", "channel": "whatsapp", "source": "whatsapp_inbound", "recorded_at": "2026-07-01T09:00:00.000Z", "record_id": "cns_1" }
  },
  "history": []
}
DocsCampaigns/campaigns
GEThttps://api.envoisms.ma/v1/campaigns
Bearer Auth

Lister les campagnes

Récupère toutes vos campagnes d'envoi programmé ou de diffusion en cours.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/campaigns
curl -X GET "https://api.envoisms.ma/v1/campaigns" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "cmp_8d2a...",
      "name": "Soldes d'été 2026",
      "channel": "sms",
      "list_id": "lst_f84b...",
      "template_id": null,
      "body": "Bonjour {{name}}, profitez de -50% sur toute la collection avec le code ETE50 !",
      "sender_id": "SOLDES",
      "status": "draft",
      "scheduled_at": null,
      "created_at": "2026-06-01T12:00:00Z"
    }
  ]
}
DocsCampaigns/campaigns
POSThttps://api.envoisms.ma/v1/campaigns
Bearer Auth

Créer une campagne

Enregistre une nouvelle campagne en tant que brouillon ou la planifie à une date précise.

Corps de la requête (JSON)
ChampTypeStatutDescription
namestringRequisNom de la campagne.
bodystringRequisCorps du message. Peut utiliser la variable {{name}}. (L'un des deux requis : body ou template_id.)
template_idstringRequisAlternativement, ID d'un template approuvé. (L'un des deux requis : body ou template_id.)
channelstringOptionnel"sms" ou "whatsapp". Par défaut "sms".
list_idstringOptionnelID de la liste de contacts destinataire.
sender_idstringOptionnelNom d'expéditeur.
scheduled_atstringOptionnelDate de programmation (ISO 8601). Met le statut en "scheduled".
buttonsarrayOptionnelTableau de boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
metadataobjectOptionnelMétadonnées personnalisées (ex: options de throttling / cadence d'envoi : {"throttling": "50_min"}).
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/campaigns
curl -X POST "https://api.envoisms.ma/v1/campaigns" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Soldes d'été 2026",
    "body": "Bonjour {{name}}, profitez de -50% avec le code ETE50 !",
    "channel": "sms",
    "list_id": "lst_f84b...",
    "sender_id": "SOLDES"
  }'
{
  "id": "cmp_8d2a...",
  "status": "draft"
}
DocsCampaigns/campaigns/:id
GEThttps://api.envoisms.ma/v1/campaigns/:id
Bearer Auth

Détails d'une campagne

Récupère les détails, la planification et le statut d'exécution d'une campagne.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/campaigns/:id
curl -X GET "https://api.envoisms.ma/v1/campaigns/:id" \
  -H "Authorization: Bearer smr_xxx"
{
  "id": "cmp_8d2a...",
  "name": "Soldes d'été 2026",
  "channel": "sms",
  "list_id": "lst_f84b...",
  "body": "Bonjour {{name}}, profitez de -50%...",
  "sender_id": "SOLDES",
  "status": "running",
  "total_count": 1420,
  "sent_count": 840,
  "started_at": "2026-06-15T10:00:00Z",
  "created_at": "2026-06-01T12:00:00Z"
}
DocsCampaigns/campaigns/:id/send
POSThttps://api.envoisms.ma/v1/campaigns/:id/send
Bearer Auth

Lancer une campagne

Démarre immédiatement la diffusion d'une campagne de type brouillon vers tous les contacts associés.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/campaigns/:id/send
curl -X POST "https://api.envoisms.ma/v1/campaigns/:id/send" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "cmp_8d2a...",
  "queued": 1420,
  "total": 1420
}
DocsWebhooks/webhooks
GEThttps://api.envoisms.ma/v1/webhooks
Bearer Auth

Lister les webhooks

Récupère la liste de tous vos endpoints de webhooks enregistrés.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/webhooks
curl -X GET "https://api.envoisms.ma/v1/webhooks" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "whk_5f2b...",
      "url": "https://mon-serveur.ma/api/envoisms-receiver",
      "events": [
        "message.delivered",
        "message.failed"
      ],
      "active": true,
      "last_triggered_at": "2026-06-15T09:30:15Z",
      "last_status": 200,
      "created_at": "2026-05-01T10:00:00Z"
    }
  ]
}
DocsWebhooks/webhooks
POSThttps://api.envoisms.ma/v1/webhooks
Bearer Auth

Créer un Webhook

Enregistre une URL HTTPS de callback pour recevoir les notifications d'événements.

Corps de la requête (JSON)
ChampTypeStatutDescription
urlstringRequisURL cible sécurisée commençant par "https://".
eventsarrayOptionnelTableau d'événements (ex: ["message.delivered", "message.failed"]). Les jokers "message.*" et "*" sont acceptés. Défaut: ["message.delivered", "message.failed"].
secretstringOptionnelClé de signature secrète. Si non fournie, elle sera générée automatiquement.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/webhooks
curl -X POST "https://api.envoisms.ma/v1/webhooks" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mon-serveur.ma/api/envoisms-receiver",
    "events": [
      "message.delivered",
      "message.failed"
    ]
  }'
{
  "id": "whk_5f2b...",
  "url": "https://mon-serveur.ma/api/envoisms-receiver",
  "events": [
    "message.delivered",
    "message.failed"
  ],
  "secret": "whsec_2f8a9e7d...",
  "active": true
}
DocsWebhooks/webhooks/:id
PATCHhttps://api.envoisms.ma/v1/webhooks/:id
Bearer Auth

Modifier un Webhook

Met à jour la configuration d'un webhook (URL, événements surveillés ou état actif).

Corps de la requête (JSON)
ChampTypeStatutDescription
urlstringOptionnelNouvelle URL HTTPS.
eventsarrayOptionnelNouvelle liste d'événements abonnés.
activebooleanOptionnelActiver (true) ou désactiver (false) le webhook.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
PATCHhttps://api.envoisms.ma/v1/webhooks/:id
curl -X PATCH "https://api.envoisms.ma/v1/webhooks/:id" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mon-serveur.ma/api/envoisms-receiver-updated",
    "active": false
  }'
{
  "updated": true,
  "id": "whk_5f2b..."
}
DocsWebhooks/webhooks/:id
DELETEhttps://api.envoisms.ma/v1/webhooks/:id
Bearer Auth

Supprimer un Webhook

Désactive et supprime logiquement un endpoint de webhook.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
DELETEhttps://api.envoisms.ma/v1/webhooks/:id
curl -X DELETE "https://api.envoisms.ma/v1/webhooks/:id" \
  -H "Authorization: Bearer smr_xxx"
{
  "deleted": true,
  "id": "whk_5f2b..."
}
DocsWebhooks/webhooks/:id/test
POSThttps://api.envoisms.ma/v1/webhooks/:id/test
Bearer Auth

Tester un Webhook

Déclenche un événement de test ("message.test") vers l'URL configurée du webhook.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/webhooks/:id/test
curl -X POST "https://api.envoisms.ma/v1/webhooks/:id/test" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "queued": true,
  "id": "whk_5f2b..."
}
DocsWebhooks/inbound-webhooks
GEThttps://api.envoisms.ma/v1/inbound-webhooks
Bearer Auth

Lister les Inbound Webhooks

Récupère tous les endpoints de capture de leads publicitaires configurés sur votre compte.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/inbound-webhooks
curl -X GET "https://api.envoisms.ma/v1/inbound-webhooks" \
  -H "Authorization: Bearer smr_xxx"
{
  "webhooks": [
    {
      "id": "inw_9a8b...",
      "name": "Campagne TikTok Ads Casablanca",
      "source": "tiktok_ads",
      "catch_url": "https://api.envoisms.ma/v1/inbound-webhooks/catch/inw_9a8b...",
      "auto_start_funnel": true,
      "total_received": 142,
      "created_at": "2026-08-20T14:00:00Z"
    }
  ]
}
DocsWebhooks/inbound-webhooks
POSThttps://api.envoisms.ma/v1/inbound-webhooks
Bearer Auth

Créer un Inbound Webhook

Génère une URL de capture pour recevoir instantanément les prospects depuis TikTok Lead Ads, Meta Lead Ads, Zapier ou Make.

Corps de la requête (JSON)
ChampTypeStatutDescription
namestringRequisNom descriptif de la source (ex: "Facebook Lead Gen Promotion Été").
sourcestringOptionnelIdentifiant de source ("tiktok_ads", "meta_leads", "google_forms", "custom"). Défaut: "custom".
auto_start_funnelbooleanOptionnelSi true, déclenche immédiatement le funnel de qualification WhatsApp AtlasAI™ dès réception du lead.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/inbound-webhooks
curl -X POST "https://api.envoisms.ma/v1/inbound-webhooks" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "inw_9a8b...",
  "name": "Campagne TikTok Ads Casablanca",
  "catch_url": "https://api.envoisms.ma/v1/inbound-webhooks/catch/inw_9a8b...",
  "auto_start_funnel": true
}
DocsAPI Keys/api-keys
GEThttps://api.envoisms.ma/v1/api-keys
Bearer Auth

Lister les clés API

Récupère la liste de toutes vos clés d'API actives ou révoquées.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/api-keys
curl -X GET "https://api.envoisms.ma/v1/api-keys" \
  -H "Authorization: Bearer smr_xxx"
{
  "data": [
    {
      "id": "key_e84c...",
      "name": "Production Server",
      "key_prefix": "smr_a8f7d6c5",
      "sandbox": false,
      "ip_whitelist": [
        "196.200.1.4"
      ],
      "rate_limit": 100,
      "permissions": [
        "send",
        "verify",
        "status"
      ],
      "active": true,
      "last_used_at": "2026-06-15T10:30:00Z",
      "created_at": "2026-05-01T08:00:00Z"
    }
  ]
}
DocsAPI Keys/api-keys
POSThttps://api.envoisms.ma/v1/api-keys
Bearer Auth

Créer une clé API

Génère un nouveau jeton d'API sécurisé avec des permissions et restrictions spécifiques.

Corps de la requête (JSON)
ChampTypeStatutDescription
namestringOptionnelLibellé pour identifier la clé (défaut: "API key").
permissionsarrayOptionnelDroits accordés (send, verify, status, balance, contacts, campaigns, webhooks, billing, analytics, api_keys, optouts).
ip_whitelistarrayOptionnelListe d'adresses IP autorisées à exécuter des requêtes avec cette clé.
rate_limitintegerOptionnelLimite maximale de requêtes/min (de 10 à 2000). Défaut selon le palier : Starter 60, Business 180, Pro 500, Enterprise 1 200.
sandboxbooleanOptionneltrue génère une clé de test préfixée env_test_. Les requêtes sont validées et enregistrées, mais aucun message n'est réellement envoyé et rien n'est facturé. Le mode d'une clé est définitif : pour changer, créez une nouvelle clé.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/api-keys
curl -X POST "https://api.envoisms.ma/v1/api-keys" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Server",
    "permissions": [
      "send",
      "verify",
      "status"
    ],
    "ip_whitelist": [
      "196.200.1.4"
    ],
    "rate_limit": 100
  }'
{
  "id": "key_e84c...",
  "name": "Production Server",
  "key_prefix": "smr_a8f7d6c5",
  "api_key": "smr_a8f7d6c5b4a3...",
  "sandbox": false,
  "permissions": [
    "send",
    "verify",
    "status"
  ],
  "rate_limit": 100,
  "warning": "The full API key is shown once. Store it securely."
}
DocsAPI Keys/api-keys/:id
PATCHhttps://api.envoisms.ma/v1/api-keys/:id
Bearer Auth

Modifier une clé API

Met à jour les permissions, restrictions IP ou l'état d'activation d'une clé API.

Corps de la requête (JSON)
ChampTypeStatutDescription
namestringOptionnelNouveau nom.
permissionsarrayOptionnelNouvelle liste de permissions.
ip_whitelistarrayOptionnelNouvelle liste d'adresses IP autorisées.
rate_limitintegerOptionnelNouvelle limite de débit par minute.
activebooleanOptionnelActiver ou suspendre la clé.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
PATCHhttps://api.envoisms.ma/v1/api-keys/:id
curl -X PATCH "https://api.envoisms.ma/v1/api-keys/:id" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Backup Server",
    "active": true
  }'
{
  "updated": true,
  "id": "key_e84c..."
}
DocsAPI Keys/api-keys/:id
DELETEhttps://api.envoisms.ma/v1/api-keys/:id
Bearer Auth

Révoquer une clé API

Révoque définitivement une clé API pour l'empêcher d'authentifier les requêtes.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
DELETEhttps://api.envoisms.ma/v1/api-keys/:id
curl -X DELETE "https://api.envoisms.ma/v1/api-keys/:id" \
  -H "Authorization: Bearer smr_xxx"
{
  "revoked": true,
  "id": "key_e84c..."
}
DocsWhatsApp/whatsapp/profile
GEThttps://api.envoisms.ma/v1/whatsapp/profile
Bearer Auth

Profil WhatsApp Business

Consulte les informations publiques de votre profil WhatsApp Business vérifié (nom, photo, description, adresse, site web).

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/whatsapp/profile
curl -X GET "https://api.envoisms.ma/v1/whatsapp/profile" \
  -H "Authorization: Bearer smr_xxx"
{
  "about": "Service client officiel EnvoiSMS.ma",
  "address": "Casablanca, Maroc",
  "description": "Infrastructure de messagerie programmable pour les entreprises au Maroc.",
  "email": "[email protected]",
  "websites": [
    "https://votremarque.ma"
  ],
  "profile_picture_url": "https://pps.whatsapp.net/v/..."
}
DocsWhatsApp/whatsapp/profile
POSThttps://api.envoisms.ma/v1/whatsapp/profile
Bearer Auth

Mettre à jour le profil WhatsApp

Met à jour les informations visibles par vos clients sur votre profil WhatsApp Business officiel.

Corps de la requête (JSON)
ChampTypeStatutDescription
aboutstringOptionnelStatut textuel court (max 139 caractères).
descriptionstringOptionnelDescription détaillée de votre entreprise (max 512 caractères).
addressstringOptionnelAdresse physique de votre siège ou boutique.
emailstringOptionnelAdresse email de contact client.
websitesarrayOptionnelTableau contenant jusqu'à 2 URLs de votre site web.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/whatsapp/profile
curl -X POST "https://api.envoisms.ma/v1/whatsapp/profile" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "success": true,
  "updated_at": "2026-08-30T10:00:00Z"
}
DocsConversations/conversations
GEThttps://api.envoisms.ma/v1/conversations
Bearer Auth

Lister les conversations

Récupère la liste des discussions WhatsApp avec suivi en temps réel de la fenêtre de service 24h et statut du bot.

Paramètres Query
ParamètreTypeStatutDescription
limitintegerOptionnelNombre maximum de conversations à retourner (défaut 30, max 100).
bot_statusstringOptionnelFiltrer par statut bot ("active" ou "muted").
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/conversations
curl -X GET "https://api.envoisms.ma/v1/conversations?limit=50&offset=0" \
  -H "Authorization: Bearer smr_xxx"
{
  "conversations": [
    {
      "phone": "+212612345678",
      "contact_name": "Yassine Alami",
      "last_message": "Bonjour, je souhaite visiter l'appartement témoin",
      "last_message_at": "2026-08-30T11:42:00Z",
      "unread_count": 1,
      "bot_muted": true,
      "can_reply_free": true,
      "window_expires_at": "2026-08-31T11:42:00Z"
    }
  ],
  "total": 1
}
DocsConversations/conversations/:phone
GEThttps://api.envoisms.ma/v1/conversations/:phone
Bearer Auth

Historique d'une conversation

Récupère le fil complet des messages échangés avec un contact WhatsApp.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/conversations/:phone
curl -X GET "https://api.envoisms.ma/v1/conversations/:phone" \
  -H "Authorization: Bearer smr_xxx"
{
  "phone": "+212612345678",
  "contact_name": "Yassine Alami",
  "bot_muted": true,
  "messages": [
    {
      "id": "msg_01J...",
      "direction": "inbound",
      "body": "Je souhaite des informations sur le projet Casablanca Marina",
      "type": "text",
      "timestamp": "2026-08-30T11:40:00Z"
    },
    {
      "id": "msg_02J...",
      "direction": "outbound",
      "body": "Bonjour Yassine ! Quel type de bien recherchez-vous ?",
      "type": "interactive",
      "timestamp": "2026-08-30T11:40:05Z"
    }
  ]
}
DocsConversations/conversations/:phone/messages
POSThttps://api.envoisms.ma/v1/conversations/:phone/messages
Bearer Auth

Répondre en direct (Live Chat)

Envoie une réponse d'agent et met le bot en pause sur cette conversation (réactivation via POST /v1/conversations/:phone/toggle-bot). Un message WhatsApp libre exige que le contact ait écrit dans les dernières 24 h (sinon 400 OUT_OF_24H_WINDOW) ; un modèle approuvé peut être envoyé à tout moment.

Corps de la requête (JSON)
ChampTypeStatutDescription
messagestringOptionnelTexte de la réponse (ou légende du média joint). Obligatoire sans modèle ni média.
channelstringOptionnel"whatsapp" (défaut) ou "sms".
template_namestringOptionnelModèle WhatsApp approuvé à envoyer à la place d'un texte libre (avec template_language et variables).
media_urlstringOptionnelURL https (ou data URI) d'une image ou d'un PDF à joindre ; media_type "image" ou "document".
phone_number_idstringOptionnelNuméro WhatsApp connecté qui répond.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/conversations/:phone/messages
curl -X POST "https://api.envoisms.ma/v1/conversations/:phone/messages" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "ok": true,
  "message": {
    "id": "msg_03J...",
    "phone": "212612345678",
    "role": "agent",
    "message": "Bonjour Yassine, votre visite est confirmée.",
    "status": "sent",
    "channel": "whatsapp",
    "created_at": "2026-08-30T11:45:00Z"
  }
}
DocsLeads/qualified-leads
GEThttps://api.envoisms.ma/v1/qualified-leads
Bearer Auth

Lister les leads qualifiés

Récupère les prospects qualifiés automatiquement par AtlasAI™ avec leur score BANT et leur statut CRM.

Paramètres Query
ParamètreTypeStatutDescription
stagestringOptionnelFiltrer par étape ("new", "contacted", "meeting_scheduled", "closed_won", "closed_lost").
min_scoreintegerOptionnelScore BANT minimum (0 à 100).
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
Notes d'implémentation
  • Les leads sont qualifiés par AtlasAI™ Conversational Engine, AtlasAI™ Voice et AtlasAI™ Vision directement via les échanges WhatsApp entrants. Ces moteurs IA sont intégrés nativement à WABA et ne sont pas proposés comme API autonomes externes.
GEThttps://api.envoisms.ma/v1/qualified-leads
curl -X GET "https://api.envoisms.ma/v1/qualified-leads?limit=50&offset=0" \
  -H "Authorization: Bearer smr_xxx"
{
  "leads": [
    {
      "id": "lead_01J...",
      "phone": "+212612345678",
      "name": "Dr. Benjelloun",
      "preset": "medical_equipment",
      "bant_score": 85,
      "is_hot": true,
      "breakdown": {
        "budget": 25,
        "authority": 25,
        "need": 20,
        "timeline": 15
      },
      "intent": "Échographe Doppler pour nouveau cabinet",
      "stage": "meeting_scheduled",
      "created_at": "2026-08-30T09:15:00Z"
    }
  ],
  "total": 1
}
DocsLeads/qualified-leads/:id/status
POSThttps://api.envoisms.ma/v1/qualified-leads/:id/status
Bearer Auth

Mettre à jour le statut du lead

Met à jour le statut dans le pipeline commercial d'un prospect qualifié.

Corps de la requête (JSON)
ChampTypeStatutDescription
statusstringRequis"new" | "contacted" | "meeting_scheduled" | "closed_won" | "closed_lost"
notesstringOptionnelNotes internes de suivi commercial.
En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
POSThttps://api.envoisms.ma/v1/qualified-leads/:id/status
curl -X POST "https://api.envoisms.ma/v1/qualified-leads/:id/status" \
  -H "Authorization: Bearer smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "success": true,
  "lead_id": "lead_01J...",
  "stage": "meeting_scheduled"
}
DocsBilling/billing/balance
GEThttps://api.envoisms.ma/v1/billing/balance
Bearer Auth

Consulter le solde

Consulte le solde disponible en Dirhams Marocains (MAD) ainsi que la devise et le forfait actif.

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/billing/balance
curl -X GET "https://api.envoisms.ma/v1/billing/balance" \
  -H "Authorization: Bearer smr_xxx"
{
  "balance_mad": 1492.5,
  "currency": "MAD",
  "plan": "croissance"
}
DocsAnalytics/analytics
GEThttps://api.envoisms.ma/v1/analytics
Bearer Auth

Statistiques d'usage

Récupère des métriques clés sur vos envois (volumes totaux, taux de délivrabilité, et coûts facturés).

En-têtes HTTP requis
Authorization: Bearer env_test_d...
Content-Type: application/json
Accept: application/json
GEThttps://api.envoisms.ma/v1/analytics
curl -X GET "https://api.envoisms.ma/v1/analytics" \
  -H "Authorization: Bearer smr_xxx"
{
  "summary": {
    "total": 12840,
    "delivered": 12570,
    "delivery_rate": 97.9,
    "cost_mad": 2663.1
  }
}

Guide Webhooks

Webhooks DLR & Accusés de réception SMS en temps réel

EnvoiSMS.ma poste des événements JSON à l'URL HTTPS de votre serveur avec un en-tête X-EnvoiSMS.ma-Signature pour authentifier chaque rapport de livraison SMS.

message.sent

Le message a été accepté par le réseau de l'opérateur.

message.delivered

Le message a été remis avec succès au destinataire (SMS ou WhatsApp).

message.read

Le message WhatsApp a été ouvert et lu par le destinataire (deux coches bleues).

message.failed

Échec de livraison côté route ou soumission (rejet, erreur d'acheminement).

message.undeliverable

Le réseau a confirmé que le message ne peut pas être remis (numéro inexistant, expiré en file opérateur).

message.fallback

Cascade (cascade: true) : le message passe au canal suivant (ex. WhatsApp → SMS), parce que le premier a refusé ou signalé l'échec du message, ou n'a pas remis d'accusé de réception dans le délai cascade_timeout. channel donne le nouveau canal, previous_channel l'ancien, error_code et error_message la raison.

message.inbound

Un destinataire a répondu à l'un de vos messages SMS ou WhatsApp (inbound).

message.flow_response

Un utilisateur a validé et soumis un formulaire natif WhatsApp Flow.

message.location

Un utilisateur a partagé sa position géographique GPS sur WhatsApp.

lead.qualified

AtlasAI™ a terminé la qualification BANT d'un prospect sur WhatsApp.

contact.optout

Un destinataire s'est désabonné (mot-clé STOP ou assimilé).

Validation de Signature Webhook
import crypto from 'node:crypto';

// La signature arrive dans le header X-EnvoiSMS-Signature
// (format "sha256=<hex>"), l'événement dans X-EnvoiSMS-Event.
// Corps livré : { "event": "...", "data": { ... }, "timestamp": "..." }
export function verifySignature(body: string, sig: string, secret: string) {
  const hmac = crypto.createHmac('sha256', secret)
    .update(body)
    .digest('hex');

  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from('sha256=' + hmac));
}
OpenAPI Spec

Erreurs

Codes d'erreur et statuts de livraison de l'API SMS

Toutes les erreurs de l'API retournent un code HTTP approprié (4xx ou 5xx) ainsi qu'une enveloppe JSON prévisible contenant le code de l'erreur et une description claire.

{
  "error": {
    "code": "INVALID_PHONE",
    "message": "to must be E.164 format, for example +212612345678",
    "docs": "https://envoisms.ma/docs#errors"
  }
}
UNAUTHORIZED

Clé API manquante ou invalide.

INSUFFICIENT_BALANCE

Solde insuffisant pour effectuer l'envoi.

INVALID_PHONE

Le numéro de téléphone n'est pas au format E.164.

WHATSAPP_NOT_CONNECTED

Aucun numéro WhatsApp Business connecté : connectez le vôtre dans le tableau de bord pour envoyer sur WhatsApp.

OUT_OF_24H_WINDOW

Message WhatsApp libre vers un contact qui ne vous a pas écrit depuis plus de 24 h. Envoyez un modèle approuvé. Rien n'a été débité.

WHATSAPP_ONLY_FIELD

Un champ réservé à WhatsApp (reaction, contacts, location, sticker, context) a été envoyé sur un autre canal.

CONFLICTING_MESSAGE_TYPES

Un message porte un seul type de contenu : reaction, contacts, location ou sticker ne se combinent avec rien d'autre.

CASCADE_NOT_SUPPORTED

cascade est impossible avec une réaction, des contacts, une localisation ou un sticker : pas d'équivalent SMS.

INVALID_REACTION

reaction doit contenir le message_id (wamid) visé et un seul emoji (ou une chaîne vide pour retirer la réaction).

INVALID_CONTEXT

context doit contenir le message_id (wamid) du message cité, et ne se combine pas avec reaction.

INVALID_CONTACTS

contacts doit être un tableau de 1 à 20 fiches, chacune avec name.formatted_name ; le message indique la fiche fautive.

INVALID_LOCATION

location exige latitude (-90 à 90) et longitude (-180 à 180) numériques ; name et address sont facultatifs.

INVALID_MEDIA

Un média WhatsApp prend soit "id", soit "link" (URL https), jamais les deux ; pas de légende sur audio et sticker.

META_WINDOW_EXPIRED

Échec WhatsApp (131047) : la fenêtre de service de 24 h était fermée. Envoyez un modèle approuvé ou un SMS.

META_UNDELIVERABLE

Échec WhatsApp (131026) : le numéro n'est pas joignable sur WhatsApp. Pas de nouvel essai automatique.

META_MARKETING_LIMIT

Échec WhatsApp (131049) : limite de messages marketing par destinataire. Ne renvoyez pas tout de suite.

META_RATE_LIMITED

Échec WhatsApp (130429 débit du numéro, ou 131056 pour META_PAIR_RATE_LIMITED : trop de messages vers ce contact) après 3 essais automatiques.

META_POLICY_BLOCKED

Échec WhatsApp (368 ; aussi META_ACCOUNT_LOCKED 131031, META_PAYMENT_ISSUE 131042, META_PHONE_NOT_REGISTERED 133010) : numéro ou compte émetteur restreint. Vérifiez WhatsApp Manager.

META_TEMPLATE_NOT_FOUND

Échec WhatsApp (132001 ; aussi META_TEMPLATE_PARAM_MISMATCH 132000, META_TEMPLATE_PARAM_FORMAT 132012) : modèle introuvable dans cette langue ou variables incorrectes.

RATE_LIMITED

Limite de requêtes par minute dépassée. Respectez l'en-tête Retry-After.

INVALID_IDEMPOTENCY_KEY

L'en-tête Idempotency-Key dépasse 255 caractères.

IDEMPOTENCY_IN_FLIGHT

La requête originale portant cette Idempotency-Key est encore en cours. Réessayez dans un instant.

IDEMPOTENCY_KEY_REUSED

Cette Idempotency-Key a déjà été utilisée avec un corps de requête différent. Utilisez une nouvelle clé.

INVALID_CHANNEL

Le canal demandé n'existe pas. Canaux valides : sms, whatsapp, telegram, voice, rcs.

CHANNEL_NOT_CONFIGURED

Le canal demandé n'est pas disponible actuellement sur la plateforme.

CHANNEL_DISABLED

Le canal demandé est désactivé sur la plateforme.

FORBIDDEN

La clé API n'a pas la permission requise pour cette action, ou le compte est suspendu.

SENDER_ID_TOO_LONG

Le Sender ID dépasse la limite de 11 caractères.

SENDER_ID_INVALID

Le Sender ID contient des caractères non autorisés.

SENDER_ID_NOT_APPROVED

Le Sender ID n'a pas encore été approuvé par les opérateurs.

SENDER_ID_PENDING

Le Sender ID est en cours d'approbation.

SENDER_ID_REJECTED

Le Sender ID a été rejeté par les opérateurs.

MISSING_FIELD

Un champ obligatoire est manquant dans la requête.

CASCADE_TIMEOUT

Le premier canal a expiré, basculement vers le canal secondaire (cascade).

UPSTREAM_ERROR

Erreur de livraison au niveau de l'opérateur ou de la passerelle.

OPTED_OUT

Le numéro a refusé vos communications (STOP). Envoi interdit.

SPAM_OR_PHISHING_DETECTED

Le message contient un lien identifié comme hameçonnage ou spam. Envoi refusé.

CONTENT_BLOCKED

Le contenu du message a été bloqué par le contrôle anti-abus et le compte est suspendu en attente de revue. Contactez le support.

INVALID_CODE

Le code OTP soumis est incorrect. Le message d'erreur indique le nombre de tentatives restantes.

EXPIRED_CODE

Le code OTP a expiré. Demandez un nouveau code via /v1/verify/send.

MAX_ATTEMPTS

Nombre maximal de tentatives de vérification dépassé. La session est clôturée.

STRIPE_ERROR

La page de paiement n'a pas pu être créée de notre côté. Aucun débit n'a eu lieu — réessayez dans un instant.

INTERNAL_ERROR

Erreur interne de notre côté. Réessayez ; contactez le support si le problème persiste.

INVALID_PURPOSE

purpose doit être marketing, transactional, otp ou service.

INVALID_STATUS

status doit être granted ou withdrawn.

INVALID_CHANNEL

channel doit être whatsapp, sms ou any.

INVALID_SOURCE

source doit être api, form, import ou dashboard.

INVALID_EVIDENCE

evidence doit être un objet JSON de moins de 4 Ko.

INVALID_DATE

Une date n'est pas au format ISO 8601, ou recorded_at est dans le futur.

Limites

Limites de débit et quotas d'envoi SMS en production

OpenAPI YAML
Requêtes API

60 à 1 200 requêtes / minute par clé selon le palier (Starter 60, Business 180, Pro 500, Enterprise 1 200), relevable sur demande.

Taille Message

1600 caractères maximum par message.

Batch Bulk

Jusqu'à 10 000 messages par appel API.

Rétention Logs

90 jours pour les rapports détaillés.