Documentation Technique
Intégrez EnvoiSMS.ma en moins de 15 minutes avec nos SDK PHP, Node.js et Python. Conçu pour les développeurs.
Start here
Tout pour démarrer avant la première requête.
EnvoiSMS.ma est une infrastructure de messagerie programmable conçue pour le Maroc. Nos routes directes avec IAM, Inwi et Orange garantissent une latence minimale.
Générez votre clé API "smr_..." depuis votre Console EnvoiSMS.ma.
Utilisez l'authentification Bearer dans vos headers HTTP pour chaque requête.
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.
Intégrez le WhatsApp Business API pour diviser vos coûts OTP par 10.
Configurez un Webhook signé pour recevoir les accusés de réception en temps réel.
Suivez votre consommation et vos factures MAD directement sur votre Dashboard.
// 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
Clés Bearer, headers et restrictions de sécurité.
Chaque endpoint /v1 nécessite une clé API valide transmise dans le header Authorization sous forme de jeton Bearer. Les clés de test et de production peuvent être générées ou révoquées depuis votre console.
Authorization: Bearer smr_xxx
X-RateLimit-Limit et X-RateLimit-Remaining retournés à chaque appel.
Les requêtes provenant d'adresses IP non configurées retournent un statut 401.
JSON, Authorization, X-EnvoiSMS.ma-Signature, et X-EnvoiSMS.ma-Version sont supportés.
POST /v1/messages HTTP/1.1
Host: api.envoisms.ma
Authorization: Bearer smr_xxxxxxxx
Content-Type: application/json
Accept: application/jsonOpen Source
SDKs officiels & Librairies clientes
Incorporez l'API EnvoiSMS en quelques lignes de code grâce à nos SDKs open-source officiels.
npm install envoismscomposer require envoisms/envoisms-phppip install envoismscomposer require envoisms/laravel-otp/v1/messagesEnvoyer un message
Envoie un SMS ou un message WhatsApp Business à un destinataire unique.
- 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é~).
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"
}/v1/messages/bulkEnvoi groupé (Bulk)
Envoie jusqu'à 10 000 messages en un seul appel API avec des destinataires ou des contenus uniques.
- 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é~).
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"
}
]
}/v1/messagesLister les messages
Récupère une liste paginée de tous les messages envoyés depuis le compte.
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
}/v1/messages/:idStatut du message
Consulte les détails et l'état de livraison en temps réel d'un message spécifique.
- 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.
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"
}/v1/templatesLister les templates
Récupère tous les templates WhatsApp et SMS approuvés de votre compte.
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
}/v1/templatesCréer un template
Soumet un nouveau template pour approbation par les opérateurs ou WhatsApp.
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"
}/v1/sender-idsLister les Sender IDs
Récupère la liste de vos Sender IDs avec leur statut d'approbation.
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"
}
]
}/v1/sender-idsDemander un Sender ID
Soumet un nouveau Sender ID pour approbation (requis pour le Maroc).
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"
}/v1/verify/sendGé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 et le moins cher (EnvoiSMS génère le code, le livre sur WhatsApp depuis un expéditeur vérifié, puis bascule automatiquement en SMS s'il n'est pas confirmé sous 60 s ; 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 : contact@envoisms.ma.
- 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.
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": 30,
"fallback_channels": ["sms"],
"expires_at": "2026-05-15T10:35:00Z",
"status": "sent",
"cost": { "eur": 0.025, "mad": 0.33 }
}/v1/verify/resendRenvoyer un code OTP (Repli)
Renvoie le même code OTP actif via un canal alternatif (ex: SMS après WhatsApp) une fois le délai de temporisation (30 s) écoulé. Aucun nouveau code n'est généré, évitant les erreurs de saisie.
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": "msg_9f1a...",
"to": "+212612345678",
"channel": "sms",
"status": "sent",
"resend_after_seconds": 30,
"expires_at": "2026-05-15T10:35:00Z"
}/v1/verify/checkVérifier un OTP
Valide le code fourni par l'utilisateur pour une session de vérification donnée.
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"
}/v1/verify/:idStatut de session OTP
Consulte l'état (validé ou expiré) d'une session de vérification spécifique.
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"
}/v1/verify/lookupValidation 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.
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"
}/v1/contactsLister les contacts
Récupère tous les contacts de votre compte, avec filtrage par mot-clé ou par liste.
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": "karim@email.ma",
"custom1": "VIP",
"custom2": null,
"custom3": null,
"created_at": "2026-05-10T14:20:00Z"
}
],
"limit": 100,
"offset": 0,
"total": 1
}/v1/contactsCréer / Modifier un contact
Ajoute un contact ou met à jour les informations d'un contact existant (détection par numéro).
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": "karim@email.ma",
"list_id": "lst_f84b..."
}'{
"id": "ctc_a2b3...",
"phone": "+212612345678",
"name": "Karim Bennani",
"email": "karim@email.ma",
"custom1": "VIP",
"custom2": null,
"custom3": null,
"created_at": "2026-05-10T14:20:00Z"
}/v1/contacts/importImporter des contacts
Importe massivement jusqu'à 5 000 contacts en un seul appel.
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
}/v1/contacts/:idSupprimer un contact
Supprime définitivement un contact à partir de son identifiant unique.
curl -X DELETE "https://api.envoisms.ma/v1/contacts/:id" \
-H "Authorization: Bearer smr_xxx"{
"deleted": true,
"id": "ctc_a2b3..."
}/v1/contacts/listsLister les listes
Récupère toutes les listes de contacts créées pour les campagnes de diffusion.
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"
}
]
}/v1/contacts/listsCréer une liste
Crée un nouveau groupe (liste de contacts) vide destiné aux campagnes.
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
}/v1/optoutsLister les désinscriptions
Récupère la liste des numéros qui se sont désinscrits (STOP) de vos communications.
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
}/v1/optoutsAjouter une désinscription
Ajoute manuellement un numéro à votre liste de désinscription (blacklist globale).
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"
}/v1/optouts/:phoneRetirer une désinscription
Retire un numéro de la liste de désinscription.
curl -X DELETE "https://api.envoisms.ma/v1/optouts/:phone" \
-H "Authorization: Bearer smr_xxx"{
"deleted": true,
"phone": "+212611111111"
}/v1/campaignsLister les campagnes
Récupère toutes vos campagnes d'envoi programmé ou de diffusion en cours.
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"
}
]
}/v1/campaignsCréer une campagne
Enregistre une nouvelle campagne en tant que brouillon ou la planifie à une date précise.
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"
}/v1/campaigns/:idDétails d'une campagne
Récupère les détails, la planification et le statut d'exécution d'une campagne.
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"
}/v1/campaigns/:id/sendLancer une campagne
Démarre immédiatement la diffusion d'une campagne de type brouillon vers tous les contacts associés.
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
}/v1/webhooksLister les webhooks
Récupère la liste de tous vos endpoints de webhooks enregistrés.
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"
}
]
}/v1/webhooksCréer un Webhook
Enregistre une URL HTTPS de callback pour recevoir les notifications d'événements.
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
}/v1/webhooks/:idModifier un Webhook
Met à jour la configuration d'un webhook (URL, événements surveillés ou état actif).
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..."
}/v1/webhooks/:idSupprimer un Webhook
Désactive et supprime logiquement un endpoint de webhook.
curl -X DELETE "https://api.envoisms.ma/v1/webhooks/:id" \
-H "Authorization: Bearer smr_xxx"{
"deleted": true,
"id": "whk_5f2b..."
}/v1/webhooks/:id/testTester un Webhook
Déclenche un événement de test ("message.test") vers l'URL configurée du webhook.
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..."
}/v1/api-keysLister les clés API
Récupère la liste de toutes vos clés d'API actives ou révoquées.
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"
}
]
}/v1/api-keysCréer une clé API
Génère un nouveau jeton d'API sécurisé avec des permissions et restrictions spécifiques.
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."
}/v1/api-keys/:idModifier une clé API
Met à jour les permissions, restrictions IP ou l'état d'activation d'une clé API.
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..."
}/v1/api-keys/:idRévoquer une clé API
Révoque définitivement une clé API pour l'empêcher d'authentifier les requêtes.
curl -X DELETE "https://api.envoisms.ma/v1/api-keys/:id" \
-H "Authorization: Bearer smr_xxx"{
"revoked": true,
"id": "key_e84c..."
}/v1/billing/balanceConsulter le solde
Consulte le solde disponible en Dirhams Marocains (MAD) ainsi que la devise et le forfait actif.
curl -X GET "https://api.envoisms.ma/v1/billing/balance" \
-H "Authorization: Bearer smr_xxx"{
"balance_mad": 1492.5,
"currency": "MAD",
"plan": "croissance"
}/v1/analyticsStatistiques d'usage
Récupère des métriques clés sur vos envois (volumes totaux, taux de délivrabilité, et coûts facturés).
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
Callbacks de livraison signés et sécurisés.
EnvoiSMS.ma poste des événements JSON à l'URL HTTPS de votre serveur avec un en-tête X-EnvoiSMS.ma-Signature pour authentifier l'expéditeur.
message.sentLe message a été accepté par le réseau de l'opérateur.
message.deliveredLe message a été remis avec succès au destinataire.
message.failedÉchec de livraison côté route ou soumission (rejet, erreur d'acheminement).
message.undeliverableLe réseau a confirmé que le message ne peut pas être remis (numéro inexistant, expiré en file opérateur).
message.inboundUn destinataire a répondu à l'un de vos messages SMS (inbound).
contact.optoutUn destinataire s'est désabonné (mot-clé STOP ou assimilé).
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
Structure des réponses d'erreur de l'API.
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.
{
"error": {
"code": "INVALID_PHONE",
"message": "to must be E.164 format, for example +212612345678",
"docs": "https://envoisms.ma/docs#errors"
}
}UNAUTHORIZEDClé API manquante ou invalide.
INSUFFICIENT_BALANCESolde insuffisant pour effectuer l'envoi.
INVALID_PHONELe numéro de téléphone n'est pas au format E.164.
RATE_LIMITEDLimite de requêtes par minute dépassée. Respectez l'en-tête Retry-After.
INVALID_IDEMPOTENCY_KEYL'en-tête Idempotency-Key dépasse 255 caractères.
IDEMPOTENCY_IN_FLIGHTLa requête originale portant cette Idempotency-Key est encore en cours. Réessayez dans un instant.
IDEMPOTENCY_KEY_REUSEDCette Idempotency-Key a déjà été utilisée avec un corps de requête différent. Utilisez une nouvelle clé.
INVALID_CHANNELLe canal demandé n'existe pas. Canaux valides : sms, whatsapp, telegram, voice, rcs.
CHANNEL_NOT_CONFIGUREDLe canal demandé n'est pas disponible actuellement sur la plateforme.
CHANNEL_DISABLEDLe canal demandé est désactivé sur la plateforme.
FORBIDDENLa clé API n'a pas la permission requise pour cette action, ou le compte est suspendu.
SENDER_ID_TOO_LONGLe Sender ID dépasse la limite de 11 caractères.
SENDER_ID_INVALIDLe Sender ID contient des caractères non autorisés.
SENDER_ID_NOT_APPROVEDLe Sender ID n'a pas encore été approuvé par les opérateurs.
SENDER_ID_PENDINGLe Sender ID est en cours d'approbation.
SENDER_ID_REJECTEDLe Sender ID a été rejeté par les opérateurs.
MISSING_FIELDUn champ obligatoire est manquant dans la requête.
CASCADE_TIMEOUTLe premier canal a expiré, basculement vers le canal secondaire (cascade).
UPSTREAM_ERRORErreur de livraison au niveau de l'opérateur ou de la passerelle.
OPTED_OUTLe numéro a refusé vos communications (STOP). Envoi interdit.
SPAM_OR_PHISHING_DETECTEDLe message contient un lien identifié comme hameçonnage ou spam. Envoi refusé.
CONTENT_BLOCKEDLe 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_CODELe code OTP soumis est incorrect. Le message d'erreur indique le nombre de tentatives restantes.
EXPIRED_CODELe code OTP a expiré. Demandez un nouveau code via /v1/verify/send.
MAX_ATTEMPTSNombre maximal de tentatives de vérification dépassé. La session est clôturée.
STRIPE_ERRORLa 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_ERRORErreur interne de notre côté. Réessayez ; contactez le support si le problème persiste.
Limites
Contraintes et quotas de l'environnement de production.
100 requêtes / minute (extensible sur demande).
1600 caractères maximum par message.
Jusqu'à 10 000 messages par appel API.
90 jours pour les rapports détaillés.