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.
Genere su clave API "env_live_..." desde su Consola EnvoiSMS.ma.
Use la autenticación Bearer en sus cabeceras HTTP para cada petición.
Pruebe su integración con el modo Sandbox para no consumir créditos reales.
Integre WhatsApp Business API para reducir sus costes de OTP por 10.
Configure un Webhook firmado para recibir confirmaciones de entrega en tiempo real.
Siga su consumo y facturas de MAD directamente en su Panel de control.
// 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.
Authorization: Bearer env_live_xxx
X-RateLimit-Limit y X-RateLimit-Remaining se devuelven en cada llamada.
Las peticiones de direcciones IP no configuradas devuelven un estado 401.
JSON, Authorization, X-EnvoiSMS.ma-Signature y X-EnvoiSMS.ma-Version están soportados.
POST /v1/messages HTTP/1.1
Host: api.envoisms.ma
Authorization: Bearer env_live_xxxxxxxx
Content-Type: application/json
Accept: application/jsonOpen 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 install envoismscomposer require envoisms/envoisms-phppip install envoismscomposer require envoisms/laravel-otp/v1/messagesEnviar un mensaje
Envía un mensaje transaccional o de marketing a través de SMS o WhatsApp Business API.
- 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 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"
}/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 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"
}
]
}/v1/messagesEnviar un mensaje
Envía un mensaje transaccional o de marketing a través de SMS o WhatsApp Business API.
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
}/v1/messages/:idObtener estado del mensaje
Recupera el estado actual y los logs de entrega de un mensaje específico.
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"
}/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 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
}/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 env_live_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 env_live_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 env_live_xxx" \
-H "Content-Type: application/json" \
-d '{}'{
"id": "sid_9a8b...",
"sender_id": "MABANQUE",
"status": "pending"
}/v1/verify/sendEnviar 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].
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 }
}/v1/verify/checkVerificar un OTP
Valida el código ingresado por el usuario para una sesión de verificación determinada.
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"
}/v1/verify/:idEstado de la sesión OTP
Recupera el estado (validado o expirado) de una sesión de verificación específica.
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"
}/v1/verify/lookupValidació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.
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"
}/v1/contactsListar contactos
Recupera contactos con búsqueda opcional por palabras clave o filtrado por lista.
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
}/v1/contactsListar contactos
Recupera contactos con búsqueda opcional por palabras clave o filtrado por lista.
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"
}/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 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
}/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 env_live_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 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"
}
]
}/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 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
}/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 env_live_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 env_live_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 env_live_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 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"
}
]
}/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 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"
}/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 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"
}/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 env_live_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 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"
}
]
}/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 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
}/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 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..."
}/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 env_live_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 env_live_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 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"
}
]
}/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 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."
}/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 env_live_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 env_live_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 env_live_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 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.deliveredSe activa cuando el operador confirma la entrega exitosa en el dispositivo del destinatario.
message.failedSe activa cuando falla la entrega (número inválido, expirado, rechazado por el operador).
message.expiredSe activa cuando el mensaje expira en la cola del operador.
message.inboundSe activa cuando un destinatario responde con un message de texto (SMS entrante).
contact.optoutSe activa cuando un destinatario se da de baja utilizando la palabra clave STOP o similar.
verify.successSe activa inmediatamente cuando una sesión OTP se valida correctamente con un código correcto.
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"
}
}UNAUTHORIZEDLa clave API falta o no es válida. Verifique su token Bearer en las cabeceras.
INSUFFICIENT_BALANCESolde insuffisant pour effectuer l'envoi.
INVALID_PHONEEl formato del número de destino no es válido. Use el estándar E.164.
RATE_LIMITEDLimite de requêtes par minute dépassée.
CHANNEL_NOT_ALLOWEDLe canal demandé (ex: WhatsApp) n'est pas activé sur votre compte.
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.
Límites
Restricciones y cuotas en el entorno de producción.
100 peticiones / minuto (escalable bajo demanda).
1600 caracteres máximo por mensaje.
Hasta 10,000 mensajes por llamada API.
90 días para informes detallados.