Referencia de API

Documentación Técnica

Integre EnvoiSMS.ma en 15 minutos con nuestros SDKs para PHP, Node.js y Python.

Start here

Todo para comenzar antes de la primera solicitud.

EnvoiSMS.ma es una infraestructura de mensajería programable diseñada para Marruecos. Nuestras rutas directas con IAM, Inwi y Orange garantizan una latencia mínima.

URL basehttps://api.envoisms.ma
Versión API/v1 (Stable)
Formato de datosapplication/json; charset=utf-8
AutenticaciónAuthorization: Bearer env_live_xxx
Límite por defecto100 peticiones / minuto
Formato de númeroE.164 (ex: +212612345678)
Canales activosSMS Premium, WhatsApp API
LocalizaciónEn Marruecos — edge Cloudflare 🇲🇦
01

Genere su clave API "env_live_..." desde su Consola EnvoiSMS.ma.

02

Use la autenticación Bearer en sus cabeceras HTTP para cada petición.

03

Pruebe su integración con el modo Sandbox para no consumir créditos reales.

04

Integre WhatsApp Business API para reducir sus costes de OTP por 10.

05

Configure un Webhook firmado para recibir confirmaciones de entrega en tiempo real.

06

Siga su consumo y facturas de MAD directamente en su Panel de control.

Enviar su primer mensaje
// 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

Autenticación

Claves Bearer, headers y restricciones de seguridad.

Cada endpoint /v1 requiere una clave API válida transmitida en el header Authorization como token Bearer. Las claves de prueba y producción se pueden generar o revocar desde su consola.

Autorización

Authorization: Bearer env_live_xxx

Cabeceras de límite de tasa

X-RateLimit-Limit y X-RateLimit-Remaining se devuelven en cada llamada.

Listas de IP permitidas

Las peticiones de direcciones IP no configuradas devuelven un estado 401.

CORS Soportado

JSON, Authorization, X-EnvoiSMS.ma-Signature y X-EnvoiSMS.ma-Version están soportados.

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

Open Source

SDKs Oficiales y Librerías

Integre la API de EnvoiSMS en su aplicación con nuestras librerías de código abierto oficiales.

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
POST/v1/messages

Enviar un mensaje

Envía un mensaje transaccional o de marketing a través de SMS o WhatsApp Business API.

Request Body
tostringRequerido
Numéro de téléphone au format E.164 (+212...).
messagestringRequerido
Contenu textuel (max 1600 caractères). Également accepté sous le nom "body".
fromstringOpcional
Sender ID personnalisé (ex: NOM_MARQUE). Par défaut "ENVOISMS".
channelstringOpcional
"sms" ou "whatsapp". Par défaut "sms".
cascadebooleanOpcional
Si activé, tente de délivrer par WhatsApp et bascule automatiquement sur SMS en cas d'échec.
metadataobjectOpcional
Clés-valeurs personnalisées stockées avec le message et transmises dans les webhooks.
buttonsarrayOpcional
Tableau d'objets boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
Notes
  • 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 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
messagesarrayRequerido
Tableau d'objets contenant "to", "message" (ou "body"), et un objet facultatif "metadata".
fromstringOpcional
Sender ID global pour tout le lot.
channelstringOpcional
Canal global ("sms" ou "whatsapp"). Par défaut "sms".
Notes
  • 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 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

Enviar un mensaje

Envía un mensaje transaccional o de marketing a través de SMS o WhatsApp Business API.

Query Parameters
limitintegerOpcional
Nombre de résultats à retourner (1-200, défaut: 50).
offsetintegerOpcional
Nombre de résultats à ignorer pour la pagination (défaut: 0).
statusstringOpcional
Filtrer par statut (queued, sent, delivered, failed).
channelstringOpcional
Filtrer par canal (sms, whatsapp).
from_datestringOpcional
Filtrer par date de début (format ISO 8601).
to_datestringOpcional
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

Obtener estado del mensaje

Recupera el estado actual y los logs de entrega de un mensaje específico.

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"
}
GET/v1/templates

Lister les templates

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

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

Créer un template

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

Request Body
namestringRequerido
Nom interne du template.
channelstringRequerido
"sms" ou "whatsapp".
bodystringRequerido
Contenu du message avec variables (ex: {{1}}).
categorystringOpcional
Catégorie du template (ex: "otp", "marketing").
POSThttps://api.envoisms.ma/v1/templates
curl -X POST "https://api.envoisms.ma/v1/templates" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "tpl_1234...",
  "name": "otp_verification",
  "status": "pending"
}
GET/v1/sender-ids

Lister les Sender IDs

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

GEThttps://api.envoisms.ma/v1/sender-ids
curl -X GET "https://api.envoisms.ma/v1/sender-ids" \
  -H "Authorization: Bearer env_live_xxx"
{
  "data": [
    {
      "id": "sid_9a8b...",
      "sender_id": "MABANQUE",
      "status": "approved",
      "requested_at": "2026-05-10T09:00:00Z"
    }
  ]
}
POST/v1/sender-ids

Demander un Sender ID

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

Request Body
sender_idstringRequerido
Le nom d'expéditeur souhaité (max 11 caractères).
rc_urlstringOpcional
Lien vers le Registre de Commerce pour vérification.
POSThttps://api.envoisms.ma/v1/sender-ids
curl -X POST "https://api.envoisms.ma/v1/sender-ids" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "sid_9a8b...",
  "sender_id": "MABANQUE",
  "status": "pending"
}
POST/v1/verify/send

Enviar un código OTP

Envía un código de verificación de un solo uso. Dos modos a elegir: "whatsapp" — verificación gestionada, la más simple y económica (EnvoiSMS genera el código, lo entrega por WhatsApp desde un remitente verificado y pasa automáticamente a SMS si no se confirma en 60 s; nada que almacenar de su lado — code_length, expiry y template se ignoran en este modo: el código es siempre de 6 dígitos, válido 5 minutos) — o "sms" — usted mantiene el control total del código, la plantilla y el remitente. Ambos modos se validan con la misma llamada /v1/verify/check. ¿Quiere su propia marca en el respaldo SMS de la verificación gestionada? Disponible bajo petición: [email protected].

Request Body
tostringRequerido
Destinataire au format E.164.
channelstringOpcional
"whatsapp" (vérification gérée : WhatsApp puis SMS automatique, code valide 5 min, 3 essais, facturée au tarif WhatsApp par vérification — le plus économique) ou "sms" (code généré pour vous, envoyé avec votre marque). Défaut: "sms".
app_idstringOpcional
ID 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.
brandstring (Optionnel, canal sms)Opcional
Nom de la marque affiché (ex: MonApp, max 32 car.). Par défaut "EnvoiSMS".
code_lengthinteger (Optionnel, canal sms)Opcional
Longueur du code généré (de 4 à 8 chiffres, défaut: 6).
expiryinteger (Optionnel, canal sms)Opcional
Durée de validité du code en secondes (de 60 à 1800, défaut: 600).
cascadearray (Optionnel, canal sms)Opcional
Liste ordonnée de canaux pour le basculement automatique en cascade (ex: ["sms", "voice"]).
templatestring (Optionnel, canal sms)Opcional
Texte personnalisé avec les variables {{code}} et {{brand}}. En mode whatsapp, le message localisé (fr/en/es) est géré pour vous.
otp_button_textstring (Optionnel, canal sms)Opcional
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...",
  "to": "+212612345678",
  "channel": "whatsapp",
  "expires_at": "2026-05-15T10:35:00Z",
  "status": "sent",
  "cost": { "eur": 0.025, "mad": 0.275 }
}
POST/v1/verify/check

Verificar un OTP

Valida el código ingresado por el usuario para una sesión de verificación determinada.

Request Body
session_idstringRequerido
ID de session reçu lors de l'appel à /v1/verify/send.
codestringRequerido
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

Estado de la sesión OTP

Recupera el estado (validado o expirado) de una sesión de verificación específica.

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

Validación de número

Valida el formato, operador de red, tipo de línea y ubicación geográfica de un número de teléfono.

Request Body
numberstringRequerido
Le numéro de téléphone à valider (format local ou international).
country_codestringOpcional
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

Listar contactos

Recupera contactos con búsqueda opcional por palabras clave o filtrado por lista.

Query Parameters
limitintegerOpcional
Résultats par page (1-500, défaut: 100).
offsetintegerOpcional
Pagination offset (défaut: 0).
qstringOpcional
Recherche par nom, téléphone ou email.
list_idstringOpcional
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

Listar contactos

Recupera contactos con búsqueda opcional por palabras clave o filtrado por lista.

Request Body
phonestringRequerido
Numéro de téléphone au format E.164.
namestringOpcional
Nom complet du contact.
emailstringOpcional
Adresse email.
list_idstringOpcional
Associer immédiatement le contact à une liste existante.
custom_fieldsobjectOpcional
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
contactsarrayRequerido
Tableau d'objets contenant "phone", "name" (optionnel) et "email" (optionnel).
list_idstringOpcional
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
namestringRequerido
Nom de la liste.
descriptionstringOpcional
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/optouts

Lister les désinscriptions

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

GEThttps://api.envoisms.ma/v1/optouts
curl -X GET "https://api.envoisms.ma/v1/optouts" \
  -H "Authorization: Bearer env_live_xxx"
{
  "data": [
    {
      "phone": "+212611111111",
      "opted_out_at": "2026-06-01T12:00:00Z"
    }
  ],
  "total": 1
}
POST/v1/optouts

Ajouter une désinscription

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

Request Body
phonestringRequerido
Numéro de téléphone au format E.164.
POSThttps://api.envoisms.ma/v1/optouts
curl -X POST "https://api.envoisms.ma/v1/optouts" \
  -H "Authorization: Bearer env_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "success": true,
  "phone": "+212611111111",
  "opted_out_at": "2026-06-01T12:00:00Z"
}
DELETE/v1/optouts/:phone

Retirer une désinscription

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

DELETEhttps://api.envoisms.ma/v1/optouts/:phone
curl -X DELETE "https://api.envoisms.ma/v1/optouts/:phone" \
  -H "Authorization: Bearer env_live_xxx"
{
  "deleted": true,
  "phone": "+212611111111"
}
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
namestringRequerido
Nom de la campagne.
bodystring (Requis*)Requerido
Corps du message. Peut utiliser la variable {{name}}.
template_idstring (Requis*)Requerido
Alternativement, ID d'un template approuvé. (*L'un des deux requis).
channelstringOpcional
"sms" ou "whatsapp". Par défaut "sms".
list_idstringOpcional
ID de la liste de contacts destinataire.
sender_idstringOpcional
Nom d'expéditeur.
scheduled_atstringOpcional
Date de programmation (ISO 8601). Met le statut en "scheduled".
buttonsarrayOpcional
Tableau de boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
metadataobjectOpcional
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
urlstringRequerido
URL cible sécurisée commençant par "https://".
eventsarrayOpcional
Tableau d'événements (ex: ["message.delivered", "message.failed"]). Défaut: tous.
secretstringOpcional
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
urlstringOpcional
Nouvelle URL HTTPS.
eventsarrayOpcional
Nouvelle liste d'événements abonnés.
activebooleanOpcional
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
namestringOpcional
Libellé pour identifier la clé (défaut: "API key").
permissionsarrayOpcional
Droits accordés (send, verify, status, balance, contacts, campaigns, webhooks, billing, analytics, api_keys, optouts).
ip_whitelistarrayOpcional
Liste d'adresses IP autorisées à exécuter des requêtes avec cette clé.
rate_limitintegerOpcional
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
namestringOpcional
Nouveau nom.
permissionsarrayOpcional
Nouvelle liste de permissions.
ip_whitelistarrayOpcional
Nouvelle liste d'adresses IP autorisées.
rate_limitintegerOpcional
Nouvelle limite de débit par minute.
activebooleanOpcional
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
  }
}

Guía de Webhooks

Callbacks de entrega firmados y seguros.

EnvoiSMS.ma envía eventos JSON a la URL HTTPS de su servidor con un encabezado X-EnvoiSMS.ma-Signature para autenticar al remitente.

message.delivered

Se activa cuando el operador confirma la entrega exitosa en el dispositivo del destinatario.

message.failed

Se activa cuando falla la entrega (número inválido, expirado, rechazado por el operador).

message.expired

Se activa cuando el mensaje expira en la cola del operador.

message.inbound

Se activa cuando un destinatario responde con un message de texto (SMS entrante).

contact.optout

Se activa cuando un destinatario se da de baja utilizando la palabra clave STOP o similar.

verify.success

Se activa inmediatamente cuando una sesión OTP se valida correctamente con un código correcto.

Validación de firma
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

Errores

Estructura de las respuestas de error de la API.

Todos los errores de la API devuelven un código HTTP adecuado (4xx o 5xx) junto con una estructura JSON predecible que contiene el código de error y la descripción.

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

La clave API falta o no es válida. Verifique su token Bearer en las cabeceras.

INSUFFICIENT_BALANCE

Solde insuffisant pour effectuer l'envoi.

INVALID_PHONE

El formato del número de destino no es válido. Use el estándar E.164.

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.

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.

Límites

Restricciones y cuotas en el entorno de producción.

OpenAPI YAML
Peticiones API

100 peticiones / minuto (escalable bajo demanda).

Tamaño del mensaje

1600 caracteres máximo por mensaje.

Lote masivo

Hasta 10,000 mensajes por llamada API.

Retención de logs

90 días para informes detallados.