API Reference

Technical Documentation

Integrate EnvoiSMS.ma in under 15 minutes with our PHP, Node.js, and Python SDKs. Built for engineers.

Start here

Everything to get started before your first request.

EnvoiSMS.ma is a programmable messaging infrastructure built for Morocco. Our direct carrier routes with IAM, Inwi, and Orange guarantee minimal latency.

Base URLhttps://api.envoisms.ma
API Version/v1 (Stable)
Data Formatapplication/json; charset=utf-8
AuthenticationAuthorization: Bearer env_live_xxx
Default Rate Limit100 requests / minute
Number FormatE.164 (ex: +212612345678)
Active ChannelsPremium SMS, WhatsApp API
LocationHosted in Morocco 🇲🇦
01

Generate your "env_live_..." API key from your EnvoiSMS.ma Console.

02

Use Bearer authentication in your HTTP headers for each request.

03

Test your integration using Sandbox mode to consume no real credits.

04

Integrate the WhatsApp Business API to divide your OTP costs by 10.

05

Configure a signed Webhook to receive delivery reports in real time.

06

Track your consumption and MAD invoices directly on your Dashboard.

Send your first message
// 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

Authentication

Bearer keys, headers, and security constraints.

Each /v1 endpoint requires a valid API key passed in the Authorization header as a Bearer token. Test and production keys can be generated or revoked from your console.

Authorization

Authorization: Bearer env_live_xxx

Rate Limit Headers

X-RateLimit-Limit and X-RateLimit-Remaining returned with each call.

IP Allowlists

Requests coming from unconfigured IP addresses return a 401 status.

CORS Supported

JSON, Authorization, X-EnvoiSMS.ma-Signature, and X-EnvoiSMS.ma-Version are supported.

HTTP Headers Example
POST /v1/messages HTTP/1.1
Host: api.envoisms.ma
Authorization: Bearer env_live_xxxxxxxx
Content-Type: application/json
Accept: application/json
POST/v1/messages

Send a message

Sends a transaction or marketing message via SMS or WhatsApp Business API.

Request Body
tostringRequired
Numéro de téléphone au format E.164 (+212...).
messagestringRequired
Contenu textuel (max 1600 caractères). Également accepté sous le nom "body".
fromstringOptional
Sender ID personnalisé (ex: NOM_MARQUE). Par défaut "ENVOISMS".
channelstringOptional
"sms" ou "whatsapp". Par défaut "sms".
cascadebooleanOptional
Si activé, tente de délivrer par WhatsApp et bascule automatiquement sur SMS en cas d'échec.
metadataobjectOptional
Clés-valeurs personnalisées stockées avec le message et transmises dans les webhooks.
buttonsarrayOptional
Tableau d'objets boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
POSThttps://api.envoisms.ma/v1/messages
curl -X POST "https://api.envoisms.ma/v1/messages" \
  -H "Authorization: Bearer env_live_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.0118,
    "mad": 0.13
  },
  "segments": 1,
  "created_at": "2026-05-15T10:30:00Z"
}
POST/v1/messages/bulk

Envoi groupé (Bulk)

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

Request Body
messagesarrayRequired
Tableau d'objets contenant "to", "message" (ou "body"), et un objet facultatif "metadata".
fromstringOptional
Sender ID global pour tout le lot.
channelstringOptional
Canal global ("sms" ou "whatsapp"). Par défaut "sms".
POSThttps://api.envoisms.ma/v1/messages/bulk
curl -X POST "https://api.envoisms.ma/v1/messages/bulk" \
  -H "Authorization: Bearer env_live_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"
    }
  ]
}
GET/v1/messages

Send a message

Sends a transaction or marketing message via SMS or WhatsApp Business API.

Query Parameters
limitintegerOptional
Nombre de résultats à retourner (1-200, défaut: 50).
offsetintegerOptional
Nombre de résultats à ignorer pour la pagination (défaut: 0).
statusstringOptional
Filtrer par statut (queued, sent, delivered, failed).
channelstringOptional
Filtrer par canal (sms, whatsapp).
from_datestringOptional
Filtrer par date de début (format ISO 8601).
to_datestringOptional
Filtrer par date de fin (format ISO 8601).
GEThttps://api.envoisms.ma/v1/messages
curl -X GET "https://api.envoisms.ma/v1/messages?limit=50&offset=0" \
  -H "Authorization: Bearer env_live_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
}
GET/v1/messages/:id

Get message status

Retrieves the current status and delivery logs of a specific message.

GEThttps://api.envoisms.ma/v1/messages/:id
curl -X GET "https://api.envoisms.ma/v1/messages/:id" \
  -H "Authorization: Bearer env_live_xxx"
{
  "id": "msg_8f2d...",
  "account_id": "acc_3f1a...",
  "api_key_id": "key_e84c...",
  "campaign_id": null,
  "to": "+212612345678",
  "channel": "whatsapp",
  "body": "Votre code de validation est 849204",
  "sender_id": "MaBanque",
  "unicode": 0,
  "segments": 1,
  "status": "delivered",
  "cost_eur": 0.0118,
  "cost_mad": 0.13,
  "metadata": "{\"purpose\": \"otp\"}",
  "created_at": "2026-05-15T10:30:00Z"
}
POST/v1/verify/send

Send an OTP code

Initiates a verification session by sending a secure OTP code via WhatsApp or SMS.

Request Body
tostringRequired
Destinataire au format E.164.
brandstringOptional
Nom de la marque affiché (ex: MonApp, max 32 car.). Par défaut "EnvoiSMS".
channelstringOptional
"whatsapp" (recommandé pour diviser les coûts par 10) ou "sms". Défaut: "sms".
code_lengthintegerOptional
Longueur du code généré (de 4 à 8 chiffres, défaut: 6).
expiryintegerOptional
Durée de validité du code en secondes (de 60 à 1800, défaut: 600).
templatestringOptional
Texte personnalisé avec les variables {{code}} et {{brand}}.
otp_button_textstringOptional
Libellé personnalisé pour le bouton de copie automatique WhatsApp (max 25 car.).
POSThttps://api.envoisms.ma/v1/verify/send
curl -X POST "https://api.envoisms.ma/v1/verify/send" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+212612345678",
    "brand": "MonApp",
    "channel": "whatsapp",
    "code_length": 6,
    "expiry": 600
  }'
{
  "session_id": "vrf_7e2a...",
  "message_id": "msg_1b8e...",
  "to": "+212612345678",
  "channel": "whatsapp",
  "expires_at": "2026-05-15T10:40:00Z",
  "status": "sent"
}
POST/v1/verify/check

Verify an OTP

Validates the code entered by the user for a given verification session.

Request Body
session_idstringRequired
ID de session reçu lors de l'appel à /v1/verify/send.
codestringRequired
Le code reçu et saisi par l'utilisateur.
POSThttps://api.envoisms.ma/v1/verify/check
curl -X POST "https://api.envoisms.ma/v1/verify/check" \
  -H "Authorization: Bearer env_live_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"
}
GET/v1/verify/:id

OTP session status

Retrieves the status (validated or expired) of a specific verification session.

GEThttps://api.envoisms.ma/v1/verify/:id
curl -X GET "https://api.envoisms.ma/v1/verify/:id" \
  -H "Authorization: Bearer env_live_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"
}
POST/v1/verify/lookup

Number Lookup

Validates the format, carrier network, line type, and geographic location of a phone number.

Request Body
numberstringRequired
Le numéro de téléphone à valider (format local ou international).
country_codestringOptional
Code pays ISO à 2 lettres (ex: MA, FR). Recommandé si le numéro est au format local.
POSThttps://api.envoisms.ma/v1/verify/lookup
curl -X POST "https://api.envoisms.ma/v1/verify/lookup" \
  -H "Authorization: Bearer env_live_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"
}
GET/v1/contacts

List contacts

Retrieves contacts with optional keyword search or contact list filtering.

Query Parameters
limitintegerOptional
Résultats par page (1-500, défaut: 100).
offsetintegerOptional
Pagination offset (défaut: 0).
qstringOptional
Recherche par nom, téléphone ou email.
list_idstringOptional
Filtrer uniquement les membres d'une liste de contacts spécifique.
GEThttps://api.envoisms.ma/v1/contacts
curl -X GET "https://api.envoisms.ma/v1/contacts?limit=50&offset=0" \
  -H "Authorization: Bearer env_live_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
}
POST/v1/contacts

List contacts

Retrieves contacts with optional keyword search or contact list filtering.

Request Body
phonestringRequired
Numéro de téléphone au format E.164.
namestringOptional
Nom complet du contact.
emailstringOptional
Adresse email.
list_idstringOptional
Associer immédiatement le contact à une liste existante.
custom_fieldsobjectOptional
Objet contenant jusqu'à 3 champs personnalisés ("custom1", "custom2", "custom3").
POSThttps://api.envoisms.ma/v1/contacts
curl -X POST "https://api.envoisms.ma/v1/contacts" \
  -H "Authorization: Bearer env_live_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"
}
POST/v1/contacts/import

Importer des contacts

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

Request Body
contactsarrayRequired
Tableau d'objets contenant "phone", "name" (optionnel) et "email" (optionnel).
list_idstringOptional
ID de la liste dans laquelle importer le groupe.
POSThttps://api.envoisms.ma/v1/contacts/import
curl -X POST "https://api.envoisms.ma/v1/contacts/import" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "phone": "+212611111111",
        "name": "Karim"
      },
      {
        "phone": "+212622222222",
        "name": "Youssef"
      }
    ],
    "list_id": "lst_f84b..."
  }'
{
  "imported": 150,
  "skipped": 3
}
DELETE/v1/contacts/:id

Supprimer un contact

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

DELETEhttps://api.envoisms.ma/v1/contacts/:id
curl -X DELETE "https://api.envoisms.ma/v1/contacts/:id" \
  -H "Authorization: Bearer env_live_xxx"
{
  "deleted": true,
  "id": "ctc_a2b3..."
}
GET/v1/contacts/lists

Lister les listes

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

GEThttps://api.envoisms.ma/v1/contacts/lists
curl -X GET "https://api.envoisms.ma/v1/contacts/lists" \
  -H "Authorization: Bearer env_live_xxx"
{
  "data": [
    {
      "id": "lst_f84b...",
      "name": "Newsletter Clients",
      "description": "Clients inscrits à notre lettre d'information",
      "count": 1420,
      "created_at": "2026-04-15T09:00:00Z"
    }
  ]
}
POST/v1/contacts/lists

Créer une liste

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

Request Body
namestringRequired
Nom de la liste.
descriptionstringOptional
Description de la liste.
POSThttps://api.envoisms.ma/v1/contacts/lists
curl -X POST "https://api.envoisms.ma/v1/contacts/lists" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Newsletter Clients",
    "description": "Clients inscrits"
  }'
{
  "id": "lst_f84b...",
  "name": "Newsletter Clients",
  "description": "Clients inscrits",
  "count": 0
}
GET/v1/campaigns

Lister les campagnes

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

GEThttps://api.envoisms.ma/v1/campaigns
curl -X GET "https://api.envoisms.ma/v1/campaigns" \
  -H "Authorization: Bearer env_live_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"
    }
  ]
}
POST/v1/campaigns

Créer une campagne

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

Request Body
namestringRequired
Nom de la campagne.
bodystring (Requis*)Required
Corps du message. Peut utiliser la variable {{name}}.
template_idstring (Requis*)Required
Alternativement, ID d'un template approuvé. (*L'un des deux requis).
channelstringOptional
"sms" ou "whatsapp". Par défaut "sms".
list_idstringOptional
ID de la liste de contacts destinataire.
sender_idstringOptional
Nom d'expéditeur.
scheduled_atstringOptional
Date de programmation (ISO 8601). Met le statut en "scheduled".
buttonsarrayOptional
Tableau de boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
metadataobjectOptional
Métadonnées personnalisées (ex: options de throttling / cadence d'envoi : {"throttling": "50_min"}).
POSThttps://api.envoisms.ma/v1/campaigns
curl -X POST "https://api.envoisms.ma/v1/campaigns" \
  -H "Authorization: Bearer env_live_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"
}
GET/v1/campaigns/:id

Détails d'une campagne

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

GEThttps://api.envoisms.ma/v1/campaigns/:id
curl -X GET "https://api.envoisms.ma/v1/campaigns/:id" \
  -H "Authorization: Bearer env_live_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"
}
POST/v1/campaigns/:id/send

Lancer une campagne

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

POSThttps://api.envoisms.ma/v1/campaigns/:id/send
curl -X POST "https://api.envoisms.ma/v1/campaigns/:id/send" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "cmp_8d2a...",
  "queued": 1420,
  "total": 1420
}
GET/v1/webhooks

Lister les webhooks

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

GEThttps://api.envoisms.ma/v1/webhooks
curl -X GET "https://api.envoisms.ma/v1/webhooks" \
  -H "Authorization: Bearer env_live_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"
    }
  ]
}
POST/v1/webhooks

Créer un Webhook

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

Request Body
urlstringRequired
URL cible sécurisée commençant par "https://".
eventsarrayOptional
Tableau d'événements (ex: ["message.delivered", "message.failed"]). Défaut: tous.
secretstringOptional
Clé de signature secrète. Si non fournie, elle sera générée automatiquement.
POSThttps://api.envoisms.ma/v1/webhooks
curl -X POST "https://api.envoisms.ma/v1/webhooks" \
  -H "Authorization: Bearer env_live_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
}
PATCH/v1/webhooks/:id

Modifier un Webhook

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

Request Body
urlstringOptional
Nouvelle URL HTTPS.
eventsarrayOptional
Nouvelle liste d'événements abonnés.
activebooleanOptional
Activer (true) ou désactiver (false) le webhook.
PATCHhttps://api.envoisms.ma/v1/webhooks/:id
curl -X PATCH "https://api.envoisms.ma/v1/webhooks/:id" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mon-serveur.ma/api/envoisms-receiver-updated",
    "active": false
  }'
{
  "updated": true,
  "id": "whk_5f2b..."
}
DELETE/v1/webhooks/:id

Supprimer un Webhook

Désactive et supprime logiquement un endpoint de webhook.

DELETEhttps://api.envoisms.ma/v1/webhooks/:id
curl -X DELETE "https://api.envoisms.ma/v1/webhooks/:id" \
  -H "Authorization: Bearer env_live_xxx"
{
  "deleted": true,
  "id": "whk_5f2b..."
}
POST/v1/webhooks/:id/test

Tester un Webhook

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

POSThttps://api.envoisms.ma/v1/webhooks/:id/test
curl -X POST "https://api.envoisms.ma/v1/webhooks/:id/test" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "queued": true,
  "id": "whk_5f2b..."
}
GET/v1/api-keys

Lister les clés API

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

GEThttps://api.envoisms.ma/v1/api-keys
curl -X GET "https://api.envoisms.ma/v1/api-keys" \
  -H "Authorization: Bearer env_live_xxx"
{
  "data": [
    {
      "id": "key_e84c...",
      "name": "Production Server",
      "key_prefix": "env_live",
      "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"
    }
  ]
}
POST/v1/api-keys

Créer une clé API

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

Request Body
namestringOptional
Libellé pour identifier la clé (défaut: "API key").
permissionsarrayOptional
Droits accordés (send, verify, status, balance, contacts, campaigns, webhooks, billing, analytics, api_keys, optouts).
ip_whitelistarrayOptional
Liste d'adresses IP autorisées à exécuter des requêtes avec cette clé.
rate_limitintegerOptional
Limite maximale de requêtes/min (de 10 à 1000, défaut: 100).
POSThttps://api.envoisms.ma/v1/api-keys
curl -X POST "https://api.envoisms.ma/v1/api-keys" \
  -H "Authorization: Bearer env_live_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": "env_live",
  "api_key": "env_live_a8f7d6c5b4a3...",
  "permissions": [
    "send",
    "verify",
    "status"
  ],
  "rate_limit": 100,
  "warning": "The full API key is shown once. Store it securely."
}
PATCH/v1/api-keys/:id

Modifier une clé API

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

Request Body
namestringOptional
Nouveau nom.
permissionsarrayOptional
Nouvelle liste de permissions.
ip_whitelistarrayOptional
Nouvelle liste d'adresses IP autorisées.
rate_limitintegerOptional
Nouvelle limite de débit par minute.
activebooleanOptional
Activer ou suspendre la clé.
PATCHhttps://api.envoisms.ma/v1/api-keys/:id
curl -X PATCH "https://api.envoisms.ma/v1/api-keys/:id" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Backup Server",
    "active": true
  }'
{
  "updated": true,
  "id": "key_e84c..."
}
DELETE/v1/api-keys/:id

Révoquer une clé API

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

DELETEhttps://api.envoisms.ma/v1/api-keys/:id
curl -X DELETE "https://api.envoisms.ma/v1/api-keys/:id" \
  -H "Authorization: Bearer env_live_xxx"
{
  "revoked": true,
  "id": "key_e84c..."
}
GET/v1/billing/balance

Consulter le solde

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

GEThttps://api.envoisms.ma/v1/billing/balance
curl -X GET "https://api.envoisms.ma/v1/billing/balance" \
  -H "Authorization: Bearer env_live_xxx"
{
  "balance_mad": 1492.5,
  "currency": "MAD",
  "plan": "croissance"
}
GET/v1/analytics

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).

GEThttps://api.envoisms.ma/v1/analytics
curl -X GET "https://api.envoisms.ma/v1/analytics" \
  -H "Authorization: Bearer env_live_xxx"
{
  "summary": {
    "total": 12840,
    "delivered": 12570,
    "delivery_rate": 97.9,
    "cost_mad": 2663.1
  }
}

Webhooks Guide

Signed and secure delivery callbacks.

EnvoiSMS.ma posts JSON events to your server's HTTPS URL with an X-EnvoiSMS.ma-Signature header to authenticate the sender.

message.delivered

Triggered when the operator confirms successful delivery to the recipient's device.

message.failed

Triggered when delivery fails (invalid number, expired, rejected by carrier).

message.expired

Le message a expiré dans la file d'attente opérateur.

verify.success

Triggered immediately when an OTP session is successfully validated by a correct code.

Signature Validation
import crypto from 'node:crypto';

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

Errors

API error response structure.

All API errors return an appropriate HTTP code (4xx or 5xx) along with a predictable JSON envelope containing the error code and description.

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

The API key is missing or invalid. Verify your Bearer token in the headers.

INSUFFICIENT_BALANCE

Solde insuffisant pour effectuer l'envoi.

INVALID_PHONE

The recipient number format is invalid. Use E.164 standard.

RATE_LIMITED

Limite de requêtes par minute dépassée.

CHANNEL_NOT_ALLOWED

Le canal demandé (ex: WhatsApp) n'est pas activé sur votre compte.

Limits

Constraints and quotas in the production environment.

OpenAPI YAML
API Requests

100 requests / minute (scalable upon request).

Message Size

1600 characters maximum per message.

Bulk Batch

Up to 10,000 messages per API call.

Log Retention

90 days for detailed reports.