مرجع واجهة البرمجة (API)

التوثيق التقني

ادمج خدمات EnvoiSMS.ma في أقل من 15 دقيقة باستخدام مكتباتنا للغات PHP و Node.js و Python. مصمم للمطورين المحترفين.

Start here

كل ما تحتاجه للبدء قبل طلبك الأول.

EnvoiSMS.ma هي بنية تحتية للرسائل المبرمجة للمغرب. تضمن مساراتنا المباشرة مع شركات الاتصالات IAM و Inwi و Orange زمن وصول فوري.

عنوان URL الأساسيhttps://api.envoisms.ma
إصدار واجهة البرمجة/v1 (Stable)
تنسيق البياناتapplication/json; charset=utf-8
المصادقةAuthorization: Bearer smr_xxx
الحد الافتراضي100 طلب / دقيقة
تنسيق الأرقامE.164 (ex: +212612345678)
القنوات النشطةالرسائل الممتازة، واتساب
الموقعفي المغرب — شبكة Cloudflare الطرفية 🇲🇦
01

قم بتوليد مفتاح واجهة برمجة التطبيقات "smr_..." من لوحة التحكم الخاصة بك.

02

استخدم مصادقة Bearer في ترويسات HTTP الخاصة بك لكل طلب.

03

اختبر الربط عبر بيئة الاختبار Sandbox لتجنب استهلاك أي رصيد حقيقي.

04

ادمج واجهة واتساب للأعمال لتقليل تكلفة رسائل التحقق (OTP) بمقدار 10 مرات.

05

قم بتهيئة ويب هوك (Webhook) موقع لاستلام تقارير التسليم في الوقت الفعلي.

06

تابع استهلاكك وفواتيرك بالدرهم المغربي مباشرة من لوحة التحكم.

إرسال رسالتك الأولى
// 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

المصادقة

مفاتيح Bearer والرؤوس والقيود الأمنية.

يتطلب كل مسار /v1 مفتاح واجهة برمجة تطبيقات صالحًا يتم تمريره في ترويسة Authorization كرمز Bearer. يمكن توليد أو إلغاء مفاتيح الاختبار والإنتاج من وحدة التحكم الخاصة بك.

المصادقة

Authorization: Bearer smr_xxx

ترووسات حدود الطلبات

يتم إرجاع X-RateLimit-Limit و X-RateLimit-Remaining مع كل طلب.

القوائم المسموحة لعناوين IP

الطلبات الواردة من عناوين IP غير المهيأة ترجع حالة 401.

دعم CORS

يتم دعم JSON و Authorization و X-EnvoiSMS.ma-Signature و X-EnvoiSMS.ma-Version.

مثال على ترويسات HTTP
POST /v1/messages HTTP/1.1
Host: api.envoisms.ma
Authorization: Bearer smr_xxxxxxxx
Content-Type: application/json
Accept: application/json

Open Source

حزم SDK الرسمية والمكتبات البرمجية

قم بربط واجهة برمجة EnvoiSMS في تطبيقك بسهولة باستخدام مكتباتنا البرمجية المفتوحة المصدر.

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

إرسال رسالة

يرسل رسالة معاملاتية أو تسويقية عبر الرسائل القصيرة أو واجهة واتساب للأعمال.

Request Body
tostringمطلوب
Numéro de téléphone au format E.164 (+212...).
messagestringمطلوب
Contenu textuel (max 1600 caractères). Également accepté sous le nom "body".
fromstringاختياري
Sender ID personnalisé (ex: NOM_MARQUE). Par défaut "EnvoiSMS".
channelstringاختياري
"sms" ou "whatsapp". Par défaut "sms".
cascadebooleanاختياري
Si activé, tente de délivrer par WhatsApp et bascule automatiquement sur SMS en cas d'échec.
metadataobjectاختياري
Clé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).
buttonsarrayاختياري
Tableau d'objets boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
Notes
  • 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.
  • 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.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
messagesarrayمطلوب
Tableau d'objets contenant "to", "message" (ou "body"), et un objet facultatif "metadata".
fromstringاختياري
Sender ID global pour tout le lot.
channelstringاختياري
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 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"
    }
  ]
}
GET/v1/messages

إرسال رسالة

يرسل رسالة معاملاتية أو تسويقية عبر الرسائل القصيرة أو واجهة واتساب للأعمال.

Query Parameters
limitintegerاختياري
Nombre de résultats à retourner (1-200, défaut: 50).
offsetintegerاختياري
Nombre de résultats à ignorer pour la pagination (défaut: 0).
statusstringاختياري
Filtrer par statut (queued, sent, delivered, failed, undeliverable, unconfirmed).
channelstringاختياري
Filtrer par canal (sms, whatsapp).
from_datestringاختياري
Filtrer par date de début (format ISO 8601).
to_datestringاختياري
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 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
}
GET/v1/messages/:id

الحصول على حالة الرسالة

يسترجع الحالة الحالية وسجلات التسليم لرسالة معينة.

Notes
  • 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.0118,
  "cost_mad": 0.13,
  "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"
}
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 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
}
POST/v1/templates

Créer un template

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

Request Body
namestringمطلوب
Nom interne du template.
channelstringمطلوب
"sms" ou "whatsapp".
bodystringمطلوب
Contenu du message avec variables (ex: {{1}}).
categorystringاختياري
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 smr_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 smr_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_idstringمطلوب
Le nom d'expéditeur souhaité (max 11 caractères).
rc_urlstringاختياري
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 smr_xxx" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "id": "sid_9a8b...",
  "sender_id": "MABANQUE",
  "status": "pending"
}
POST/v1/verify/send

إرسال رمز OTP

يرسل رمز تحقق لمرة واحدة. وضعان حسب اختيارك: "whatsapp" — تحقق مُدار، الأبسط والأوفر (تنشئ EnvoiSMS الرمز وتسلّمه عبر واتساب من مرسل موثّق ثم تتحول تلقائياً إلى الرسائل القصيرة إذا لم يتم التأكيد خلال 60 ثانية؛ لا شيء تخزنه من جانبك — يتم تجاهل code_length وexpiry وtemplate في هذا الوضع: الرمز دائماً 6 أرقام وصالح لمدة 5 دقائق) — أو "sms" — تحتفظ بالتحكم الكامل في الرمز والقالب والمرسل. يتم التحقق في الوضعين بنفس استدعاء ‎/v1/verify/check. هل تريد علامتك التجارية الخاصة على الرسالة الاحتياطية للتحقق المُدار؟ متاح عند الطلب: [email protected].

Request Body
tostringمطلوب
Destinataire au format E.164.
channelstringاختياري
"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_idstringاختياري
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)اختياري
Nom de la marque affiché (ex: MonApp, max 32 car.). Par défaut "EnvoiSMS".
code_lengthinteger (Optionnel, canal sms)اختياري
Longueur du code généré (de 4 à 8 chiffres, défaut: 6).
expiryinteger (Optionnel, canal sms)اختياري
Durée de validité du code en secondes (de 60 à 1800, défaut: 600).
cascadearray (Optionnel, canal sms)اختياري
Liste ordonnée de canaux pour le basculement automatique en cascade (ex: ["whatsapp", "sms"]).
templatestring (Optionnel, 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_textstring (Optionnel, canal sms)اختياري
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 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",
  "expires_at": "2026-05-15T10:35:00Z",
  "status": "sent",
  "cost": { "eur": 0.025, "mad": 0.33 }
}
POST/v1/verify/check

التحقق من رمز OTP

يتحقق من صحة الرمز الذي أدخله المستخدم لجلسة تحقق معينة.

Request Body
session_idstringمطلوب
ID de session reçu lors de l'appel à /v1/verify/send.
codestringمطلوب
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 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"
}
GET/v1/verify/:id

حالة جلسة OTP

يسترجع حالة (تم التحقق منها أو منتهية الصلاحية) لجلسة تحقق معينة.

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"
}
POST/v1/verify/lookup

التحقق من الرقم

يتحقق من صحة التنسيق، وشبكة الاتصالات، ونوع الخط، والموقع الجغرافي لرقم الهاتف.

Request Body
numberstringمطلوب
Le numéro de téléphone à valider (format local ou international).
country_codestringاختياري
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 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"
}
GET/v1/contacts

قائمة جهات الاتصال

يسترجع جهات الاتصال مع إمكانية البحث بكلمة مفتاحية أو التصفية حسب قائمة جهات الاتصال.

Query Parameters
limitintegerاختياري
Résultats par page (1-500, défaut: 100).
offsetintegerاختياري
Pagination offset (défaut: 0).
qstringاختياري
Recherche par nom, téléphone ou email.
list_idstringاختياري
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 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
}
POST/v1/contacts

قائمة جهات الاتصال

يسترجع جهات الاتصال مع إمكانية البحث بكلمة مفتاحية أو التصفية حسب قائمة جهات الاتصال.

Request Body
phonestringمطلوب
Numéro de téléphone au format E.164.
namestringاختياري
Nom complet du contact.
emailstringاختياري
Adresse email.
list_idstringاختياري
Associer immédiatement le contact à une liste existante.
custom_fieldsobjectاختياري
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 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"
}
POST/v1/contacts/import

Importer des contacts

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

Request Body
contactsarrayمطلوب
Tableau d'objets contenant "phone", "name" (optionnel) et "email" (optionnel).
list_idstringاختياري
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 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
}
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 smr_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 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"
    }
  ]
}
POST/v1/contacts/lists

Créer une liste

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

Request Body
namestringمطلوب
Nom de la liste.
descriptionstringاختياري
Description de la liste.
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
}
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 smr_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
phonestringمطلوب
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 smr_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 smr_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 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"
    }
  ]
}
POST/v1/campaigns

Créer une campagne

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

Request Body
namestringمطلوب
Nom de la campagne.
bodystring (Requis*)مطلوب
Corps du message. Peut utiliser la variable {{name}}.
template_idstring (Requis*)مطلوب
Alternativement, ID d'un template approuvé. (*L'un des deux requis).
channelstringاختياري
"sms" ou "whatsapp". Par défaut "sms".
list_idstringاختياري
ID de la liste de contacts destinataire.
sender_idstringاختياري
Nom d'expéditeur.
scheduled_atstringاختياري
Date de programmation (ISO 8601). Met le statut en "scheduled".
buttonsarrayاختياري
Tableau de boutons WhatsApp interactifs (max 3, type "copy" | "url" | "call").
metadataobjectاختياري
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 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"
}
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 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"
}
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 smr_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 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"
    }
  ]
}
POST/v1/webhooks

Créer un Webhook

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

Request Body
urlstringمطلوب
URL cible sécurisée commençant par "https://".
eventsarrayاختياري
Tableau d'événements (ex: ["message.delivered", "message.failed"]). Les jokers "message.*" et "*" sont acceptés. Défaut: ["message.delivered", "message.failed"].
secretstringاختياري
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 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
}
PATCH/v1/webhooks/:id

Modifier un Webhook

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

Request Body
urlstringاختياري
Nouvelle URL HTTPS.
eventsarrayاختياري
Nouvelle liste d'événements abonnés.
activebooleanاختياري
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 smr_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 smr_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 smr_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 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"
    }
  ]
}
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
namestringاختياري
Libellé pour identifier la clé (défaut: "API key").
permissionsarrayاختياري
Droits accordés (send, verify, status, balance, contacts, campaigns, webhooks, billing, analytics, api_keys, optouts).
ip_whitelistarrayاختياري
Liste d'adresses IP autorisées à exécuter des requêtes avec cette clé.
rate_limitintegerاختياري
Limite maximale de requêtes/min (de 10 à 1000, défaut: 100).
sandboxbooleanاختياري
true 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é.
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."
}
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
namestringاختياري
Nouveau nom.
permissionsarrayاختياري
Nouvelle liste de permissions.
ip_whitelistarrayاختياري
Nouvelle liste d'adresses IP autorisées.
rate_limitintegerاختياري
Nouvelle limite de débit par minute.
activebooleanاختياري
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 smr_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 smr_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 smr_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 smr_xxx"
{
  "summary": {
    "total": 12840,
    "delivered": 12570,
    "delivery_rate": 97.9,
    "cost_mad": 2663.1
  }
}

دليل ويب هوكس

تأكيدات تسليم موقعة وآمنة.

يقوم EnvoiSMS.ma بإرسال أحداث JSON إلى عنوان HTTPS الخاص بخادمك مع ترويسة X-EnvoiSMS.ma-Signature للتحقق من المرسل.

message.sent

يتم تشغيله عندما يتم قبول الرسالة من بوابتنا وجدولتها للتسليم.

message.delivered

يتم تشغيله عندما يؤكد مشغل الشبكة تسليم الرسالة بنجاح إلى جهاز المستلم.

message.failed

يتم تشغيله عند فشل التسليم (رقم غير صالح، منتهي الصلاحية، مرفوض من الشبكة).

message.undeliverable

يتم تشغيله عندما تؤكد الشبكة تعذر تسليم الرسالة (رقم غير موجود أو انتهت صلاحيتها في قائمة انتظار المشغل).

message.inbound

يتم تشغيله عندما يرسل المستلم رسالة نصية للرد عليك (SMS واردة).

contact.optout

يتم تشغيله عندما يلغي المستلم اشتراكه باستخدام كلمة مرور STOP أو ما يماثلها.

التحقق من التوقيع
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

الأخطاء

هيكل استجابات أخطاء واجهة البرمجة (API).

ترجع جميع أخطاء واجهة برمجة التطبيقات رمز استجابة HTTP مناسبًا (4xx أو 5xx) بالإضافة إلى ترويسة JSON متوقعة تحتوي على رمز الخطأ ووصفه.

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

مفتاح واجهة البرمجة مفقود أو غير صالح. تحقق من رمز Bearer في الترويسات.

INSUFFICIENT_BALANCE

رصيد حسابك منخفض جداً لإتمام عملية الإرسال هذه.

INVALID_PHONE

تنسيق رقم المستلم غير صالح. استخدم صيغة 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.

SPAM_OR_PHISHING_DETECTED

تحتوي الرسالة على رابط مصنّف كتصيّد احتيالي أو رسالة مزعجة. تم رفض الإرسال.

CONTENT_BLOCKED

تم حظر محتوى الرسالة بواسطة نظام مكافحة إساءة الاستخدام وتم تعليق الحساب في انتظار المراجعة. يرجى التواصل مع الدعم.

INVALID_CODE

رمز التحقق المُدخل غير صحيح. تشير رسالة الخطأ إلى عدد المحاولات المتبقية.

EXPIRED_CODE

انتهت صلاحية رمز التحقق. اطلب رمزاً جديداً عبر ‎/v1/verify/send.

MAX_ATTEMPTS

تم تجاوز الحد الأقصى لمحاولات التحقق. أُغلقت الجلسة.

الحدود والقيود

الحدود والكوتا في بيئة الإنتاج.

OpenAPI YAML
طلبات واجهة البرمجة (API)

100 طلب / دقيقة (قابل للتوسيع عند الطلب).

حجم الرسالة

1600 حرف كحد أقصى لكل رسالة.

إرسال جماعي دفعة واحدة

حتى 10,000 رسالة لكل طلب واجهة برمجة.

الاحتفاظ بالسجلات

90 يوماً للتقارير المفصلة.