المفتاح لـ «جرّب»:لا يوجد — الأمثلة لا تُرسلأنشئ حساباً للحصول على مفتاح تجريبي
يبقى المفتاح في هذا التبويب فقط: لا يُحفظ ولا يُرسل إلا إلى https://api.envoisms.ma.

البدء السريع

أول طلب لك في دقيقة#

ترسل واجهة EnvoiSMS رسائل SMS وواتساب وتتحقق من أرقام الهواتف، بصيغة JSON عبر HTTPS. أنشئ مفتاحاً تجريبياً والصق مثالاً وشغّله: لا يُرسل شيء ولا يُخصم شيء.

لوكلاء البرمجة بالذكاء الاصطناعي: llms.txt · MCP
عنوان URL الأساسيhttps://api.envoisms.ma/v1
المصادقةAuthorization: Bearer <المفتاح>
المفاتيحsmr_… (حقيقي) · env_test_… (تجريبي: لا إرسال ولا خصم)
التنسيقJSON للطلب والاستجابة، UTF-8، تواريخ ISO 8601 ‏(UTC)
أرقام الهاتفE.164: ‎+212612345678
حد الطلباتلكل مفتاح في الدقيقة حسب الباقة (60 إلى 1200)؛ انظر X-RateLimit-*
  1. أنشئ حساباً ثم مفتاحاً تجريبياً من لوحة التحكم ← مفاتيح API، وصدّره: export ENVOISMS_API_KEY=env_test_…
  2. الصق أحد الأمثلة المجاورة: يعمل كما هو بهذا المفتاح دون إرسال أو خصم أي شيء.
  3. سجّل webhook لاستقبال حالات التسليم والردود.
  4. اشحن رصيدك وأنشئ مفتاحاً حقيقياً (smr_…) واستبدل به المفتاح التجريبي في إعداداتك.

1. إرسال رسالة SMS

طلب واحد فقط. مع مفتاح تجريبي (env_test_…) يكون الإرسال محاكاة: لا يخرج شيء من المنصة ولا يُخصم أي مبلغ، وتُظهر الاستجابة السعر الذي كان سيدفعه مفتاح حقيقي (simulated_cost).

الاستجابة
HTTP/1.1 202 Accepted
{
  "id": "msg_9f2c4e1a7b3d",
  "to": "+212612345678",
  "channel": "sms",
  "cascade": false,
  "status": "queued",
  "cost": { "eur": 0, "mad": 0 },
  "sandbox": true,
  "simulated_cost": { "eur": 0.0704, "mad": 0.792 },
  "segments": 1,
  "created_at": "2026-10-22T10:30:00.000Z"
}
1. إرسال رسالة SMS
curl https://api.envoisms.ma/v1/messages \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "to": "+212612345678",
    "message": "Your order #1042 has shipped."
  }'

2. إرسال نموذج واتساب

يُرسل واتساب من رقم واتساب للأعمال الخاص بك، المرتبط مرة واحدة في لوحة التحكم (وإلا 403 WHATSAPP_NOT_CONNECTED). خارج نافذة 24 ساعة لا يفتح المحادثة إلا نموذج معتمد؛ وتُمرَّر متغيراته {{1}} و{{2}}… في metadata.variables بالترتيب.

الاستجابة
HTTP/1.1 202 Accepted
{
  "id": "msg_4b81d0c2e9f7",
  "to": "+212612345678",
  "channel": "whatsapp",
  "cascade": false,
  "status": "queued",
  "cost": { "eur": 0.05778, "mad": 0.65 },
  "segments": 1,
  "created_at": "2026-10-22T10:31:00.000Z"
}
2. إرسال نموذج واتساب
curl https://api.envoisms.ma/v1/messages \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+212612345678",
    "channel": "whatsapp",
    "template": { "name": "order_shipped", "language": "fr" },
    "metadata": { "variables": ["Karim", "#1042"] }
  }'

3. التحقق من رقم هاتف (OTP)

تولّد EnvoiSMS الرمز وترسله وتحصي المحاولات وتُنهي صلاحيته (10 دقائق افتراضياً). لا تحفظ سوى session_id. مع مفتاح تجريبي تتضمن الاستجابة sandbox_code لاختبار ‎/verify/check دون هاتف.

الاستجابة
POST /v1/verify/send → 202 Accepted
{
  "session_id": "vrf_2c7e9a14b0d3",
  "message_id": "msg_e1a07c93b5f2",
  "to": "+212612345678",
  "channel": "sms",
  "expires_at": "2026-10-22T10:42:00.000Z",
  "resend_after_seconds": 30,
  "fallback_channels": [],
  "status": "sent",
  "sandbox": true,
  "simulated": true,
  "sandbox_code": "483921"
}

POST /v1/verify/check → 200 OK
{ "session_id": "vrf_2c7e9a14b0d3", "verified": true, "verified_at": "2026-10-22T10:33:12.000Z" }
3. التحقق من رقم هاتف (OTP)
# 1. Send the code
curl https://api.envoisms.ma/v1/verify/send \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+212612345678", "brand": "MyApp" }'

# 2. Check what the user typed
curl https://api.envoisms.ma/v1/verify/check \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "session_id": "vrf_…", "code": "483921" }'

المصادقة

المصادقة#

يحمل كل طلب ‎/v1 مفتاح API في ترويسة Authorization. أنشئ مفاتيحك وقيّدها وألغها من لوحة التحكم ← مفاتيح API؛ يُعرض المفتاح مرة واحدة عند إنشائه. استخدمه من جهة الخادم فقط.

نوعان من المفاتيح

smr_… يرسل فعلياً ويخصم من الرصيد؛ وenv_test_… يحاكي كل شيء مجاناً. العنوان نفسه للاثنين.

الصلاحيات

يحمل كل مفتاح قائمة صلاحيات (send وverify وstatus…). وما خرج عنها: 403 FORBIDDEN.

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

اختيارية لكل مفتاح. يتلقى أي طلب من عنوان IP آخر الرمز 401 UNAUTHORIZED.

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

X-RateLimit-Limit وX-RateLimit-Remaining وX-RateLimit-Reset (توقيت Unix) في كل استجابة.

ترويسات الطلب
POST /v1/messages HTTP/1.1
Host: api.envoisms.ma
Authorization: Bearer smr_your_live_key
Content-Type: application/json
Idempotency-Key: 6f1d2c9e-4b7a-4f3e-9d21-0c5e8a7b3f10

HTTP/1.1 202 Accepted
X-RateLimit-Limit: 180
X-RateLimit-Remaining: 179
X-RateLimit-Reset: 1792663860

تأكيد الطلب (SMS)

إرسال تأكيد طلب عبر SMS#

آخر تحديث

  1. أنشئ مفتاحاً تجريبياً وصدّره: export ENVOISMS_API_KEY=env_test_…
  2. اختياري: اطلب اسم المرسل الخاص بك (POST /v1/sender-ids، من 15 إلى 30 يوماً). وإلى ذلك الحين احذف sender_id: يُطبق المرسل الافتراضي.
  3. عند حدث «تم دفع الطلب» أرسل SMS مع Idempotency-Key = معرّف الطلب: الحدث المزدوج يرسل رسالة واحدة.
  4. سجّل webhook للحدثين message.delivered وmessage.failed؛ ويعود metadata.order_id في كل تسليم.
  5. جرّب ‎+212600000002 لرؤية مسار الفشل، ثم انتقل إلى مفتاح حقيقي (smr_…).
هل كان هذا القسم مفيداً؟
تأكيد الطلب (SMS)
curl https://api.envoisms.ma/v1/messages \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-paid" \
  -d '{
    "to": "+212612345678",
    "message": "Commande #1042 confirmée : 349 MAD. Livraison prévue jeudi.",
    "metadata": { "order_id": "1042" }
  }'

طلبات الدفع عند الاستلام عبر واتساب

تأكيد طلبات الدفع عند الاستلام عبر واتساب#

آخر تحديث

على WooCommerce تتولى إضافة EnvoiSMS ‏(v2.0.0) كل شيء: ينتظر كل طلب دفع عند الاستلام، ويتلقى العميل رسالة بزري تأكيد / إلغاء، ونقرته تحدّث الطلب.

  1. اربط رقم واتساب الخاص بك من لوحة التحكم ← واتساب (يمكنك الاحتفاظ بتطبيق WhatsApp Business على هاتفك).
  2. ثبّت الإضافة من github.com/envoisms/envoisms-woocommerce ‏(WooCommerce 7.1+، PHP 8.0+) والصق مفتاح API في WooCommerce ← EnvoiSMS Maroc.
  3. فعّل خيار COD «Activer» واحفظ: تسجل الإضافة الـ webhook الخاص بها (message.inbound) وتحتفظ بسر التوقيع.
  4. انقر «Créer les modèles WhatsApp» (بالفرنسية والعربية): تراجعها EnvoiSMS ثم ترسلها إلى Meta؛ وتظهر حالتها في الصفحة نفسها.
  5. بعد اعتماد النماذج، قدّم طلباً تجريبياً بالدفع عند الاستلام. ويمكنك متابعة حالتها عبر الواجهة:
هل كان هذا القسم مفيداً؟
طلبات الدفع عند الاستلام عبر واتساب
curl "https://api.envoisms.ma/v1/templates?channel=whatsapp" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"

حملة تسويقية (API)

إطلاق حملة تسويقية عبر الواجهة#

آخر تحديث

  1. أنشئ قائمة: POST /v1/contacts/lists ‏{"name": "عملاء أوفياء"} ← lst_…
  2. استورد جهات الاتصال: POST /v1/contacts/import ‏{"list_id", "contacts": [{"phone", "name"}]}.
  3. سجّل دليل موافقة كل شخص: POST /v1/consents ‏{"phone", "purpose": "marketing", "status": "granted", "source": "form", "evidence": {…}}.
  4. أنشئ الحملة: SMS مع body (اذكر طريقة إلغاء الاشتراك)؛ أو واتساب مع template_id وtemplate_variables و"consent_attested": true. ويجدولها scheduled_at.
  5. أطلقها (POST /v1/campaigns/{id}/send)، وتابعها بـ GET /v1/campaigns/{id}، وأوقفها مؤقتاً بـ ‎/pause. تُستبعد الأرقام الملغى اشتراكها (STOP) تلقائياً.
هل كان هذا القسم مفيداً؟
حملة تسويقية (API)
curl https://api.envoisms.ma/v1/campaigns \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Soldes de novembre",
    "channel": "sms",
    "list_id": "lst_…",
    "body": "-20% ce week-end avec le code NOV20.",
    "scheduled_at": "2026-11-07T09:00:00Z"
  }'

صندوق وارد ثنائي الاتجاه

صندوق دعم ثنائي الاتجاه#

آخر تحديث

  1. سجّل webhook للحدث message.inbound (وmessage.read إن كنت تعرض إشعارات القراءة).
  2. تحقق من التوقيع ثم صنّف الرسالة حسب الرقم: data.from هو العميل وdata.channel هي القناة.
  3. اقرأ سجل العميل عبر GET /v1/conversations/{phone}.
  4. ردّ عبر POST /v1/conversations/{phone}/messages. على واتساب لا يُسمح بالنص الحر إلا خلال 24 ساعة من آخر رسالة للعميل؛ وبعدها أرسل نموذجاً (template_name) أو انتقل إلى SMS.
  5. علّم المحادثة كمقروءة عبر POST /v1/conversations/{phone}/mark-read. يصل STOP من العميل كحدث contact.optout ويمنع الإرسال اللاحق.
هل كان هذا القسم مفيداً؟
صندوق وارد ثنائي الاتجاه
curl https://api.envoisms.ma/v1/conversations/+212612345678/messages \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Bonjour, votre colis part aujourd'"'"'hui." }'

المنصات والوكالات

ربط واتساب عملائك#

آخر تحديث

لا يُربط رقم واتساب عبر الواجهة: تشترط Meta أن يسجّل صاحب النشاط الدخول بنفسه (Embedded Signup). لذا لكل عميل حساب EnvoiSMS خاص به يدفع ثمن إرسالاته.

  1. ينشئ العميل حسابه على envoisms.ma (تسجيل بالبريد الإلكتروني).
  2. يربط رقمه من لوحة التحكم ← واتساب بتسجيل الدخول إلى Meta ‏(Embedded Signup؛ مع إمكانية التعايش مع تطبيق WhatsApp Business).
  3. ينشئ مفتاح API مقيداً بما تحتاجه (مثل send وstatus) ويسلّمه لك؛ وتحتفظ به في الخادم، مفتاح لكل عميل.
  4. تحقق من قدرة الرقم على الإرسال: GET /v1/whatsapp/waba-connection ← readiness.can_send وreadiness.blockers.
  5. أنشئ نماذجه (POST /v1/templates) وأرسل بمفتاحه. تبقى إرسالاته ورصيده وwebhooks الخاصة به ملكاً له.
هل كان هذا القسم مفيداً؟
المنصات والوكالات
curl https://api.envoisms.ma/v1/whatsapp/waba-connection \
  -H "Authorization: Bearer $CLIENT_API_KEY"

البيئة التجريبية والاختبار

اختبر دون إرسال أو دفع#

آخر تحديث

أنشئ مفتاحاً تجريبياً من لوحة التحكم ← مفاتيح API (حدد «Sandbox»). يبدأ بـ env_test_، أما المفتاح الحقيقي فيبدأ بـ smr_. كلاهما يستدعي العنوان نفسه https://api.envoisms.ma/v1: المفتاح هو الذي يحدد وليس العنوان.

يُتحقق من المفتاح التجريبي تماماً مثل المفتاح الحقيقي (صيغة الرقم، معرّف المرسل، نافذة 24 ساعة، المحتوى)، لكن لا يُرسل شيء ولا يُخصم شيء. وما كان المفتاح الحقيقي سيرفضه يُذكر في warnings بدلاً من إخفائه.

  • يعيد POST /v1/messages القيمة sandbox: true وتكلفة صفرية وsimulated_cost: السعر الحقيقي للإرسال نفسه.
  • يعيد POST /v1/verify/send القيمة sandbox_code: الرمز الذي كان المستخدم سيستلمه.
  • لا يرى كل مفتاح إلا نوع حركته: GET /v1/messages بمفتاح تجريبي يعرض الإرسالات المحاكاة فقط، والعكس صحيح.
  • أرقام الاختبار (POST /v1/messages، بمفتاح تجريبي فقط): ‎+212600000002 يفشل (message.failed، SANDBOX_TEST_FAILED)؛ ‎+212600000003 غير قابل للتسليم (message.undeliverable)؛ ‎+212600000004 ملغى الاشتراك (403 OPTED_OUT عند الطلب)؛ ‎+212600000005 لا يتلقى إشعاراً أبداً (يبقى «sent»)؛ وأي رقم آخر، بما فيه ‎+212600000001، يُسلَّم (message.delivered) بعد مهلة محاكاة قصيرة (نحو ثانيتين).
  • لا يمكن تحويل المفتاح التجريبي إلى حقيقي: أنشئ مفتاحاً حقيقياً عندما تكون جاهزاً وغيّر متغير البيئة.
هل كان هذا القسم مفيداً؟

SMS أم واتساب؟

اختيار القناة المناسبة#

آخر تحديث

SMS هي القناة الافتراضية: احذف channel. تصل إلى أي هاتف دون رقم مرتبط ودون نموذج ودون نافذة 24 ساعة. إنها الخيار الصحيح للإشعارات والتنبيهات لأي عميل.

يتطلب واتساب ("channel": "whatsapp") رقم واتساب للأعمال الخاص بك مرتبطاً. للمبادرة بالكتابة، أو بعد أكثر من 24 ساعة من آخر رسالة للعميل، استخدم نموذجاً معتمداً؛ ولا يُقبل النص الحر إلا خلال 24 ساعة من رسالة العميل (وإلا 400 OUT_OF_24H_WINDOW دون أي خصم). يُسعَّر واتساب حسب فئة النموذج.

الاثنان معاً: "cascade": true يجرب واتساب ثم يتحول إلى SMS إذا رفض واتساب أو فشل أو لم يؤكد التسليم خلال cascade_timeout ثانية (120 افتراضياً). لا يُحتسب إلا ما أُرسل فعلاً.

رموز التحقق: فضّل POST /v1/verify/send الذي يتولى التوليد والمحاولات وانتهاء الصلاحية وإعادة الإرسال، بدلاً من إرسال رمزك بنفسك عبر ‎/v1/messages.

هل كان هذا القسم مفيداً؟

التكرار الآمن وإعادة المحاولة

أعد المحاولة دون الإرسال مرتين#

آخر تحديث

أضف ترويسة Idempotency-Key (حتى 255 حرفاً، مثل UUID أو «order-1042-shipped») إلى POST /v1/messages وPOST /v1/messages/bulk (ومكافئاتها ‎/v1/waba/messages). إذا انتهت مهلة الطلب أو تعطلت عمليتك، أعد الطلب نفسه بالمفتاح نفسه: يتم الإرسال مرة واحدة، وتُعيد المحاولة نص JSON الأصلي مع Idempotency-Replayed: true.

  • يُحفظ المفتاح 24 ساعة لكل حساب. تُحفظ كل استجابة أقل من 500 وتُعاد، بما في ذلك أخطاء 4xx (مثل 429 أو 402): بعد خطأ 4xx أصلح السبب واستخدم مفتاحاً جديداً.
  • يرتبط المفتاح بالنص نفسه بايتاً ببايت: إعادة المحاولة ترسل النص ذاته. أي نص مختلف بالمفتاح نفسه — حتى JSON نفسه بتنسيق مختلف — يعيد 422 IDEMPOTENCY_KEY_REUSED.
  • لا يُحفظ خطأ 5xx أو انتهاء المهلة: أعد المحاولة بالمفتاح نفسه مع انتظار متزايد (1 ث، 2 ث، 4 ث…).
  • 409 IDEMPOTENCY_IN_FLIGHT: الطلب الأصلي لا يزال قيد التنفيذ؛ انتظر Retry-After وأعد المحاولة بالمفتاح نفسه. 422 IDEMPOTENCY_KEY_REUSED: استُخدم المفتاح سابقاً مع نص مختلف.
  • 429 RATE_LIMITED: انتظر عدد الثواني المذكور في Retry-After. ترافق الترويسات X-RateLimit-Limit وX-RateLimit-Remaining وX-RateLimit-Reset كل استجابة موثّقة.
هل كان هذا القسم مفيداً؟

ترقيم الصفحات

التنقل في القوائم#

آخر تحديث

تقبل القوائم limit وoffset وتعيد { "data": [...], "limit", "offset", "total" }. بالنسبة لـ GET /v1/messages: ‏50 افتراضياً و200 كحد أقصى، من الأحدث إلى الأقدم، مع التصفية حسب status وchannel وcampaign_id وfrom_date وto_date. أضف format=csv للحصول على كامل النتائج المصفّاة في ملف واحد.

هل كان هذا القسم مفيداً؟
ترقيم الصفحات
curl "https://api.envoisms.ma/v1/messages?status=failed&limit=100&offset=0" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"

صلاحيات المفاتيح

مفتاح واحد بأقل الصلاحيات#

آخر تحديث

يحمل كل مفتاح صلاحيات. أي طلب خارجها يعيد 403 FORBIDDEN. امنح كل خادم أصغر قائمة كافية: خادم رموز التحقق لا يحتاج إلا verify وstatus.

  • send — ‏POST /v1/messages و‎/v1/messages/bulk و‎/v1/templates و‎/v1/conversations و‎/v1/lookup
  • status — ‏GET /v1/messages و‎POST /v1/verify/check وبقية ‎/v1/verify (sessions وapps وlookup وvoid)
  • verify — ‏POST /v1/verify/send و‎/v1/verify/resend
  • balance — ‏GET /v1/billing/balance؛ billing — بقية ‎/v1/billing
  • contacts (جهات الاتصال والقوائم والموافقات)، campaigns، webhooks، optouts، analytics، api_keys، sender_id
  • إعداد واتساب (‎/v1/whatsapp/…): التعديلات — ربط رقم، الأدوات، الملف التعريفي، الترحيل — تتطلب جلسة لوحة التحكم (يتلقى مفتاح API الرمز 403). القراءة فقط متاحة للمفاتيح، مثل GET /v1/whatsapp/waba-connection.
هل كان هذا القسم مفيداً؟

الإصدارات والتغييرات

ما الذي قد يتغير، وكيف ستعرف#

آخر تحديث

الإصدار جزء من المسار: ‎/v1. داخل ‎/v1 لا تتغير الواجهة إلا بالإضافة — نقاط نهاية جديدة، حقول اختيارية، حقول في الاستجابة، رموز أخطاء، أحداث webhook. تجاهل الحقول التي لا تعرفها. أي تغيير غير متوافق يصدر في ‎/v2 بجانب ‎/v1 وليس مكانه.

يُعلن عن حذف أي شيء من ‎/v1 قبل 12 شهراً على الأقل: بالبريد لصاحب الحساب، وفي سجل التغييرات، وعلى المسار نفسه الذي تحمل كل استجابة منه حينها Deprecation (تاريخ الإعلان) وSunset (تاريخ التوقف) وLink إلى دليل الترحيل. الاستثناء الوحيد إصلاح أمني يُعلن عنه في أقرب وقت. لا يوجد اليوم أي مسار مُتقادم في ‎/v1.

هل كان هذا القسم مفيداً؟

الحدود لكل نقطة نهاية

الحدود، نقطة نهاية تلو الأخرى#

آخر تحديث

تشترك كل المسارات في حد الدقيقة الخاص بالمفتاح (افتراضياً Starter ‏60، Business ‏180، Pro ‏500، Enterprise ‏1200؛ وترويسات X-RateLimit-* في كل استجابة؛ و429 RATE_LIMITED مع Retry-After عند التجاوز). وتضيف بعض المسارات قواعدها الخاصة:

  • POST /v1/messages/bulk: ‏10,000 رسالة في كل طلب.
  • POST /v1/messages و‎/bulk: الحصص اليومية والشهرية الاختيارية للحساب (PATCH /v1/billing/quota)؛ وما زاد عنها 429 QUOTA_EXCEEDED حتى منتصف الليل UTC.
  • POST /v1/verify/send و‎/resend: لكل رقم رمز كل 30 ثانية عبر SMS و60 ثانية عبر واتساب (429 OTP_COOLDOWN)، و5 في الساعة و10 في اليوم (429 OTP_RATE_LIMIT)؛ و200 يومياً لكل حساب؛ وخارج المغرب OTP_COUNTRY_PAUSED عندما يُؤكَّد عدد قليل جداً.
  • POST /v1/verify/check: ‏3 محاولات لكل جلسة افتراضياً (قابلة للضبط لكل تطبيق Verify)، ثم 429 MAX_ATTEMPTS.
  • POST /v1/inbound-webhooks/catch/{id} (دون مفتاح): ‏120 طلباً في الدقيقة لكل webhook، و64 كيلوبايت لكل طلب.
  • webhooks الخاصة بك: ننتظر ردك 10 ثوانٍ كحد أقصى، ثم نعيد المحاولة 3 مرات (دقيقة، 10 دقائق، ساعة).
هل كان هذا القسم مفيداً؟

Webhooks

استقبال الحالات والردود#

آخر تحديث

أنشئ webhook عبر POST /v1/webhooks ‏({"url": "https://…", "events": ["message.delivered", "message.failed"]}). تتضمن الاستجابة سر التوقيع ويُعرض مرة واحدة فقط؛ ويصدر POST /v1/webhooks/{id}/rotate-secret سراً جديداً. تقبل events اسماً دقيقاً أو نطاقاً ("message.*") أو "*".

كل تسليم هو طلب POST بصيغة JSON ‏{"event", "data", "timestamp"}. لحالة رسالة تكون data ‏{id, to, channel, status, error_code?, error_message?, metadata?}، وmetadata هي ما أرسلته. أجب بـ 2xx قبل انتهاء المهلة (10 ثوانٍ) ثم عالج بشكل غير متزامن؛ وأزل التكرار بالاعتماد على data.id + event لأن التسليم قد يصل مرتين.

تحقق من X-EnvoiSMS-Signature-256: t=<ثوانٍ>,v1=<hex>: احسب HMAC-SHA256(السر، t + "." + النص الخام)، وقارنه بـ v1 بزمن ثابت، وارفض إذا مضى على t أكثر من 5 دقائق. لا تزال الترويسة القديمة X-EnvoiSMS-Signature ‏(sha256=<hex> للنص وحده دون طابع زمني) تُرسل؛ فضّل الجديدة لأنها تمنع إعادة الإرسال. ويوجد الحدث أيضاً في X-EnvoiSMS-Event.

  • إعادة المحاولة: يُعاد إرسال 5xx أو 429 أو خطأ الشبكة 3 مرات (بعد دقيقة و10 دقائق وساعة — 4 محاولات إجمالاً). ولا يُعاد أي 4xx آخر.
  • السجل وإعادة الإرسال: يعرض GET /v1/webhooks/logs آخر 100 محاولة؛ ويعيد POST /v1/webhooks/logs/{log_id}/replay إرسال تسليم بتوقيع جديد. ويرسل POST /v1/webhooks/{id}/test مثالاً.
  • ترحيل واتساب إلى خادمك (رقم مرتبط مضبوط على وضع «webhook» في لوحة التحكم): تصل الرسائل والحالات بصيغة WhatsApp Cloud الأصلية، موقّعة بـ X-Hub-Signature-256: sha256=<hex> = ‏HMAC-SHA256(webhook_secret الخاص بالرقم، النص الخام). يُعرض هذا السر مرة واحدة عند إنشائه أو تجديده (rotate_webhook_secret). دون سر لا يُرحَّل أي شيء. لا يوجد طابع زمني: أزل التكرار بمعرّف الرسالة.

الأحداث

message.sent

سُلّمت الرسالة إلى الشبكة (المشغّل أو واتساب).

message.delivered

أكد هاتف المستلم الاستلام.

message.read

واتساب: قرأ المستلم الرسالة (ما لم يُعطّل إشعارات القراءة).

message.failed

فشل الإرسال؛ يوضح error_code وerror_message السبب (انظر رموز فشل التسليم).

message.undeliverable

أكدت الشبكة تعذّر تسليم الرسالة (رقم غير موجود، أو انتهت صلاحيتها لدى المشغّل).

message.fallback

التسلسل: تنتقل الرسالة إلى القناة التالية. channel = القناة الجديدة، previous_channel = السابقة، error_code = السبب.

message.inbound

راسلك أحد جهات الاتصال (رد SMS أو رسالة واتساب، بما في ذلك الضغط على زر أو قائمة).

message.reaction

واتساب: تفاعل أحد جهات الاتصال مع إحدى رسائلك برمز تعبيري.

contact.optout / contact.optin

ألغى أحد جهات الاتصال اشتراكه (STOP) أو أعاد الاشتراك. يُرفض الإرسال إلى رقم ملغى الاشتراك (403 OPTED_OUT).

lead.qualified

أنهى بوت التأهيل في واتساب تأهيل عميل محتمل.

هل كان هذا القسم مفيداً؟
التحقق من التوقيع
import crypto from 'node:crypto';
import express from 'express';

const app = express();

// Keep the RAW body: the signature is computed over the exact bytes received.
app.post('/webhooks/envoisms', express.raw({ type: 'application/json' }), (req, res) => {
  const header = req.get('X-EnvoiSMS-Signature-256') || '';
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  const expected = crypto
    .createHmac('sha256', process.env.ENVOISMS_WEBHOOK_SECRET)
    .update(`${parts.t}.${req.body}`)
    .digest('hex');

  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  const valid = parts.v1?.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
  if (!fresh || !valid) return res.sendStatus(401);

  const { event, data } = JSON.parse(req.body);
  res.sendStatus(200);              // answer fast…
  queue.push({ event, data });      // …then process (de-duplicate on data.id + event)
});
مثال على تسليم
POST /webhooks/envoisms HTTP/1.1
Content-Type: application/json
X-EnvoiSMS-Event: message.delivered
X-EnvoiSMS-Signature-256: t=1792663800,v1=5f0c…e9
X-EnvoiSMS-Signature: sha256=a41b…7d
User-Agent: EnvoiSMS-Webhook/1.0 (formerly SMSMaroc)

{
  "event": "message.delivered",
  "data": {
    "id": "msg_9f2c4e1a7b3d",
    "to": "+212612345678",
    "channel": "sms",
    "status": "delivered",
    "metadata": { "order_id": "1042" }
  },
  "timestamp": "2026-10-22T10:30:04.000Z"
}

الأخطاء

الأخطاء#

يعيد الخطأ حالة 4xx أو 5xx ودائماً الغلاف نفسه. اعتمد في منطقك على error.code وليس على النص: error.message جملة بالإنجليزية قد تتحسن صياغتها. كل رمز أدناه يوضح ما يجب فعله.

HTTP/1.1 400 Bad Request
{
  "error": {
    "code": "INVALID_PHONE",
    "message": "to must be E.164 format, for example +212612345678",
    "docs": "https://envoisms.ma/en/docs#errors"
  }
}

المصادقة والوصول

UNAUTHORIZEDHTTP 401

ترويسة Authorization مفقودة، أو المفتاح غير معروف أو ملغى، أو عنوان IP غير مسموح به لهذا المفتاح، أو الحساب غير نشط؛ يوضح error.message السبب. أرسل Authorization: Bearer <المفتاح> وتحقق منه في لوحة التحكم ← مفاتيح API.

FORBIDDENHTTP 403

المفتاح لا يملك صلاحية هذا المسار (انظر صلاحيات المفاتيح)، أو يتطلب المسار جلسة لوحة التحكم. أضف الصلاحية إلى المفتاح أو استخدم مفتاحاً آخر.

ACCOUNT_SUSPENDEDHTTP 403

الحساب معلّق. تواصل مع الدعم؛ لا يمكن إرسال أي شيء حتى تتم مراجعته.

WORKSPACE_NOT_FOUNDWORKSPACE_SUSPENDEDAPI_KEY_WORKSPACE_MISMATCHHTTP 404 / 403

مساحة العمل المحددة في ترويسة x-workspace-id غير موجودة أو تم تعليقها أو تتعارض مع المفتاح.

FORBIDDEN_ASSETHTTP 403

رقم واتساب هذا لا ينتمي إلى حسابك. استخدم phone_number_id من أرقامك المرتبطة.

PAYMENT_NOT_SETTLEDINVALID_CREDENTIALMACHINE_PAYMENTS_DISABLEDHTTP 402 / 400 / 501

مدفوعات الآلات (Authorization: Payment …): لم يُؤكَّد الإيداع بعد (انتظر ثم أعد المحاولة)، أو تعذّر فك ترميز بيانات الاعتماد، أو الميزة معطلة.

طلب غير صالح

INVALID_JSONHTTP 400

النص ليس JSON صالحاً. أرسل Content-Type: application/json وكائن JSON.

MISSING_FIELDMISSING_FIELDSINVALID_FIELDMISSING_BODYMISSING_MESSAGEMISSING_URLHTTP 400

حقل إلزامي مفقود أو قيمته خارج النطاق؛ يذكر error.message اسم الحقل. صحّحه وأعد الإرسال.

INVALID_PHONEHTTP 400

الرقم ليس بصيغة E.164. أرسل + ورمز الدولة ثم الرقم دون مسافات: ‎+212612345678.

INVALID_URLHTTP 400

رابط ليس https:// أو غير صالح (webhook أو وسائط أو زر). استخدم رابط https عاماً.

INVALID_CHANNELCHANNEL_NOT_CONFIGUREDCHANNEL_DISABLEDUNSUPPORTED_CHANNELHTTP 400

قناة غير معروفة أو غير متاحة. في ‎/v1/messages تكون channel إما sms (الافتراضي) أو whatsapp؛ وفي ‎/v1/consents إما whatsapp أو sms أو any.

INVALID_PURPOSEINVALID_STATUSINVALID_SOURCEINVALID_EVIDENCEINVALID_DATEHTTP 400

الموافقات: purpose = marketing | transactional | otp | service؛ status = granted | withdrawn؛ source = api | form | import | dashboard؛ evidence = كائن JSON أقل من 4 كيلوبايت؛ التواريخ بصيغة ISO 8601 وrecorded_at ليس في المستقبل.

INVALID_PERMISSIONSSANDBOX_IMMUTABLEHTTP 400

مفاتيح API: امنح صلاحية صالحة واحدة على الأقل؛ ولا يتحول المفتاح أبداً بين التجريبي والحقيقي — أنشئ مفتاحاً جديداً.

NOT_FOUNDLIST_NOT_FOUNDLEAD_NOT_FOUNDTEMPLATE_NOT_FOUNDAPP_NOT_FOUNDSHEET_NOT_FOUNDINVALID_MESSAGE_IDHTTP 400 / 404

المورد غير موجود لهذا الحساب (أو لنمط المفتاح هذا: المفتاح التجريبي لا يرى العناصر الحقيقية)، أو أن المعرّف المطلوب غير صالح (مثل null أو غير محدد). تحقق من المعرّف والمفتاح.

METHOD_NOT_ALLOWEDHTTP 405

طريقة HTTP هذه غير موجودة على هذا المسار. راجع مرجع نقطة النهاية.

UNSUPPORTED_MEDIA_TYPEPAYLOAD_TOO_LARGEFILE_TOO_LARGEINVALID_FILE_TYPEINVALID_FORM_DATAMISSING_FILEEMPTY_SHEETPARSE_FAILEDMAPPING_ERRORFETCH_FAILEDINVALID_PATHNO_FILE_PROVIDEDNO_DATA_PROVIDEDUPLOAD_FAILEDHTTP 400 / 413 / 415 / 502

رُفض الملف أو الاستيراد: نوع غير مدعوم أو حجم كبير أو ملف فارغ أو أعمدة غير معروفة أو رابط يتعذر الوصول إليه. يحدد error.message السبب؛ صحّح الملف وأعد الإرسال.

الإرسال (SMS والعام)

INSUFFICIENT_BALANCEHTTP 402

الرصيد غير كافٍ لهذا الإرسال. اشحن من لوحة التحكم ← الفوترة؛ لم يُخصم أي مبلغ.

INTERNATIONAL_REQUIRES_TOPUPHTTP 403

الإرسال خارج المغرب متاح للحسابات التي شحنت رصيدها مرة واحدة على الأقل. قم بأول شحن.

QUOTA_EXCEEDEDHTTP 429

تم بلوغ الحصة اليومية المحددة لحسابك؛ وتتجدد عند منتصف الليل UTC. ارفعها من لوحة التحكم إن لزم. بعد خطأ 429 هذا أعد المحاولة بمفتاح Idempotency-Key جديد.

OPTED_OUTHTTP 403

ألغى هذا المستلم اشتراكه في رسائلك (STOP). لا تُعد الإرسال وأزله من قوائمك. يمكنه إعادة الاشتراك بنفسه.

SENDER_ID_TOO_LONGSENDER_ID_TOO_SHORTSENDER_ID_INVALIDHTTP 400

معرّف المرسل الأبجدي الرقمي من 3 إلى 11 حرفاً (حروف وأرقام ومسافة). صحّحه أو احذفه لاستخدام المرسل الافتراضي.

SENDER_ID_GENERICHTTP 400

معرّف مرسل عام (INFO، ALERT، SERVICE…) وليس علامة تجارية. استخدم اسم علامتك أو احذفه.

SENDER_ID_PROTECTED_BRANDHTTP 403

يشير معرّف المرسل إلى مؤسسة محمية أو يشبهها (بنك، مشغّل، إدارة). مخصّص للحساب المعتمد لهذا الاسم بالضبط.

SENDER_ID_NOT_APPROVEDSENDER_ID_PENDINGSENDER_ID_IN_REVIEWSENDER_ID_REJECTEDSENDER_ID_APPROVEDHTTP 403 / 409

تسجيل معرّف المرسل: لم يُعتمد بعد، أو قيد المراجعة، أو مرفوض، أو معتمد مسبقاً (409). تابع حالته في الإعدادات ← معرّفات المرسل.

SENDER_ID_NOT_REGISTEREDHTTP 403

لم يعد يُعاد منذ 27/09/2026: يُرسَل معرّف المرسل غير المسجّل تلقائياً بالتسعيرة القياسية. أُبقي عليه كي يظل الكود الذي يتحقق منه صالحاً.

SENDER_NOT_ASSIGNED_TO_WORKSPACEHTTP 403

معرّف المرسل المحدد غير مخصص لمساحة العمل هذه. عيّنه في الإعدادات ← مساحات العمل.

NO_SENDER_ID_ASSIGNEDHTTP 422

لا يوجد أي معرّف مرسل مخصص لمساحة العمل هذه. خصص معرّف مرسل معتمد في الإعدادات ← مساحات العمل.

WORKSPACE_BALANCE_EXHAUSTEDHTTP 402

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

SPAM_OR_PHISHING_DETECTEDCONTENT_BLOCKEDHTTP 400

رُفض المحتوى: رابط تصيّد، أو رسالة تتحدث باسم بنك أو مشغّل أو إدارة، أو مخالفة لشروط الاستخدام. عُلّق الحساب في انتظار المراجعة. للاعتراض: POST /v1/moderation/appeals مع error.appeal.id وerror.appeal.token وملاحظة (دون مفتاح API).

CONTENT_REFUSEDHTTP 400

رفض نظام مكافحة الإساءة المحتوى (الرفض الأول). لم يُرسل شيء والحساب لا يزال نشطاً؛ والرفض الثاني يعلّقه. أعد الصياغة أو اعترض عبر POST /v1/moderation/appeals.

INVALID_APPEALAPPEAL_NOT_FOUNDAPPEAL_ALREADY_FILEDHTTP 400 / 404 / 409

الاعتراض: المعرّف أو الرمز مفقود أو خاطئ، أو يوجد اعتراض مفتوح بالفعل لهذا الرفض.

EMPTY_BATCHTOO_MANY_MESSAGESHTTP 400

يقبل POST /v1/messages/bulk من 1 إلى 10,000 رسالة في كل طلب. قسّم الدفعات الأكبر.

SEND_PERSIST_FAILEDHTTP 502

تعذّر تسجيل الرسالة؛ لم يُرسل شيء ولم يُخصم شيء. أعد المحاولة بنفس Idempotency-Key.

واتساب

WHATSAPP_NOT_CONNECTEDHTTP 403

لا يوجد رقم واتساب للأعمال مرتبط بالحساب. اربطه من لوحة التحكم؛ وللنص البسيط احذف channel (SMS). لم يُخصم أي مبلغ.

OUT_OF_24H_WINDOWHTTP 400

رسالة واتساب حرة إلى جهة لم تراسلك خلال 24 ساعة. أرسل نموذجاً معتمداً (template) أو SMS. لم يُخصم أي مبلغ.

CONTACT_HAS_NO_PHONEHTTP 400

تستخدم هذه الجهة اسم مستخدم واتساب ولم تشارك رقمها: لا يمكن الوصول إليها إلا عبر واتساب، وليس عبر SMS. لم يُخصم أي مبلغ.

WHATSAPP_ONLY_FIELDBUTTONS_NOT_SUPPORTEDINTERACTIVE_NOT_SUPPORTEDHTTP 400

أُرسل حقل خاص بواتساب (buttons أو interactive أو reaction أو contacts أو location أو sticker أو context) عبر SMS. أضف "channel": "whatsapp" أو احذف الحقل.

CONFLICTING_MESSAGE_TYPESCASCADE_NOT_SUPPORTEDINVALID_MESSAGEHTTP 400

تحمل الرسالة نوع محتوى واحداً؛ ولا تُجمع reaction وcontacts وlocation وsticker مع أي شيء وليس لها مقابل SMS (دون cascade).

INVALID_REACTIONINVALID_CONTEXTINVALID_CONTACTSINVALID_LOCATIONINVALID_MEDIAHTTP 400

كائن واتساب غير صالح: reaction = {message_id, emoji}؛ context = {message_id}؛ contacts = من 1 إلى 20 بطاقة مع name.formatted_name؛ location = خط عرض وطول رقميان؛ الوسائط = "id" أو "link" بصيغة https، ولا شرح على الصوت/الملصق.

INVALID_INTERACTIVEINVALID_INTERACTIVE_TYPEMISSING_INTERACTIVE_ACTIONINTERACTIVE_BODY_TOO_LONGINVALID_CTA_URL_ACTIONMISSING_CTA_DISPLAY_TEXTCTA_DISPLAY_TEXT_TOO_LONGINVALID_LOCATION_REQUEST_ACTIONINVALID_FLOW_ACTIONMISSING_FLOW_IDMISSING_FLOW_CTAFLOW_CTA_TOO_LONGMISSING_CAROUSEL_CARDSTOO_MANY_CAROUSEL_CARDSINVALID_PRODUCT_ACTIONINVALID_PRODUCT_LISTMISSING_ORDER_ACTIONMISSING_ORDER_CURRENCYMISSING_ORDER_ITEMSMISSING_ORDER_PARAMETERSMISSING_REFERENCE_IDINVALID_TOTAL_AMOUNTMISSING_PHONE_NUMBERHTTP 400

رسالة interactive غير صالحة (قائمة، أزرار، cta_url، flow، دوّارة، منتج، طلب، location_request). يذكر error.message الحقل الخاطئ وحد واتساب الذي تجاوزه.

MISSING_BUTTONS_ARRAYINVALID_BUTTONINVALID_BUTTON_COUNTINVALID_BUTTON_TEXTINVALID_BUTTON_TYPEINVALID_REPLY_BUTTONBUTTON_TEXT_TOO_LONGBUTTON_TITLE_TOO_LONGTOO_MANY_BUTTONSMISSING_COPY_CODEMISSING_LIST_BUTTONLIST_BUTTON_TOO_LONGMISSING_LIST_SECTIONSTOO_MANY_SECTIONSSECTION_TITLE_TOO_LONGINVALID_SECTION_ROWSTOO_MANY_ROWSMISSING_ROW_IDMISSING_ROW_TITLEROW_ID_TOO_LONGROW_TITLE_TOO_LONGROW_DESC_TOO_LONGHTTP 400

أزرار أو قائمة خارج حدود واتساب: 3 أزرار كحد أقصى، وعنوان الزر 20 حرفاً، و10 أقسام و10 صفوف، وعنوان الصف 24 حرفاً، والوصف 72 حرفاً. يذكر error.message الحد الدقيق.

META_SERVICE_UNAVAILABLEHTTP 502

كان واتساب غير متاح مؤقتاً وفشل الإرسال بعد إعادة المحاولات التلقائية. أعد المحاولة بعد بضع دقائق.

النماذج والحملات

TEMPLATE_PENDING_REVIEWTEMPLATE_REJECTED_BY_REVIEWHTTP 409

النموذج بانتظار مراجعة EnvoiSMS (يُرسل إلى Meta بعد الموافقة)، أو رُفض في هذه المراجعة: عدّله لإعادته إلى المراجعة.

TEMPLATE_EXISTSTEMPLATE_ALREADY_ON_METATEMPLATE_EDIT_NOT_ALLOWEDTEMPLATE_IMMUTABLE_FIELDHTTP 400 / 409

يوجد نموذج بهذا الاسم، أو هو موجود لدى Meta (زامنه)، أو لا يمكن تعديله في حالته الحالية، أو تحاول تغيير حقل تثبّته Meta (الاسم أو اللغة أو فئة نموذج معتمد) — أنشئ نموذجاً جديداً.

INVALID_LANGUAGEINVALID_META_TEMPLATEINVALID_AUTH_TEMPLATEMISSING_SAMPLE_VALUESMISSING_HEADER_EXAMPLEINVALID_HEADER_EXAMPLEHEADER_EXAMPLE_INVALID_SIZEHEADER_EXAMPLE_INVALID_TYPEHEADER_EXAMPLE_UNREACHABLEHTTP 400

النموذج لا يحترم قواعد Meta: لغة غير معروفة، أو أمثلة المتغيرات مفقودة، أو وسائط الترويسة مفقودة أو يتعذر الوصول إليها أو من نوع خاطئ أو كبيرة جداً، أو نموذج مصادقة غير مطابق. يوضح error.message ذلك.

INVALID_WABAWHATSAPP_TOKEN_EXPIREDMETA_API_ERRORMETA_SUBMIT_FAILEDMETA_UPLOAD_FAILEDMETA_NOT_CONFIGUREDHTTP 400 / 502 / 503

رفضت Meta العملية على حساب واتساب للأعمال الخاص بك: waba_id لا يخصك، أو رمز اتصال منتهي (أعد ربط الحساب من لوحة التحكم)، أو خطأ من Meta. أعد المحاولة؛ وإن استمر تواصل مع الدعم.

TEMPLATE_NOT_APPROVEDMISSING_TEMPLATEMISSING_TEMPLATE_PARAMSHTTP 400

حملة أو محادثة واتساب: النموذج غير معتمد أو مفقود أو تنقصه متغيرات. يسرد MISSING_TEMPLATE_PARAMS ما يجب تقديمه في template_variables (_header_media_url أو _button_<i> أو "static:القيمة").

INVALID_WABA_SENDERMISSING_LISTEMPTY_LISTLIST_IN_USEHTTP 400

الحملة: مرسل واتساب غير مرتبط بحسابك، أو القائمة مفقودة أو بلا مستلمين مؤهلين، أو القائمة مستخدمة في حملة نشطة (ولا يمكن حذفها).

ALREADY_RUNNINGCAMPAIGN_RUNNINGCAMPAIGN_NOT_EDITABLENOT_PAUSEDNOT_RUNNINGHTTP 400 / 409

حالة الحملة لا تسمح بهذا الإجراء: لا تُعدَّل إلا الحملة المسودة أو المجدولة، ويجب إيقاف الحملة الجارية مؤقتاً قبل حذفها.

التحقق (OTP)

INVALID_CODEHTTP 400

رمز خاطئ. يذكر error.message عدد المحاولات المتبقية؛ دع المستخدم يحاول مجدداً.

MAX_ATTEMPTSHTTP 429

محاولات كثيرة: أُغلقت الجلسة. ابدأ جلسة جديدة عبر ‎/v1/verify/send.

SESSION_NOT_FOUNDSESSION_EXPIREDINVALID_STATEINVALID_SESSION_DATAINVALID_SESSION_IDHTTP 400 / 404 / 409

جلسة غير معروفة أو منتهية أو معرّف غير صالح (مثل null)، أو تم التحقق منها أو أُلغيت، أو أنشأها مفتاح من النمط الآخر (تجريبي/حقيقي). ابدأ تحققاً جديداً باستخدام المفتاح نفسه لـ send وresend وcheck.

OTP_COOLDOWNOTP_RATE_LIMITHTTP 429

أُرسل رمز للتو إلى هذا الرقم (30 ث عبر SMS و60 ث عبر واتساب)، أو أُرسلت رموز كثيرة خلال الساعة. انتظر Retry-After واقترح «إعادة الإرسال» عبر ‎/v1/verify/resend.

OTP_RESEND_LIMIT_EXCEEDEDHTTP 429

تم بلوغ الحد الأقصى لمحاولات إعادة الإرسال (4 إرسالات) لهذه الجلسة. انتظر حتى تنتهي صلاحية الجلسة قبل بدء جلسة جديدة.

OTP_COUNTRY_PAUSEDHTTP 429

رموز التحقق نحو هذا البلد (خارج المغرب) موقوفة لحسابك حتى 00:00 UTC: عدد قليل جداً من رموز اليوم تم تأكيده، وهو نمط إساءة آلية. يحمل Retry-After الثواني المتبقية.

COUNTRY_NOT_ALLOWEDHTTP 403

الرموز نحو هذا البلد غير مفتوحة لحسابك أو لتطبيق Verify الخاص بك. تواصل مع الدعم لفتحها.

WHATSAPP_UNAVAILABLEDELIVERY_FAILEDINVALID_CODE_TYPEBAD_GATEWAYHTTP 400 / 502 / 503

تعذّر إرسال الرمز عبر واتساب (غير متاح للحساب، أو مرفوض، أو رمز غير رقمي). لم يُخصم شيء؛ أعد الإرسال مع "channel": "sms".

HLR_UNAVAILABLEHTTP 503

تعذّر تنفيذ استعلام HLR (‎/v1/hlr): الخدمة غير متاحة مؤقتاً أو مقيّدة. أعد المحاولة بعد ثوانٍ؛ لم يُخصم شيء. و502 BAD_GATEWAY على هذا المسار يعني أن الشبكة لم تُجب — القاعدة نفسها، لا خصم.

LOOKUP_FAILEDLOOKUP_UNAVAILABLEHTTP 500 / 503

فشل البحث عن المشغّل (‎/v1/verify/lookup) أو أنه غير متاح. أعد المحاولة لاحقاً؛ لم يُخصم شيء.

حدود الطلبات والتكرار الآمن

RATE_LIMITEDTOO_MANY_REQUESTSRATE_LIMIT_EXCEEDEDHTTP 429

تم تجاوز حد الطلبات في الدقيقة لهذا المفتاح. انتظر Retry-After (بالثواني)؛ فالمحاولة قبل ذلك تستهلك النافذة التالية فقط.

INVALID_IDEMPOTENCY_KEYHTTP 400

يتجاوز Idempotency-Key ‏255 حرفاً. استخدم UUID أو معرّفاً قصيراً.

IDEMPOTENCY_IN_FLIGHTHTTP 409

الطلب الأصلي الذي يحمل هذا المفتاح لا يزال قيد التنفيذ. انتظر Retry-After وأعد المحاولة بالمفتاح نفسه.

IDEMPOTENCY_KEY_REUSEDHTTP 422

استُخدم مفتاح Idempotency-Key هذا مع نص طلب مختلف. المفتاح يخص طلباً واحداً: أنشئ مفتاحاً جديداً.

REPLAY_UNAVAILABLEHTTP 422

لا يحتوي تسليم الـ webhook هذا على محتوى محفوظ لإعادة إرساله. لا يمكن إعادة تشغيله.

الحساب والفوترة

LIMIT_EXCEEDEDHTTP 403

تم بلوغ الحد الأقصى لمفاتيح API أو الـ webhooks في باقتك. ألغِ أحدها أو غيّر الباقة.

INVALID_AMOUNTINVALID_PACKINVALID_PAYMENT_METHODUNSUPPORTED_METHODALREADY_COMPLETEDTRANSACTION_CANCELLEDRECEIPT_NOT_AVAILABLEINVOICE_NOT_AVAILABLESTRIPE_INVOICES_UNAVAILABLENO_STRIPE_CUSTOMERINVALID_THRESHOLDINVALID_CYCLEINVALID_CYCLE_LIMITNO_PAID_TOPUPNO_FIELDSHTTP 400 / 403 / 404 / 409 / 410

الشحن أو الشحن التلقائي: مبلغ أو حد أو سقف أو دورة أو باقة أو وسيلة دفع غير صالحة، أو يلزم شحن يدوي أول، أو عملية ملغاة أو مكتملة مسبقاً، أو لا توجد فاتورة متاحة (بعد).

STRIPE_ERRORPORTAL_ERRORCUSTOMER_CREATION_FAILEDSTRIPE_NOT_CONFIGUREDPAYMENT_METHOD_NOT_CONFIGUREDNOT_AVAILABLEINVOICE_TEMPORARILY_UNAVAILABLEINVOICE_BEING_GENERATEDINVALID_SIGNATUREHTTP 401 / 500 / 502 / 503

تعذّر الحصول على صفحة الدفع أو الفاتورة من جانبنا. لم يُخصم أي مبلغ؛ أعد المحاولة بعد لحظات.

من جانب الخادم

INTERNAL_ERRORDB_ERRORSERVICE_UNAVAILABLEBAD_REQUESTHTTP 400 / 500 / 503

خطأ من جانبنا. أعد المحاولة مع انتظار متزايد (وبنفس Idempotency-Key للإرسال)؛ وتواصل مع الدعم إن استمر.

رموز فشل التسليم

قد تفشل رسالة مقبولة (202) لاحقاً. يكون error_code الخاص بها — في GET /v1/messages/{id} وفي webhook ‏message.failed — أحد هذه الرموز. تُسترد تلقائياً قيمة رسالة واتساب رُفضت قبل إرسالها.

META_WINDOW_EXPIRED

مرّت أكثر من 24 ساعة على آخر رسالة من جهة الاتصال. أرسل نموذجاً معتمداً أو SMS.

META_UNDELIVERABLE

لا يمكن الوصول إلى الرقم عبر واتساب. لا إعادة محاولة تلقائية: استخدم SMS.

META_MARKETING_LIMIT

حد واتساب للرسائل التسويقية لكل مستلم. لا تُعد الإرسال فوراً.

META_RATE_LIMITED / META_PAIR_RATE_LIMITED

تم تجاوز سعة الرقم، أو أُرسلت رسائل كثيرة لهذه الجهة. فشل بعد إعادة المحاولات التلقائية؛ خفّف الوتيرة.

META_POLICY_BLOCKED / META_ACCOUNT_LOCKED / META_PAYMENT_ISSUE / META_PHONE_NOT_REGISTERED

الرقم أو الحساب المرسل في واتساب مقيّد أو مقفل أو بلا وسيلة دفع صالحة لدى Meta أو غير مسجّل. تحقق من WhatsApp Manager؛ رصيدك في EnvoiSMS ليس السبب.

META_TEMPLATE_NOT_FOUND / META_TEMPLATE_PARAM_MISMATCH / META_TEMPLATE_PARAM_FORMAT

النموذج غير موجود بهذه اللغة أو لم يُعتمد بعد، أو عدد المتغيرات خاطئ، أو متغير بصيغة خاطئة (وسائط الترويسة أو الزر).

META_UNSUPPORTED_TYPE

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

META_GENERIC_ERROR / META_SERVICE_UNAVAILABLE

خطأ مؤقت في واتساب استمر بعد إعادة المحاولات التلقائية. أعد الإرسال بعد بضع دقائق.

CASCADE_TIMEOUT

التسلسل: لم يصل إشعار تسليم خلال cascade_timeout؛ انتقلت الرسالة إلى القناة التالية (حدث message.fallback).

هل كان هذا القسم مفيداً؟

الحدود

الحدود#

الطلبات

لكل مفتاح في الدقيقة. القيمة الافتراضية لمفتاح جديد حسب الباقة: Starter ‏60، Business ‏180، Pro ‏500، Enterprise ‏1200. وما زاد: 429 RATE_LIMITED مع Retry-After.

الإرسال الجماعي

حتى 10,000 رسالة في كل طلب POST /v1/messages/bulk.

التحقق

رمز من 4 إلى 8 أرقام (6 افتراضياً)، صالح من 60 ثانية إلى 30 دقيقة (10 دقائق افتراضياً). إعادة الإرسال بعد 30 ثانية عبر SMS و60 ثانية عبر واتساب.

التكرار الآمن

مفتاح Idempotency-Key حتى 255 حرفاً، يُحفظ 24 ساعة لكل حساب.

حزم SDK

مكتبات العملاء#

اختيارية: كل مثال في هذه الصفحة يعمل عبر HTTP بسيط دون أي اعتماديات.

Node.jsTypeScript · JavaScript
npm install envoisms
مستودع GitHub
PythonPython 3.8+
pip install envoisms
مستودع GitHub
PHPPHP 8.1+
composer require envoisms/envoisms-php
مستودع GitHub
Laravel OTPLaravel 9–11
composer require envoisms/laravel-otp
مستودع GitHub
GoGo 1.21+
go get github.com/n4ouri/envoisms-go
مستودع GitHub
MCP serverClaude, Cursor, agents
npx -y @envoisms/mcp-server
مستودع GitHub
DocsMessages/messages
POSThttps://api.envoisms.ma/v1/messages
Bearer

إرسال رسالة

يضع رسالة SMS أو رسالة واتساب واحدة في قائمة الانتظار نحو مستلم واحد ويخصم ثمنها. يعيد 202 مع معرّف الرسالة؛ وتصل نتيجة التسليم لاحقاً عبر webhook أو عبر GET /v1/messages/:id.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
tostringمطلوبرقم المستلم بصيغة E.164 ‏(+212612345678).
messagestringمطلوبنص الرسالة، 1600 حرف كحد أقصى (يُقتطع ما زاد). الاسم البديل: body. اختياري على واتساب عندما يحمل الطلب قالباً أو وسائط أو تفاعلاً أو جهات اتصال أو موقعاً أو رسالة تفاعلية.
sender_idstringاختياريSMS: الاسم الذي يظهر لدى المستلم (حروف وأرقام ومسافات، من 3 إلى 11 حرفاً؛ يُرفض الاسم العام مثل INFO أو اسم بنك). إن أُغفل، تُرسل الرسالة باسم مرسلنا المشترك EnvoiSMS بسعر 0.792 درهم. اسمك الخاص يعمل دون أي إجراء بسعر 1.70 درهم ما لم يُعتمد بالسجل التجاري، ثم بالسعر العادي بعد اعتماده. واتساب: الرقم المتصل الذي يرسل. الأسماء البديلة: from وsender.
channelstringاختياري"sms" (الافتراضي) أو "whatsapp". يرسل "whatsapp" من رقم واتساب للأعمال الخاص بك والمتصل (وإلا 403 WHATSAPP_NOT_CONNECTED). ما لم تكن الرسالة قالباً، لا تُقبل رسالة واتساب إلا إذا راسلك جهة الاتصال خلال آخر 24 ساعة؛ وإلا 400 OUT_OF_24H_WINDOW دون أي خصم.
cascadeboolean | string[]اختياريtrue: يحاول واتساب ثم يتحول إلى SMS — فوراً إذا رفض واتساب الرسالة أو أبلغ بفشلها، أو إذا لم يصل إشعار التسليم خلال cascade_timeout. يقبل أيضاً قائمة مرتّبة مثل ["whatsapp", "sms"]. لا يُفوتَر إلا الإرسال الذي خرج فعلاً؛ ورسالة واتساب التي لم يصل إشعارها قد خرجت، فتُفوتَر مع رسالة SMS الاحتياطية وتُسترد إذا أبلغ واتساب لاحقاً بفشلها.
cascade_timeoutintegerاختياريمع cascade: عدد ثواني انتظار إشعار التسليم قبل القناة التالية، من 30 إلى 43200. الافتراضي: 120. اجعل مدة صلاحية (TTL) قالب واتساب لا تتجاوز هذه القيمة، حتى لا يستلم الهاتف العائد للاتصال الرسالتين معاً.
templateobjectاختياري(واتساب) قالب معتمد في حسابك: {"name"، "language"، "components"?}. توضع قيم متغيرات النص في metadata.variables. النوع الوحيد المسموح به خارج نافذة الـ 24 ساعة؛ ويُسعَّر حسب فئة القالب.
metadataobjectاختياريأزواج مفتاح-قيمة تُحفظ مع الرسالة وتُعاد في Webhooks (لا في GET /v1/messages). مفاتيح تقرؤها المنصة: variables (قيم القالب)، وmedia_url وmedia_type (ترويسة وسائط القالب)، وpurpose: "otp" (انظر الملاحظات).
buttonsarrayاختياري(واتساب) حتى 3 أزرار {"type"، "text"}؛ لا يتجاوز text ‏25 حرفاً. النوع "copy" يتطلب copy_code، و"url" يتطلب url ‏(http أو https)، و"call" يتطلب phone_number.
interactiveobjectاختياري(واتساب) رسالة تفاعلية بصيغة واتساب: قائمة ("list")، أزرار رد ("button"، من 1 إلى 3)، استمارة ("flow")، زر رابط ("cta_url") أو طلب موقع ("location_request_message").
image | video | audio | document | stickerobjectاختياري(واتساب) وسائط عبر "id" (معرّف وسائط مرفوعة) أو عبر "link" (رابط https)، وليس الاثنين معاً. "caption" للصورة والفيديو والمستند؛ و"filename" للمستند.
reactionobjectاختياري(واتساب) {"message_id": wamid، "emoji": "👍"} — تفاعل مع رسالة من المحادثة؛ الرمز الفارغ يزيل التفاعل. غير مُفوتَر.
contactsarrayاختياري(واتساب) بطاقات جهات اتصال (20 كحد أقصى): name.formatted_name إلزامي؛ وphones وemails وurls وaddresses وorg وbirthday اختيارية.
locationobjectاختياري(واتساب) دبوس موقع: {"latitude"، "longitude"، "name"?، "address"?}.
contextobjectاختياري(واتساب) {"message_id": wamid} — رد مع اقتباس رسالة سابقة. صالح لجميع الأنواع باستثناء reaction.
phone_number_idstringاختياري(واتساب) معرّف Meta للرقم المتصل الذي يرسل؛ افتراضياً رقمك الافتراضي.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • التكرار الآمن: أرسل ترويسة Idempotency-Key ‏(255 حرفاً كحد أقصى) لإعادة محاولة الطلب دون إرسال مزدوج. خلال 24 ساعة يعيد المفتاح نفسه مع النص نفسه الاستجابة الأصلية (مع الترويسة Idempotency-Replayed: true)؛ ومع نص مختلف 422 IDEMPOTENCY_KEY_REUSED؛ وما دام الطلب الأول قيد التنفيذ 409 IDEMPOTENCY_IN_FLIGHT.
  • مفتاح تجريبي (env_test_…): لا يُرسل ولا يُخصم شيء؛ قيمة cost صفر، وتضيف الاستجابة "sandbox": true و"simulated_cost" (الثمن الذي كان سيدفعه مفتاح حقيقي) و"warnings" عند الاقتضاء (ما كان سيُرفض لمفتاح حقيقي، مثل نافذة 24 ساعة مغلقة).
  • الرموز لمرة واحدة: يتولى ‎/v1/verify/send الدورة كاملة ويبقى المسار الموصى به. إذا كنت تنشئ رموزك بنفسك وترسلها هنا، أضف metadata: {"purpose": "otp"}: عند فشل تسليم مؤكد من الشبكة نحو رقم مغربي والرمز لم يتجاوز 10 دقائق، تعيد المنصة إرساله مرة واحدة عبر مسار SMS آخر، بنفس معرّف الرسالة ودون تكلفة إضافية.
  • أخطاء شائعة: 400 INVALID_PHONE و400 OUT_OF_24H_WINDOW و400 SENDER_ID_GENERIC و402 INSUFFICIENT_BALANCE و403 WHATSAPP_NOT_CONNECTED و403 SENDER_ID_PROTECTED_BRAND. لا يُخصم أي طلب مرفوض.
  • التنسيق: فواصل الأسطر (‎\n) تعمل على جميع القنوات. رسالة SMS نص عادي؛ ويعرض واتساب *العريض* و_المائل_ و~المشطوب~.
POSThttps://api.envoisms.ma/v1/messages
curl -X POST "https://api.envoisms.ma/v1/messages" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+212612345678",
    "message": "Your order #1042 has shipped."
  }'
{
  "id": "msg_3f9a1c7e5b2d4a6f8e0c1b3d",
  "to": "+212612345678",
  "channel": "sms",
  "cascade": false,
  "status": "queued",
  "cost": { "eur": 0.072, "mad": 0.792 },
  "segments": 1,
  "created_at": "2026-10-22T09:14:03.512Z"
}
DocsMessages/messages/bulk
POSThttps://api.envoisms.ma/v1/messages/bulk
Bearer

إرسال جماعي

يضع حتى 10,000 رسالة في قائمة الانتظار في طلب واحد، لكل منها مستلمها ونصها. يعيد 202 مع batch_id والرسائل المقبولة والمرفوضة إن وُجدت.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
messagesarrayمطلوبمصفوفة من 1 إلى 10,000 كائن: "to" ‏(E.164) و"message" (أو "body")، واختيارياً "metadata" و"buttons" (واتساب).
sender_idstringاختياريمرسل موحّد للدفعة كاملة (نفس قواعد POST /v1/messages). الأسماء البديلة: from وsender.
channelstringاختياري"sms" (الافتراضي) أو "whatsapp". على واتساب لا يحمل الإرسال الجماعي قالباً: يجب أن يكون كل مستلم داخل نافذة الـ 24 ساعة الخاصة به.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • تُتحقَّق الدفعة كاملة قبل أي إرسال: يكفي إدخال واحد غير صالح لفشل الطلب بـ 400 INVALID_MESSAGE مع قائمة أول 20 إدخالاً خاطئاً (الفهرس والقاعدة). ويُتحقَّق من الرصيد للدفعة كاملة (402 INSUFFICIENT_BALANCE).
  • يسرد "rejected" الإدخالات المرفوضة واحداً واحداً (إلغاء اشتراك، نافذة 24 ساعة مغلقة…) مع رمزها؛ ولا تُخصم. لا يظهر إلا عند وجودها. و"estimated_cost" هو تقدير الدفعة قبل الرفض.
  • تُقبل الترويسة Idempotency-Key بنفس قواعد POST /v1/messages.
POSThttps://api.envoisms.ma/v1/messages/bulk
curl -X POST "https://api.envoisms.ma/v1/messages/bulk" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "to": "+212611111111",
        "message": "Your appointment is tomorrow at 10:00."
      },
      {
        "to": "+212622222222",
        "message": "Your appointment is tomorrow at 11:30."
      }
    ]
  }'
{
  "batch_id": "batch_9a3c5e7f1b2d4c6e8a0f2b4d",
  "total": 2,
  "channel": "sms",
  "estimated_cost": { "eur": 0.144, "mad": 1.584 },
  "messages": [
    { "id": "msg_1a2b3c4d5e6f7a8b9c0d1e2f", "to": "+212611111111", "status": "queued" },
    { "id": "msg_3c4d5e6f7a8b9c0d1e2f3a4b", "to": "+212622222222", "status": "queued" }
  ],
  "rejected": [
    { "to": "+212633333333", "code": "OPTED_OUT", "message": "This number opted out of messages from your account" }
  ]
}
DocsMessages/messages/typing
POSThttps://api.envoisms.ma/v1/messages/typing
Bearer

مؤشر الكتابة في واتساب

يضع علامة «مقروءة» على رسالة واتساب مستلمة ويُظهر لمرسلها «يكتب…» أثناء تحضير الرد (حتى ترد أو نحو 25 ثانية). لا يُخزَّن ولا يُفوتَر أي شيء.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
message_idstringمطلوبمعرّف واتساب (wamid) للرسالة المستلمة التي ترد عليها.
typing_indicatorbooleanاختياريالقيمة false ترسل إشعار القراءة فقط. الافتراضي: true.
phone_number_idstringاختياريالرقم المتصل الذي استلم الرسالة؛ افتراضياً رقمك الافتراضي.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • مع مفتاح تجريبي لا يصل شيء إلى واتساب وتكون الاستجابة {"status": "simulated"، "sandbox": true، "message_id"، "typing_indicator"}.
POSThttps://api.envoisms.ma/v1/messages/typing
curl -X POST "https://api.envoisms.ma/v1/messages/typing" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message_id": "wamid.HBgMMjEyNjEyMzQ1Njc4FQIAEhg",
    "typing_indicator": true
  }'
{
  "status": "ok",
  "message_id": "wamid.HBgLMjEyNjEyMzQ1Njc4FQIAEhgg",
  "typing_indicator": true
}
DocsMessages/messages
GEThttps://api.envoisms.ma/v1/messages
Bearer

قائمة الرسائل

يعيد رسائل الحساب من الأحدث إلى الأقدم، مع عوامل تصفية وتقسيم على صفحات. format=csv يصدّر المجموعة المصفاة كاملة.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 50 افتراضياً و200 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
statusstringاختياريqueued أو sent أو delivered أو read (واتساب) أو failed أو undeliverable أو unconfirmed.
channelstringاختياريsms أو whatsapp.
campaign_idstringاختياريرسائل حملة واحدة (cmp_…).
from_datestringاختياريالمُنشأة ابتداءً من هذا التاريخ (UTC). اكتبه بصيغة YYYY-MM-DD: يُقارن مع created_at ذي الصيغة "YYYY-MM-DD HH:MM:SS".
to_datestringاختياريالمُنشأة حتى هذا التاريخ (UTC)، بنفس المقارنة. لتضمين يوم كامل، مرّر اليوم التالي.
formatstringاختياريcsv: ينزّل المجموعة المصفاة كاملة (حتى سقف التصدير المذكور في الملف) بدل صفحة واحدة.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: status.
  • لا يرى المفتاح إلا رسائل نمطه: المفتاح التجريبي لا يعرض إلا الإرسالات المحاكاة، والمفتاح الحقيقي لا يعرض إلا الإرسالات الفعلية.
GEThttps://api.envoisms.ma/v1/messages
curl -X GET "https://api.envoisms.ma/v1/messages?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "msg_3f9a1c7e5b2d4a6f8e0c1b3d",
      "campaign_id": null,
      "to": "+212612345678",
      "channel": "sms",
      "body": "Votre commande 4512 est expédiée.",
      "sender_id": "MABOUTIQUE",
      "unicode": 0,
      "segments": 1,
      "status": "delivered",
      "error_code": null,
      "error_message": null,
      "cost_eur": 0.072,
      "cost_mad": 0.792,
      "scheduled_at": null,
      "sent_at": "2026-10-22 09:14:05",
      "delivered_at": "2026-10-22 09:14:09",
      "read_at": null,
      "failed_at": null,
      "created_at": "2026-10-22 09:14:03",
      "operator": "Maroc Telecom",
      "sandbox": 0
    }
  ],
  "limit": 50,
  "offset": 0,
  "total": 1
}
DocsMessages/messages/:id
GEThttps://api.envoisms.ma/v1/messages/:id
Bearer

عرض رسالة

يعيد رسالة واحدة وحالة تسليمها. 404 NOT_FOUND إذا لم يكن المعرّف تابعاً للحساب أو لنمط المفتاح.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: status.
  • الحالات: queued وsent وdelivered وread (واتساب) وfailed وundeliverable وunconfirmed. تعني "unconfirmed" أن المشغّل لم يؤكد التسليم ولم ينفه؛ وقد يحل محلها إشعار يصل لاحقاً.
  • لا يُعاد هنا حقل metadata المقدَّم عند الإرسال؛ بل يرافق Webhooks.
GEThttps://api.envoisms.ma/v1/messages/:id
curl -X GET "https://api.envoisms.ma/v1/messages/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "msg_3f9a1c7e5b2d4a6f8e0c1b3d",
  "campaign_id": null,
  "to": "+212612345678",
  "channel": "sms",
  "body": "Votre commande 4512 est expédiée.",
  "sender_id": "MABOUTIQUE",
  "unicode": 0,
  "segments": 1,
  "status": "delivered",
  "error_code": null,
  "error_message": null,
  "cost_eur": 0.072,
  "cost_mad": 0.792,
  "scheduled_at": null,
  "sent_at": "2026-10-22 09:14:05",
  "delivered_at": "2026-10-22 09:14:09",
  "read_at": null,
  "failed_at": null,
  "created_at": "2026-10-22 09:14:03",
  "operator": "Maroc Telecom",
  "sandbox": 0
}
DocsTemplates/templates
GEThttps://api.envoisms.ma/v1/templates
Bearer

قائمة القوالب

يعيد القوالب النشطة في الحساب (SMS وواتساب) من الأحدث إلى الأقدم، أياً كانت حالتها.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
channelstringاختياريsms أو whatsapp أو telegram أو any.
categorystringاختياريmarketing أو utility أو authentication.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • "variables" سلسلة JSON تصف بنية القالب: المتغيرات والقيم التوضيحية والترويسة والتذييل والأزرار والدوّار والمراجعة.
  • حالات واتساب: pending_admin (مراجعة EnvoiSMS) وpending_meta وapproved وrejected وpaused وdisabled وin_appeal وflagged وdeleted_on_meta. قالب SMS يكون approved فور إنشائه.
GEThttps://api.envoisms.ma/v1/templates
curl -X GET "https://api.envoisms.ma/v1/templates" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "tpl_4c1e9a7b3d5f2e8a6c0b1d3f",
      "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
      "name": "order_shipped",
      "channel": "whatsapp",
      "body": "Bonjour {{1}}, votre commande {{2}} est expédiée.",
      "variables": "{\"variables\":[\"1\",\"2\"],\"parameter_format\":\"positional\",\"sample_values\":{\"1\":\"Amine\",\"2\":\"4512\"},\"header_type\":\"none\",\"header_text\":null,\"footer\":null,\"buttons\":[]}",
      "category": "utility",
      "active": 1,
      "created_at": "2026-10-20 14:02:11",
      "status": "approved",
      "rejection_reason": null,
      "meta_template_id": "1203948576102938",
      "language": "fr",
      "quality_score": "GREEN",
      "quality_updated_at": "2026-10-21 08:00:00",
      "waba_id": null
    }
  ]
}
DocsTemplates/templates
POSThttps://api.envoisms.ma/v1/templates
Bearer

إنشاء قالب

ينشئ قالب SMS (قابلاً للاستخدام فوراً) أو قالب واتساب (تراجعه EnvoiSMS ثم يُقدَّم إلى Meta على حساب واتساب للأعمال الخاص بك). يعيد 201 مع السطر المُنشأ.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
namestringمطلوباسم القالب. يُحوَّل إلى أحرف صغيرة؛ وكل حرف غير a-z و0-9 و_ يصبح _.
channelstringمطلوبsms أو whatsapp أو telegram أو any.
bodystringمطلوبنص القالب. واتساب: 1024 حرفاً كحد أقصى؛ المتغيرات إما كلها مرقّمة ابتداءً من {{1}} ومتتالية، وإما كلها مسمّاة بأحرف صغيرة ({{first_name}})؛ ولا تكون أبداً في بداية النص أو نهايته ولا متلاصقة. غير مطلوب لقالب واتساب "authentication" الذي تحدد Meta نصه.
categorystringاختياريmarketing (الافتراضي) أو utility أو authentication. القيمة otp تعني authentication، وtransactional تعني utility. قد تعيد Meta تحديد الفئة عند المراجعة.
languagestringاختياري(واتساب) رمز لغة Meta، مثل fr وar وen_US وes. الافتراضي: fr.
sample_valuesobject | string[]اختياري(واتساب) قيمة توضيحية لكل متغير، تشترطها Meta: {"1": "Amine"} أو ["Amine"]. بدونها 400 MISSING_SAMPLE_VALUES.
variablesstring[]اختياري(SMS) أسماء متغيرات النص، تُحفظ كما هي.
header_typestringاختياري(واتساب) none (الافتراضي) أو text أو image أو video أو document. ترويسة text تأخذ header_text ‏(60 حرفاً، ومتغير واحد كحد أقصى مع header_sample)؛ وترويسة الوسائط تتطلب header_example_url.
header_text | header_sample | header_example_urlstringاختياري(واتساب) نص الترويسة؛ القيمة التوضيحية لمتغيرها؛ رابط https عام لملف توضيحي لترويسة صورة أو فيديو أو مستند (400 MISSING_HEADER_EXAMPLE إذا غاب).
footerstringاختياري(واتساب) تذييل، 60 حرفاً كحد أقصى.
buttonsarrayاختياري(واتساب) حتى 10 أزرار {"type"، "text"} ‏(25 حرفاً). الأنواع: quick_reply؛ url (مع url ‏http(s)، وurl_example إذا انتهى الرابط بمتغير)؛ phone_number (مع phone_number)؛ copy_code (مع copy_code)؛ flow (مع flow_id، معرّف أحد WhatsApp Flows المنشورة لديك، وnavigate_screen، و"LEAD" افتراضياً).
carouselobjectاختياري(واتساب، marketing أو utility) {"header_type": "image" | "video"، "cards": [...]}: من 2 إلى 10 بطاقات، كل منها {"header_example_url" ‏(https)، "body" ‏(160 حرفاً بلا متغير)، "buttons" ‏(1 أو 2، quick_reply أو url بلا متغير)}. تحمل كل البطاقات الأزرار نفسها. ولا يملك قالب الدوّار ترويسة ولا تذييلاً ولا أزراراً خاصة به.
add_security_recommendation | code_expiration_minutes | otp_type | supported_appsmixedاختياري(واتساب، authentication) تنبيه الأمان من Meta (قيمة منطقية)؛ صلاحية الرمز من 1 إلى 90 دقيقة؛ COPY_CODE (الافتراضي) أو ONE_TAP أو ZERO_TAP؛ supported_apps ‏[{"package_name"، "signature_hash" ‏(11 حرفاً)}] مطلوبة لـ ONE_TAP وZERO_TAP. ويتطلب ZERO_TAP أيضاً zero_tap_terms_accepted: true.
waba_idstringاختياري(واتساب) حساب واتساب للأعمال المستهدف إذا كان للحساب أكثر من واحد؛ يجب أن يكون أحد حساباتك المتصلة (وإلا 400 INVALID_WABA).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • المراجعة: يُنشأ قالب واتساب بحالة pending_admin. تجري فوراً فحوص آلية (انتحال صفة بنك، رابط تصيّد، مستضيف روابط مؤقتة، حساب غير نشط)؛ فإن لم تجد شيئاً يُقدَّم القالب إلى Meta ‏(pending_meta) وتُظهر الاستجابة ذلك مباشرة. وإلا يبقى pending_admin لمراجعة بشرية. Meta وحدها تعتمده (approved) وتحدد فئته النهائية.
  • الأخطاء: 400 MISSING_FIELD وINVALID_CHANNEL وINVALID_LANGUAGE وINVALID_META_TEMPLATE وMISSING_SAMPLE_VALUES وMISSING_HEADER_EXAMPLE وINVALID_AUTH_TEMPLATE وINVALID_WABA؛ و409 TEMPLATE_EXISTS (الاسم واللغة نفسهما نشطان مسبقاً؛ ويُستبدل القالب المرفوض الذي يحمل الاسم نفسه).
POSThttps://api.envoisms.ma/v1/templates
curl -X POST "https://api.envoisms.ma/v1/templates" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "order_shipped",
    "channel": "whatsapp",
    "category": "utility",
    "language": "fr",
    "body": "Bonjour {{1}}, votre commande {{2}} est expédiée.",
    "sample_values": [
      "Karim",
      "#1042"
    ]
  }'
{
  "id": "tpl_8e2a4c6b1d3f5a7c9e0b2d4f",
  "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
  "name": "catalogue_automne",
  "channel": "whatsapp",
  "body": "Découvrez notre sélection d’automne, {{1}} !",
  "variables": "{\"header_type\":\"none\",\"header_text\":null,\"footer\":null,\"buttons\":[],\"carousel\":{\"header_type\":\"image\",\"cards\":[{\"header_example_url\":\"https://example.ma/veste.jpg\",\"body\":\"Veste en laine\",\"buttons\":[{\"type\":\"url\",\"text\":\"Voir\",\"url\":\"https://example.ma/veste\"}]},{\"header_example_url\":\"https://example.ma/pull.jpg\",\"body\":\"Pull en coton\",\"buttons\":[{\"type\":\"url\",\"text\":\"Voir\",\"url\":\"https://example.ma/pull\"}]}]},\"variables\":[\"1\"],\"parameter_format\":\"positional\",\"sample_values\":{\"1\":\"Amine\"}}",
  "category": "marketing",
  "active": 1,
  "created_at": "2026-10-22 09:20:41",
  "status": "pending_meta",
  "rejection_reason": null,
  "meta_template_id": "1203948576102944",
  "language": "fr",
  "quality_score": null,
  "quality_updated_at": null,
  "waba_id": null
}
DocsTemplates/templates/:id
GEThttps://api.envoisms.ma/v1/templates/:id
Bearer

عرض قالب

يعيد قالباً نشطاً في الحساب مع حالته و، إن رُفض، rejection_reason. وإلا 404 NOT_FOUND.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
GEThttps://api.envoisms.ma/v1/templates/:id
curl -X GET "https://api.envoisms.ma/v1/templates/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "tpl_4c1e9a7b3d5f2e8a6c0b1d3f",
  "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
  "name": "order_shipped",
  "channel": "whatsapp",
  "body": "Bonjour {{1}}, votre commande {{2}} est expédiée.",
  "variables": "{\"variables\":[\"1\",\"2\"],\"parameter_format\":\"positional\",\"sample_values\":{\"1\":\"Amine\",\"2\":\"4512\"},\"header_type\":\"none\",\"header_text\":null,\"footer\":null,\"buttons\":[]}",
  "category": "utility",
  "active": 1,
  "created_at": "2026-10-20 14:02:11",
  "status": "approved",
  "rejection_reason": null,
  "meta_template_id": "1203948576102938",
  "language": "fr",
  "quality_score": "GREEN",
  "quality_updated_at": "2026-10-21 08:00:00",
  "waba_id": null
}
DocsTemplates/templates/:id
PATCHhttps://api.envoisms.ma/v1/templates/:id
Bearer

تعديل قالب

يعدّل قالباً بنفس حقول الإنشاء؛ لا يتغير إلا ما ترسله. يعيد السطر المحدَّث.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
name | body | category | language | sample_values | header_* | footer | buttons | carouselmixedاختيارينفس الحقول والقواعد في POST /v1/templates. قالب SMS لا يقبل إلا name وbody وcategory وvariables.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • واتساب، قالب لم يصل Meta بعد: يعيده التعديل إلى المراجعة (pending_admin ثم الفحوص الآلية). قالب موجود لدى Meta: يُقدَّم التعديل إلى Meta ويعود القالب إلى pending_meta؛ ولا يتغير الاسم ولا اللغة بعد ذلك (400 TEMPLATE_IMMUTABLE_FIELD)، ولا فئة القالب المعتمد؛ ولا تعديل أثناء pending_meta أو in_appeal أو disabled ‏(409 TEMPLATE_EDIT_NOT_ALLOWED).
PATCHhttps://api.envoisms.ma/v1/templates/:id
curl -X PATCH "https://api.envoisms.ma/v1/templates/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "tpl_4c1e9a7b3d5f2e8a6c0b1d3f",
  "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
  "name": "order_shipped",
  "channel": "whatsapp",
  "body": "Bonjour {{1}}, votre commande {{2}} est en route.",
  "variables": "{\"variables\":[\"1\",\"2\"],\"parameter_format\":\"positional\",\"sample_values\":{\"1\":\"Amine\",\"2\":\"4512\"},\"header_type\":\"none\",\"header_text\":null,\"footer\":null,\"buttons\":[]}",
  "category": "utility",
  "active": 1,
  "created_at": "2026-10-20 14:02:11",
  "status": "pending_meta",
  "rejection_reason": null,
  "meta_template_id": "1203948576102938",
  "language": "fr",
  "quality_score": "GREEN",
  "quality_updated_at": "2026-10-21 08:00:00",
  "waba_id": null
}
DocsTemplates/templates/:id
DELETEhttps://api.envoisms.ma/v1/templates/:id
Bearer

حذف قالب

يعطّل القالب. ويُحذف قالب واتساب الموجود لدى Meta هناك أيضاً؛ يبيّن meta_deleted ما إذا فعلت Meta ذلك، وmeta_note سبب عدمه.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
DELETEhttps://api.envoisms.ma/v1/templates/:id
curl -X DELETE "https://api.envoisms.ma/v1/templates/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "deleted": true,
  "id": "tpl_4c1e9a7b3d5f2e8a6c0b1d3f",
  "meta_deleted": true
}
DocsTemplates/templates/:id/submit-meta
POSThttps://api.envoisms.ma/v1/templates/:id/submit-meta
Bearer

تقديم قالب إلى Meta

يقدّم إلى Meta قالب واتساب اجتاز مراجعة EnvoiSMS لكنه غير موجود لدى Meta (حذفته Meta مثلاً). ليس وسيلة لتجاوز المراجعة.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • حالات الرفض: 409 TEMPLATE_PENDING_REVIEW (القالب ينتظر مراجعة EnvoiSMS؛ ويُقدَّم إلى Meta بعد اعتماده)، 409 TEMPLATE_REJECTED_BY_REVIEW (رفضته المراجعة؛ عدّله لإعادته إلى المراجعة)، 409 TEMPLATE_ALREADY_ON_META، و400 INVALID_CHANNEL (ليس قالب واتساب).
POSThttps://api.envoisms.ma/v1/templates/:id/submit-meta
curl -X POST "https://api.envoisms.ma/v1/templates/{id}/submit-meta" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "ok": true,
  "template": {
    "id": "tpl_4c1e9a7b3d5f2e8a6c0b1d3f",
    "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
    "name": "order_shipped",
    "channel": "whatsapp",
    "body": "Bonjour {{1}}, votre commande {{2}} est expédiée.",
    "variables": "{\"variables\":[\"1\",\"2\"],\"parameter_format\":\"positional\",\"sample_values\":{\"1\":\"Amine\",\"2\":\"4512\"},\"header_type\":\"none\",\"header_text\":null,\"footer\":null,\"buttons\":[]}",
    "category": "utility",
    "active": 1,
    "created_at": "2026-10-20 14:02:11",
    "status": "pending_meta",
    "rejection_reason": null,
    "meta_template_id": "1203948576102951",
    "language": "fr",
    "quality_score": null,
    "quality_updated_at": null,
    "waba_id": null
  },
  "meta": { "id": "1203948576102951", "status": "PENDING", "category": "UTILITY" }
}
DocsTemplates/templates/sync
POSThttps://api.envoisms.ma/v1/templates/sync
Bearer

مزامنة القوالب من Meta

يستورد قوالب حسابات واتساب للأعمال الخاصة بك (الحالة، الفئة، الجودة). يصبح القالب الذي لم يعد لدى Meta بحالة deleted_on_meta، إلا إذا كانت المزامنة ناقصة (complete: false).

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
POSThttps://api.envoisms.ma/v1/templates/sync
curl -X POST "https://api.envoisms.ma/v1/templates/sync" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "ok": true,
  "wabas": ["104857392017465"],
  "fetched": 12,
  "updated": 9,
  "inserted": 3,
  "deduped": 0,
  "marked_deleted": 1,
  "complete": true,
  "errors": []
}
DocsSender IDs/sender-ids
GEThttps://api.envoisms.ma/v1/sender-ids
Bearer

قائمة مُعرّفات المرسل

يعيد طلبات مُعرّف مرسل SMS الخاصة بك وحالتها، مع اسم مقترح انطلاقاً من ملفك.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: sender_id.
GEThttps://api.envoisms.ma/v1/sender-ids
curl -X GET "https://api.envoisms.ma/v1/sender-ids" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "sid_6a2c8e4b0d1f3a5c7e9b2d4f",
      "sender_id": "MABOUTIQUE",
      "status": "approved",
      "rc_url": "/v1/sender-ids/rc/acct_7b2e4c6a8d0f1e3b5c7a9d2f/rc_1f3a5c7e9b2d4f6a8c0e2b4d.pdf",
      "note": null,
      "requested_at": "2026-10-02 10:15:00",
      "reviewed_at": "2026-10-09 16:40:00",
      "company_website": "https://maboutique.ma",
      "sample_content": "Votre commande 4512 est expédiée.",
      "message_type": "transactional",
      "estimated_volume": "5000/mois",
      "operator_emailed_at": "2026-10-02 10:20:00"
    }
  ],
  "suggestedSenderId": "MABOUTIQUE"
}
DocsSender IDs/sender-ids
POSThttps://api.envoisms.ma/v1/sender-ids
Bearer

طلب مُعرّف مرسل

يقدّم طلب مُعرّف مرسل SMS مرفقاً بالسجل التجاري بصيغة PDF. النص بصيغة multipart/form-data. يعيد 201 (أو 200 عند تحديث طلب قائم) بحالة pending.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
sender_idstringمطلوبالاسم المطلوب: حروف بلا تشكيل وأرقام ومسافات، 11 حرفاً كحد أقصى، وحرف واحد على الأقل. يُرفض الاسم العام (INFO وALERT…) أو اسم مؤسسة محمية.
filefileمطلوبالسجل التجاري، ملف PDF لا يتجاوز 5 ميغابايت.
message_typestringاختياريtransactional (الافتراضي) أو promotional.
company_website | sample_content | estimated_volumestringاختياريموقع الشركة ومثال للرسالة والحجم المقدَّر، تُرسَل إلى المشغّلين مع الطلب.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: sender_id.
  • الأخطاء: 400 INVALID_FORM_DATA وMISSING_FIELD وINVALID_FIELD وSENDER_ID_GENERIC وINVALID_FILE_TYPE وFILE_TOO_LARGE؛ و403 SENDER_ID_PROTECTED_BRAND؛ و409 SENDER_ID_PENDING أو SENDER_ID_APPROVED.
POSThttps://api.envoisms.ma/v1/sender-ids
curl -X POST "https://api.envoisms.ma/v1/sender-ids" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "sid_6a2c8e4b0d1f3a5c7e9b2d4f",
  "sender_id": "MABOUTIQUE",
  "status": "pending",
  "rc_url": "/v1/sender-ids/rc/acct_7b2e4c6a8d0f1e3b5c7a9d2f/rc_1f3a5c7e9b2d4f6a8c0e2b4d.pdf"
}
DocsWhatsApp/whatsapp/waba-connection
GEThttps://api.envoisms.ma/v1/whatsapp/waba-connection
Bearer

ربط واتساب للأعمال

يعيد حالة أرقام واتساب للأعمال المتصلة لديك وقائمة تحقق الرقم الافتراضي (readiness): ما يمنعه من الإرسال حسب Meta. قراءة فقط؛ ولا يُعاد أي سر.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • أي مفتاح API صالح: لا تُشترط صلاحية بعينها.
  • readiness: قيمة can_send هي AVAILABLE أو LIMITED أو BLOCKED أو unknown (لم تُجب Meta)؛ وblockers تسرد أسباب Meta ‏(entity وreason وresolution)؛ وpayment_method تكون missing عندما تشير Meta إلى غياب وسيلة الدفع، وunchecked في غير ذلك؛ وbusiness_verification هي حالة توثيق النشاط لدى Meta. وتكون readiness ‏null في غياب رقم متصل. وما لم تقله Meta يُعاد null، لا كقيمة سليمة افتراضية.
  • ربط رقم أو فصله أو إعادة ضبطه، وكل كتابة تحت ‎/v1/whatsapp (الملف التعريفي، الإعدادات، الأدوات)، تتم من جلسة لوحة التحكم: يتلقى مفتاح API ‏403 FORBIDDEN. ولا يبقى مفتوحاً للمفاتيح إلا POST /v1/whatsapp/lookup-phone وPOST /v1/whatsapp/media/upload.
GEThttps://api.envoisms.ma/v1/whatsapp/waba-connection
curl -X GET "https://api.envoisms.ma/v1/whatsapp/waba-connection" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "readiness": {
    "waba_id": "104857392017465",
    "payment_method": "unchecked",
    "can_send": "AVAILABLE",
    "blockers": [],
    "business_verification": "verified",
    "approved_templates": 4,
    "checked_at": "2026-10-22T08:00:12.000Z"
  },
  "connected": true,
  "mode": "custom_waba",
  "gateway_number": "+212 708-789095",
  "waba_id": "104857392017465",
  "phone_number_id": "109283746501928",
  "phone_number": "+212522000000",
  "name": "Ma Boutique",
  "status": "connected",
  "error": null,
  "quality_rating": "GREEN",
  "messaging_limit_tier": "TIER_1K",
  "connected_at": "2026-09-30 11:02:44",
  "meta_app_id": "1029384756102938",
  "meta_config_id": "2039485761029384",
  "preverified_phone_ids": [],
  "connections": [
    {
      "id": "5f1c9e3a7b2d4f6a8c0e1b3d5f7a9c2e",
      "waba_id": "104857392017465",
      "phone_number_id": "109283746501928",
      "phone_number": "+212522000000",
      "verified_name": "Ma Boutique",
      "status": "connected",
      "is_default": true,
      "webhook_url": null,
      "settings": {},
      "created_at": "2026-09-30 11:02:44",
      "updated_at": "2026-10-20 08:15:02"
    }
  ]
}
DocsWhatsApp/whatsapp/profile
GEThttps://api.envoisms.ma/v1/whatsapp/profile
Bearer

الملف التعريفي لواتساب للأعمال

يعيد الملف التعريفي العام لأحد أرقامك كما تحتفظ به Meta: النبذة، العنوان، الوصف، البريد الإلكتروني، الصورة، المواقع، القطاع.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
phone_number_idstringاختياريالرقم المتصل المطلوب؛ افتراضياً رقمك الافتراضي.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • أي مفتاح API صالح: لا تُشترط صلاحية بعينها.
  • يُحدَّث الملف التعريفي من لوحة التحكم؛ ومع مفتاح API يعيد POST /v1/whatsapp/profile ‏403 FORBIDDEN.
GEThttps://api.envoisms.ma/v1/whatsapp/profile
curl -X GET "https://api.envoisms.ma/v1/whatsapp/profile" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "ok": true,
  "phone_number_id": "109283746501928",
  "profile": {
    "about": "Service client",
    "address": "Casablanca, Maroc",
    "description": "Prêt-à-porter, livraison partout au Maroc.",
    "email": "contact@maboutique.ma",
    "profile_picture_url": "https://pps.whatsapp.net/v/t61/...",
    "websites": ["https://maboutique.ma"],
    "vertical": "APPAREL"
  }
}
DocsVerify/verify/send
POSThttps://api.envoisms.ma/v1/verify/send
Bearer

إرسال رمز تحقق

يولّد رمزاً لمرة واحدة ويرسله ويفتح جلسة تحقق. لا تخزّن أي رمز: تحقق مما يكتبه المستخدم عبر POST /v1/verify/check. يعيد 202.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
tostringمطلوبالمستلم بصيغة E.164.
channelstringاختياري"sms" (الافتراضي) أو "whatsapp". على واتساب يُرسل الرمز كقالب مصادقة — من رقمك الخاص إذا ربطت رقماً له قالب مصادقة معتمد، وإلا من رقم EnvoiSMS — ويتحول إلى SMS إذا رفضت Meta الإرسال.
app_idstringاختياريتطبيق Verify ‏(vra_…) المُنشأ في لوحة التحكم: يحدد الطول والصلاحية وعدد المحاولات والقنوات والتسلسل، ويحل محل code_length وexpiry.
code_lengthintegerاختياريطول الرمز من 4 إلى 8 أرقام. الافتراضي: 6.
expiryintegerاختياريصلاحية الرمز بالثواني من 60 إلى 1800. الافتراضي: 600. وعلى واتساب لا تتجاوز 600.
brandstringاختياري(SMS) الاسم المعروض في الرسالة، 32 حرفاً كحد أقصى. الافتراضي: EnvoiSMS. يُستبدل الاسم العام بـ ENVOISMS، ويُرفض اسم المؤسسة المحمية (403 SENDER_ID_PROTECTED_BRAND).
templatestringاختياري(SMS) نص مخصص يتضمن {{code}} و{{brand}}.
otp_button_textstringاختياري(واتساب) تسمية زر النسخ، 25 حرفاً كحد أقصى.
otp_type | package_name | signature_hashstringاختياري(واتساب) copy_code (الافتراضي) أو one_tap أو zero_tap أو url؛ ومع one_tap وzero_tap اسم حزمة Android وبصمة توقيع التطبيق الذي يستقبل الرمز.
web_otp_domain | app_hashstringاختياري(SMS) نطاق الملء التلقائي WebOTP (يضيف «‎@domain #code» إلى الرسالة)؛ وبصمة تطبيق Android ذات 11 حرفاً لواجهة SMS Retriever.
auto_cascadebooleanاختيارييرسل أيضاً رسالة SMS الاحتياطية عند انتهاء مهلة القناة الأولى دون تسليم. يحل محل إعداد تطبيق Verify.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: verify.
  • على واتساب تحمل الاستجابة "channel": "whatsapp" و"resend_after_seconds": 60 و"fallback_channels": ["sms"، "whatsapp"] و"cost" ‏({eur، mad})، بلا message_id. ومع مفتاح تجريبي لا يُرسل ولا يُخصم شيء وتضيف الاستجابة "sandbox": true و"simulated": true و"sandbox_code"، أي الرمز الذي يُقدَّم إلى ‎/v1/verify/check.
  • حدود لكل رقم: إرسال واحد كل 30 ثانية عبر SMS و60 ثانية عبر واتساب (429 OTP_COOLDOWN مع Retry-After)، و5 في الساعة و10 في اليوم (429 OTP_RATE_LIMIT)؛ و200 إرسال في اليوم لكل حساب.
  • الملء التلقائي: في موقعك أضف autocomplete="one-time-code" وinputmode="numeric" إلى حقل إدخال الرمز.
POSThttps://api.envoisms.ma/v1/verify/send
curl -X POST "https://api.envoisms.ma/v1/verify/send" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+212612345678",
    "brand": "MyApp"
  }'
{
  "session_id": "vrf_7e2a9c4b1d3f5a7c9e0b2d4f",
  "message_id": "msg_2b4d6f8a0c1e3b5d7f9a1c3e",
  "to": "+212612345678",
  "channel": "sms",
  "expires_at": "2026-10-22T09:24:03.000Z",
  "resend_after_seconds": 30,
  "fallback_channels": [],
  "status": "sent"
}
DocsVerify/verify/resend
POSThttps://api.envoisms.ma/v1/verify/resend
Bearer

إعادة إرسال الرمز

يعيد إرسال رمز جلسة لا تزال مفتوحة، عبر SMS أو واتساب، بعد انقضاء فترة الانتظار. لا يتغير الرمز. يعيد 200.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
session_idstringمطلوبالجلسة التي أعادها ‎/v1/verify/send ‏(vrf_…).
channelstringاختياري"sms" (الافتراضي) أو "whatsapp".
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: verify.
  • تبدأ فترة الانتظار من آخر إرسال فعلي: 30 ثانية بعد SMS و60 ثانية بعد واتساب. يعطي GET /v1/verify/:id العد التنازلي (resend_available_in_seconds) ويحمل 429 OTP_COOLDOWN الترويسة Retry-After. والنافذة خاصة بحسابك وبالرقم.
  • الأخطاء: 404 SESSION_NOT_FOUND (غير معروفة أو منتهية أو من نمط مفتاح آخر)، 400 SESSION_EXPIRED، 400 INVALID_STATE (جلسة سبق التحقق منها أو مغلقة)، 400 UNSUPPORTED_CHANNEL، 429 OTP_COOLDOWN. ومع مفتاح تجريبي تضيف الاستجابة "sandbox": true و"simulated": true و"sandbox_code".
POSThttps://api.envoisms.ma/v1/verify/resend
curl -X POST "https://api.envoisms.ma/v1/verify/resend" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "vrf_…",
    "channel": "sms"
  }'
{
  "session_id": "vrf_7e2a9c4b1d3f5a7c9e0b2d4f",
  "message_id": "msg_8c0e2b4d6f1a3c5e7b9d1f3a",
  "to": "+212612345678",
  "channel": "sms",
  "status": "sent",
  "resend_after_seconds": 30,
  "expires_at": "2026-10-22T09:24:03.000Z"
}
DocsVerify/verify/check
POSThttps://api.envoisms.ma/v1/verify/check
Bearer

التحقق من رمز

يقارن الرمز الذي كتبه المستخدم برمز الجلسة. الرمز الصحيح يغلق الجلسة: والتحقق الثاني يعيد 404.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
session_idstringمطلوبالجلسة التي أعادها ‎/v1/verify/send.
codestringمطلوبالرمز الذي كتبه المستخدم.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: status.
  • الأخطاء: 400 INVALID_CODE (تذكر الرسالة المحاولات المتبقية)، 429 MAX_ATTEMPTS (تصبح الجلسة failed)، 404 SESSION_NOT_FOUND — بما في ذلك للجلسة المنتهية أو التي سبق التحقق منها. لا يعيد ‎/v1/verify أبداً EXPIRED_CODE.
POSThttps://api.envoisms.ma/v1/verify/check
curl -X POST "https://api.envoisms.ma/v1/verify/check" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "vrf_…",
    "code": "483921"
  }'
{
  "session_id": "vrf_7e2a9c4b1d3f5a7c9e0b2d4f",
  "verified": true,
  "verified_at": "2026-10-22T09:15:12.408Z"
}
DocsVerify/verify/void
POSThttps://api.envoisms.ma/v1/verify/void
Bearer

إلغاء جلسة

يغلق جلسة معلّقة: لم يعد الرمز المرسل مقبولاً. متاح أيضاً عبر POST /v1/verify/:id/void.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
session_idstringمطلوبالجلسة المراد إلغاؤها (تُحذف إذا كان المعرّف في المسار).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: status.
  • الأخطاء: 404 SESSION_NOT_FOUND و409 INVALID_STATE (جلسة سبق التحقق منها أو فشلت أو انتهت). وإذا كان لتطبيق Verify ‏callback_url فيُبلَّغ (expired).
POSThttps://api.envoisms.ma/v1/verify/void
curl -X POST "https://api.envoisms.ma/v1/verify/void" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "vrf_…"
  }'
{
  "session_id": "vrf_7e2a9c4b1d3f5a7c9e0b2d4f",
  "status": "expired",
  "voided": true
}
DocsVerify/verify/:id
GEThttps://api.envoisms.ma/v1/verify/:id
Bearer

عرض جلسة

يعيد حالة جلسة تحقق: الحالة والمحاولات والعد التنازلي قبل إعادة الإرسال ونتيجة تسليم كل إرسال.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: status.
  • قيمة status هي pending أو verified أو failed أو expired. و404 NOT_FOUND إذا لم تكن الجلسة تابعة للحساب.
GEThttps://api.envoisms.ma/v1/verify/:id
curl -X GET "https://api.envoisms.ma/v1/verify/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "vrf_7e2a9c4b1d3f5a7c9e0b2d4f",
  "session_id": "vrf_7e2a9c4b1d3f5a7c9e0b2d4f",
  "to": "+212612345678",
  "channel": "sms",
  "status": "pending",
  "attempts_used": 1,
  "attempts_remaining": 2,
  "max_attempts": 3,
  "resend_available_in_seconds": 0,
  "can_resend_now": true,
  "expires_at": "2026-10-22T09:24:03.000Z",
  "verified_at": null,
  "created_at": "2026-10-22 09:14:03",
  "app_id": null,
  "app_name": null,
  "attempted_channels": [],
  "deliveries": [
    {
      "channel": "sms",
      "kind": "send",
      "status": "delivered",
      "simulated": false,
      "submitted_at": "2026-10-22 09:14:03",
      "delivered_at": "2026-10-22 09:14:07",
      "read_at": null,
      "failed_at": null,
      "error_code": null,
      "error_message": null
    }
  ],
  "callback_delivered": null,
  "cascade_triggered": false
}
DocsVerify/lookup/:number
GEThttps://api.envoisms.ma/v1/lookup/:number
Bearer

معرفة مشغّل رقم

يتحقق من رقم ويعيد بلده، ولرقم الجوال المغربي المشغّل الذي يخدمه مع احتساب نقل الأرقام. يُفوتَر كل استعلام ناجح؛ ولا يُفوتَر الرقم غير الصالح (400).

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
numberstringاختياريبديل عن معامل المسار: GET /v1/lookup?number=%2B212612345678.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • الأخطاء: 400 MISSING_FIELD و400 INVALID_PHONE و402 INSUFFICIENT_BALANCE. مع مفتاح تجريبي تكون الإجابة حقيقية دون أي خصم، وتحمل "sandbox": true. قيمة type هي mobile أو unknown؛ وoperator تكون null إذا كان مجهولاً.
GEThttps://api.envoisms.ma/v1/lookup/:number
curl -X GET "https://api.envoisms.ma/v1/lookup/{number}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "lkp_5d7f9b1c3e5a7c9e1b3d5f7a",
  "number": "+212612345678",
  "valid": true,
  "country_iso": "MA",
  "type": "mobile",
  "operator": "Maroc Telecom",
  "ported": false,
  "cost": { "eur": 0.005, "mad": 0.055 }
}
DocsVerify/hlr/:number
GEThttps://api.envoisms.ma/v1/hlr/:number
Bearer

استعلام الشبكة (HLR)

يستعلم سجل المشغّل (HLR): هل الرقم قابل للوصول الآن، وأي شبكة تخدمه اليوم (مع احتساب نقل الأرقام)، وهل هو في التجوال، وهل هو جوال أم ثابت. يُفوتَر كل جواب من الشبكة أياً كان؛ ولا يُفوتَر الرقم غير الصالح (400) ولا الاستعلام غير المكتمل (502/503).

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
numberstringاختياريبديل عن معامل المسار: GET /v1/hlr?number=%2B212612345678.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • قيمة status هي active (قابل للوصول) أو absent (معروف لكنه مطفأ أو خارج التغطية) أو inactive (خارج الخدمة) أو invalid أو unknown. يستغرق الجواب جولة شبكة واحدة (1 إلى 5 ثوانٍ). تشير source إلى مصدر الجواب: network = سجل المشغّل مستعلَماً مباشرة (تعكس status إمكانية الوصول)؛ portability = قاعدة نقل الأرقام لدى المشغّلين (الأرقام المغربية): المشغّل وحالة النقل والخط في الخدمة (active)، دون القول إن الهاتف مشغّل في هذه اللحظة. الأخطاء: 400 MISSING_FIELD و400 INVALID_PHONE و402 INSUFFICIENT_BALANCE و502 BAD_GATEWAY و503 HLR_UNAVAILABLE. مع مفتاح تجريبي يُحاكى الجواب مما تعرفه المنصة أصلاً، دون أي استعلام أو خصم، ويحمل "sandbox": true.
GEThttps://api.envoisms.ma/v1/hlr/:number
curl -X GET "https://api.envoisms.ma/v1/hlr/{number}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "hlr_5d7f9b1c3e5a7c9e1b3d5f7a",
  "number": "+212612345678",
  "valid": true,
  "status": "active",
  "type": "mobile",
  "country_iso": "MA",
  "operator": "Maroc Telecom",
  "mcc": "604",
  "mnc": "01",
  "ported": false,
  "ported_operator": null,
  "ported_mnc": null,
  "roaming": false,
  "roaming_country_iso": null,
  "roaming_operator": null,
  "roaming_mnc": null,
  "source": "portability",
  "cost": { "eur": 0.018, "mad": 0.20 }
}
DocsVerify/verify/lookup
POSThttps://api.envoisms.ma/v1/verify/lookup
Bearer

التحقق من صيغة رقم

يتحقق من صيغة رقم ويعيد صيغتيه المحلية والدولية وبلده وموقعه والمشغّل المخصِّص ونوع الخط. غير مُفوتَر.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
numberstringمطلوبالرقم بصيغة محلية أو دولية.
country_codestringاختياريرمز الدولة ISO من حرفين (MA وFR…)، يُوصى به للرقم بصيغة محلية.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: status.
  • carrier هو المشغّل الذي خُصّصت له شريحة الأرقام، وليس بالضرورة من يخدم رقماً منقولاً: للمشغّل الفعلي استعمل GET /v1/lookup/:number. الأخطاء: 400 MISSING_FIELD؛ و503 LOOKUP_UNAVAILABLE عند تعذّر الخدمة مؤقتاً.
POSThttps://api.envoisms.ma/v1/verify/lookup
curl -X POST "https://api.envoisms.ma/v1/verify/lookup" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "number": "+212612345678"
  }'
{
  "valid": true,
  "number": "212612345678",
  "local_format": "0612345678",
  "international_format": "+212612345678",
  "country_prefix": "+212",
  "country_code": "MA",
  "country_name": "Morocco",
  "location": null,
  "carrier": "Maroc Telecom",
  "line_type": "mobile"
}
DocsConversations/conversations
GEThttps://api.envoisms.ma/v1/conversations
Bearer

قائمة المحادثات

يعيد سلاسل محادثات واتساب وSMS في الحساب، مع حالة نافذة الـ 24 ساعة لكل منها وعدادات إجمالية.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 50 افتراضياً و100 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
filterstringاختياريall (الافتراضي) أو unread أو active_window أو needs_human.
channelstringاختياريall (الافتراضي) أو whatsapp أو sms.
phone_number_id | assigned_to | searchstringاختياريرقم واتساب المتصل؛ المستشار المكلَّف؛ بحث في الرقم والاسم وآخر رسالة.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
GEThttps://api.envoisms.ma/v1/conversations
curl -X GET "https://api.envoisms.ma/v1/conversations?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "th_212612345678",
      "phone": "212612345678",
      "contact_name": "Yassine Alami",
      "channel": "whatsapp",
      "lead_status": "new",
      "unread_count": 1,
      "bot_muted": false,
      "handling_agent": null,
      "notes": null,
      "tags": [],
      "last_inbound_at": "2026-10-22 08:42:00",
      "last_outbound_at": "2026-10-21 17:10:00",
      "last_message_preview": "Bonjour, la veste existe en taille L ?",
      "last_message_role": "customer",
      "last_message_at": "2026-10-22 08:42:00",
      "is_window_active": true,
      "window_expires_at": "2026-10-23T08:42:00.000Z",
      "window_seconds_remaining": 84960,
      "waba_name": "Ma Boutique",
      "waba_phone": "+212522000000",
      "phone_number_id": "109283746501928"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0,
  "stats": {
    "total_threads": 1,
    "unread_threads": 1,
    "active_window_threads": 1,
    "human_takeover_threads": 0
  }
}
DocsConversations/conversations/:phone
GEThttps://api.envoisms.ma/v1/conversations/:phone
Bearer

عرض محادثة

يعيد سلسلة واحدة ورسائلها (500 كحد أقصى) من الأقدم إلى الأحدث، مع حالة نافذة الـ 24 ساعة.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • يقبل ‎:phone الرقم مع + أو بدونه. قيمة role هي customer للرسالة المستلمة، وagent أو bot للرسالة المرسلة.
GEThttps://api.envoisms.ma/v1/conversations/:phone
curl -X GET "https://api.envoisms.ma/v1/conversations/{phone}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "thread": {
    "id": "th_212612345678",
    "phone": "212612345678",
    "contact_name": "Yassine Alami",
    "channel": "whatsapp",
    "lead_status": "new",
    "unread_count": 0,
    "bot_muted": true,
    "handling_agent": "Salma",
    "notes": null,
    "tags": [],
    "last_inbound_at": "2026-10-22 08:42:00",
    "last_outbound_at": "2026-10-22 08:45:10",
    "is_window_active": true,
    "window_expires_at": "2026-10-23T08:42:00.000Z",
    "window_seconds_remaining": 84960,
    "window": {
      "is_window_active": true,
      "window_expires_at": "2026-10-23T08:42:00.000Z",
      "window_seconds_remaining": 84960
    },
    "waba_name": "Ma Boutique",
    "waba_phone": "+212522000000",
    "phone_number_id": "109283746501928"
  },
  "messages": [
    {
      "id": "wamsg_1c3e5a7c9e1b3d5f7a9c1e3b",
      "phone": "212612345678",
      "role": "customer",
      "message": "Bonjour, la veste existe en taille L ?",
      "wamid": "wamid.HBgLMjEyNjEyMzQ1Njc4FQIAEhgg",
      "status": "read",
      "media_type": "text",
      "media_url": null,
      "metadata": {},
      "read_at": "2026-10-22 08:43:00",
      "created_at": "2026-10-22 08:42:00"
    }
  ]
}
DocsConversations/conversations/:phone/messages
POSThttps://api.envoisms.ma/v1/conversations/:phone/messages
Bearer

الرد في محادثة

يرسل رد مستشار (نص أو وسائط أو قالب) ويوقف المساعد الآلي مؤقتاً في هذه السلسلة. يمر الإرسال بنفس مسار POST /v1/messages: تُطبَّق التسعيرة وقائمة إلغاء الاشتراك والخصم. يعيد 201.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
messagestringاختيارينص الرد أو شرح الوسائط. إلزامي في غياب قالب أو وسائط (400 MISSING_MESSAGE).
channelstringاختياري"whatsapp" (الافتراضي) أو "sms".
template_id | template_name | template_language | variablesmixedاختياريقالب واتساب معتمد يُرسل بدل النص الحر (بالمعرّف أو بالاسم واللغة)، مع قيمه (مصفوفة أو كائن).
media_url | media_type | filenamestringاختياريالوسائط المرفقة: رابط https (أو data URI)، النوع image أو document، واسم ملف المستند.
phone_number_idstringاختياريرقم واتساب المتصل الذي يرد.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: send.
  • تتطلب رسالة واتساب الحرة أن يكون جهة الاتصال قد راسلك خلال آخر 24 ساعة (وإلا 400 OUT_OF_24H_WINDOW)؛ ويمكن إرسال القالب المعتمد في أي وقت. أخطاء أخرى: 403 WHATSAPP_NOT_CONNECTED و404 TEMPLATE_NOT_FOUND و400 TEMPLATE_NOT_APPROVED.
POSThttps://api.envoisms.ma/v1/conversations/:phone/messages
curl -X POST "https://api.envoisms.ma/v1/conversations/{phone}/messages" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Thanks, we will call you back today."
  }'
{
  "ok": true,
  "message": {
    "id": "msg_9e1b3d5f7a9c1e3b5d7f9a1c",
    "phone": "212612345678",
    "role": "agent",
    "message": "Oui, la taille L est disponible.",
    "wamid": "wamid.HBgLMjEyNjEyMzQ1Njc4FQIAERgS",
    "status": "sent",
    "channel": "whatsapp",
    "media_type": "text",
    "metadata": { "agent": "Salma" },
    "created_at": "2026-10-22T08:45:10.221Z"
  }
}
DocsLeads/qualified-leads
GEThttps://api.envoisms.ma/v1/qualified-leads
Bearer

قائمة العملاء المحتملين المؤهلين

يعيد العملاء المحتملين الذين سجّلهم روبوت واتساب الخاص بك، من الأحدث إلى الأقدم، مع درجتهم (0 إلى 100) وحالتهم. format=csv ينزّل القائمة نفسها.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 100 افتراضياً و500 كحد أقصى.
statusstringاختياريnew أو contacted أو qualified أو Fournisseur أو won أو lost.
presetstringاختياريقطاع الروبوت (مثلاً medical_equipment)؛ وsupplier يجمع طلبات الموردين.
formatstringاختياريjson (الافتراضي) أو csv.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • أي مفتاح API صالح: لا تُشترط صلاحية بعينها.
  • لا يوجد تقسيم عبر offset: يحدّ limit القائمة. تُحسب metrics على العملاء المُعادين؛ ويعدّ hot من بلغت درجتهم 80 فأكثر.
GEThttps://api.envoisms.ma/v1/qualified-leads
curl -X GET "https://api.envoisms.ma/v1/qualified-leads?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "ok": true,
  "leads": [
    {
      "id": "lead_3a5c7e9b1d3f5a7c9e1b3d5f",
      "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
      "phone_number_id": "109283746501928",
      "contact_phone": "+212612345678",
      "contact_name": "Cabinet Benjelloun",
      "preset": "medical_equipment",
      "category": "Échographe",
      "bant_score": 85,
      "urgency": "immediate",
      "budget": "200 000 - 300 000 MAD",
      "authority": "decision_maker",
      "notes": null,
      "source_type": "direct_inbound",
      "status": "new",
      "created_at": "2026-10-21 09:15:00",
      "updated_at": "2026-10-21 09:15:00"
    }
  ],
  "metrics": { "total": 1, "hot": 1, "average_score": 85 }
}
DocsLeads/qualified-leads/:id
PATCHhttps://api.envoisms.ma/v1/qualified-leads/:id
Bearer

تحديث عميل محتمل

يغيّر حالة العميل المحتمل أو ملاحظاته أو اسمه. يعيد العميل بعد التحديث.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
statusstringاختياريnew أو contacted أو qualified أو Fournisseur أو won أو lost (وإلا 400 INVALID_STATUS).
notesstringاختياريملاحظات متابعة داخلية.
contact_namestringاختيارياسم جهة الاتصال أو المؤسسة.
value_minor | currencyinteger | stringاختياريقيمة الصفقة بأصغر وحدة نقدية وعملتها، تُرسلان إلى Meta عند الانتقال إلى won.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • أي مفتاح API صالح: لا تُشترط صلاحية بعينها.
  • يُبلَّغ Meta بالانتقال إلى qualified أو won ‏(QualifiedLead وPurchase) إذا جاء العميل من إعلان يقود إلى واتساب؛ وذلك عند تغيّر فعلي في الحالة فقط. و404 LEAD_NOT_FOUND إذا لم يكن العميل تابعاً للحساب.
PATCHhttps://api.envoisms.ma/v1/qualified-leads/:id
curl -X PATCH "https://api.envoisms.ma/v1/qualified-leads/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "contacted",
    "notes": "Called back on 22/10"
  }'
{
  "ok": true,
  "lead": {
    "id": "lead_3a5c7e9b1d3f5a7c9e1b3d5f",
    "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
    "phone_number_id": "109283746501928",
    "contact_phone": "+212612345678",
    "contact_name": "Cabinet Benjelloun",
    "preset": "medical_equipment",
    "category": "Échographe",
    "bant_score": 85,
    "urgency": "immediate",
    "budget": "200 000 - 300 000 MAD",
    "authority": "decision_maker",
    "notes": "Rendez-vous fixé jeudi.",
    "source_type": "direct_inbound",
    "status": "contacted",
    "created_at": "2026-10-21 09:15:00",
    "updated_at": "2026-10-22 10:02:31",
    "user_id": null
  }
}
DocsContacts/contacts
GEThttps://api.envoisms.ma/v1/contacts
Bearer

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

يعيد جهات الاتصال في الحساب، مع البحث والتصفية حسب القائمة.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 100 افتراضياً و500 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
qstringاختياريبحث في الاسم والهاتف والبريد الإلكتروني.
list_idstringاختياريأعضاء هذه القائمة فقط (lst_…).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
GEThttps://api.envoisms.ma/v1/contacts
curl -X GET "https://api.envoisms.ma/v1/contacts?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "ctc_2d4f6a8c0e1b3d5f7a9c1e3b",
      "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
      "phone": "+212612345678",
      "name": "Karim Bennani",
      "email": "karim@example.ma",
      "custom1": "VIP",
      "custom2": null,
      "custom3": null,
      "opted_out": 0,
      "opted_out_at": null,
      "created_at": "2026-10-10 14:20:00"
    }
  ],
  "limit": 100,
  "offset": 0,
  "total": 1
}
DocsContacts/contacts
POSThttps://api.envoisms.ma/v1/contacts
Bearer

إنشاء جهة اتصال أو تحديثها

ينشئ جهة اتصال أو يحدّث الجهة التي تملك هذا الرقم (يُستبدل الاسم والبريد والحقول المخصصة). يعيد 201 مع جهة الاتصال.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
phonestringمطلوبالرقم بصيغة E.164 (وإلا 400 INVALID_PHONE).
name | emailstringاختيارياسم جهة الاتصال وبريدها الإلكتروني.
list_idstringاختيارييضيف جهة الاتصال أيضاً إلى هذه القائمة (404 LIST_NOT_FOUND إن لم تكن لك).
custom_fieldsobjectاختياري{"custom1"، "custom2"، "custom3"}: ثلاثة حقول حرة تُستعمل في الحملات.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
POSThttps://api.envoisms.ma/v1/contacts
curl -X POST "https://api.envoisms.ma/v1/contacts" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+212612345678",
    "name": "Karim Bennani",
    "email": "karim@example.ma"
  }'
{
  "id": "ctc_2d4f6a8c0e1b3d5f7a9c1e3b",
  "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
  "phone": "+212612345678",
  "name": "Karim Bennani",
  "email": "karim@example.ma",
  "custom1": "VIP",
  "custom2": null,
  "custom3": null,
  "opted_out": 0,
  "opted_out_at": null,
  "created_at": "2026-10-10 14:20:00"
}
DocsContacts/contacts/import
POSThttps://api.envoisms.ma/v1/contacts/import
Bearer

استيراد جهات الاتصال

يضع استيراد جهات اتصال في قائمة الانتظار، بصيغة JSON أو ملف CSV، ويعيد 202 فوراً؛ ثم يجري الاستيراد على دفعات من 100.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
contactsarrayمطلوب(application/json) كائنات {"phone"، "name"?، "email"?، "custom1"?، "custom2"?، "custom3"?}. ولملف CSV أرسل text/csv أو multipart/form-data (الحقل file) ومرّر القائمة عبر ‎?list_id=.
list_idstringاختياريالقائمة التي تستقبل جهات الاتصال المستوردة.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
  • تُعطى الاستجابة عند الوضع في قائمة الانتظار: يعدّ total الأسطر المستلمة، ويكرره imported كما هو. تُستبعد الأرقام غير الصالحة أثناء الاستيراد؛ تحقق من النتيجة عبر GET /v1/contacts. أنواع المحتوى الأخرى: 415 UNSUPPORTED_MEDIA_TYPE.
POSThttps://api.envoisms.ma/v1/contacts/import
curl -X POST "https://api.envoisms.ma/v1/contacts/import" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "phone": "+212611111111",
        "name": "Karim"
      },
      {
        "phone": "+212622222222",
        "name": "Salma"
      }
    ]
  }'
{
  "jobId": "job_4b6d8f0a2c4e6b8d0f2a4c6e",
  "total": 150,
  "imported": 150,
  "skipped": 0,
  "status": "queued"
}
DocsContacts/contacts/:id
DELETEhttps://api.envoisms.ma/v1/contacts/:id
Bearer

حذف جهة اتصال

يحذف جهة اتصال نهائياً. 404 NOT_FOUND إن لم تكن موجودة.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
DELETEhttps://api.envoisms.ma/v1/contacts/:id
curl -X DELETE "https://api.envoisms.ma/v1/contacts/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "deleted": true,
  "id": "ctc_2d4f6a8c0e1b3d5f7a9c1e3b"
}
DocsContacts/contacts/lists
GEThttps://api.envoisms.ma/v1/contacts/lists
Bearer

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

يعيد قوائم جهات الاتصال في الحساب مع عدد أعضائها.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
GEThttps://api.envoisms.ma/v1/contacts/lists
curl -X GET "https://api.envoisms.ma/v1/contacts/lists" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "lst_f84b2d6a8c0e1f3b5d7a9c2e",
      "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
      "name": "Clients fidèles",
      "description": "Clients ayant commandé au moins deux fois",
      "count": 1420,
      "created_at": "2026-09-15 09:00:00"
    }
  ]
}
DocsContacts/contacts/lists
POSThttps://api.envoisms.ma/v1/contacts/lists
Bearer

إنشاء قائمة

ينشئ قائمة جهات اتصال فارغة تُملأ عبر POST /v1/contacts أو ‎/v1/contacts/import. يعيد 201.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
namestringمطلوباسم القائمة.
descriptionstringاختياريوصف حر.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
POSThttps://api.envoisms.ma/v1/contacts/lists
curl -X POST "https://api.envoisms.ma/v1/contacts/lists" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Newsletter",
    "description": "Customers who subscribed at checkout"
  }'
{
  "id": "lst_f84b2d6a8c0e1f3b5d7a9c2e",
  "name": "Clients fidèles",
  "description": "Clients ayant commandé au moins deux fois",
  "count": 0
}
DocsContacts/contacts/lists/:id
POSThttps://api.envoisms.ma/v1/contacts/lists/:id
Bearer

إعادة تسمية قائمة

يستبدل اسم القائمة ووصفها. 404 NOT_FOUND إن لم تكن موجودة.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
namestringمطلوبالاسم الجديد.
descriptionstringاختياريالوصف الجديد؛ يُمحى إذا لم يُرسل.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
POSThttps://api.envoisms.ma/v1/contacts/lists/:id
curl -X POST "https://api.envoisms.ma/v1/contacts/lists/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "lst_f84b2d6a8c0e1f3b5d7a9c2e",
  "name": "Clients fidèles 2026",
  "description": null
}
DocsContacts/contacts/lists/:id
DELETEhttps://api.envoisms.ma/v1/contacts/lists/:id
Bearer

حذف قائمة

يحذف قائمة وعضوياتها؛ وتبقى جهات الاتصال نفسها. يُرفض (400 LIST_IN_USE) ما دامت حملة مجدولة أو جارية أو متوقفة مؤقتاً تستعملها.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
DELETEhttps://api.envoisms.ma/v1/contacts/lists/:id
curl -X DELETE "https://api.envoisms.ma/v1/contacts/lists/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "deleted": true,
  "id": "lst_f84b2d6a8c0e1f3b5d7a9c2e"
}
DocsContacts/optouts
GEThttps://api.envoisms.ma/v1/optouts
Bearer

قائمة إلغاءات الاشتراك

يعيد الأرقام التي ألغت اشتراكها في إرسالياتك. لا تُرسل إليها أي رسالة (403 OPTED_OUT).

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 100 افتراضياً و500 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: optouts.
GEThttps://api.envoisms.ma/v1/optouts
curl -X GET "https://api.envoisms.ma/v1/optouts?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    { "phone": "+212611111111", "opted_out_at": "2026-10-01 12:00:00" }
  ],
  "limit": 100,
  "offset": 0,
  "total": 1
}
DocsContacts/optouts
POSThttps://api.envoisms.ma/v1/optouts
Bearer

إضافة إلغاء اشتراك

يضيف رقماً إلى قائمة إلغاء الاشتراك الخاصة بك. يعيد 201.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
phonestringمطلوبالرقم بصيغة E.164.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: optouts.
POSThttps://api.envoisms.ma/v1/optouts
curl -X POST "https://api.envoisms.ma/v1/optouts" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+212612345678"
  }'
{
  "phone": "+212611111111",
  "opted_out": true
}
DocsContacts/optouts/:phone
DELETEhttps://api.envoisms.ma/v1/optouts/:phone
Bearer

إزالة إلغاء اشتراك

يزيل رقماً من قائمة إلغاء الاشتراك. لا تفعل ذلك إلا بموافقة جديدة من الشخص، تُسجَّل عبر POST /v1/consents.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: optouts.
DELETEhttps://api.envoisms.ma/v1/optouts/:phone
curl -X DELETE "https://api.envoisms.ma/v1/optouts/{phone}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "phone": "+212611111111",
  "opted_out": false
}
DocsContacts/consents
GEThttps://api.envoisms.ma/v1/consents
Bearer

قائمة أحداث الموافقة

سجل موافقات بالإضافة فقط (القانون 09-08): كل موافقة وكل سحب حدث مؤرَّخ بمصدره ودليله. وتسجّل المنصة بنفسها الكلمتين STOP/START المستلمتين وأول محادثة يفتحها الزبون.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 100 افتراضياً و500 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
phonestringاختياريرقم E.164.
purposestringاختياريmarketing أو transactional أو otp أو service.
statusstringاختياريgranted أو withdrawn.
from | tostringاختياريحدود ISO 8601 على recorded_at.
formatstringاختياريcsv: ينزّل المجموعة المصفاة كاملة.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
GEThttps://api.envoisms.ma/v1/consents
curl -X GET "https://api.envoisms.ma/v1/consents?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "cns_9f2a4c6e8b0d1f3a5c7e9b2d",
      "phone": "+212612345678",
      "channel": "whatsapp",
      "purpose": "marketing",
      "status": "withdrawn",
      "source": "whatsapp_keyword",
      "evidence": { "keyword": "stop", "lang": "fr" },
      "recorded_at": "2026-10-05T09:00:00.000Z",
      "created_at": "2026-10-05T09:00:00.000Z"
    }
  ],
  "limit": 100,
  "offset": 0,
  "total": 1
}
DocsContacts/consents
POSThttps://api.envoisms.ma/v1/consents
Bearer

تسجيل حدث موافقة

يسجّل أن شخصاً منح موافقته أو سحبها، مع الدليل الذي بحوزتك. ويضع سحب الموافقة التسويقية الرقم فوراً في قائمة إلغاء الاشتراك. يعيد 201.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
phonestringمطلوبالرقم بصيغة E.164.
purposestringمطلوبmarketing أو transactional أو otp أو service.
statusstringاختياريgranted (الافتراضي) أو withdrawn.
channelstringاختياريwhatsapp أو sms أو any (الافتراضي).
sourcestringاختياريapi (الافتراضي) أو form أو import أو dashboard. مصادر الكلمات المفتاحية محجوزة للمنصة.
evidenceobjectاختياريكائن JSON حر أقل من 4096 بايت: النص المعروض، الرابط، عنوان IP، المرجع.
recorded_atstringاختياريتاريخ ISO 8601 للفعل (افتراضياً الآن)؛ يمكن تأريخه بأثر رجعي عند الاستيراد، لكن ليس في المستقبل.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
  • الأخطاء: 400 INVALID_PHONE وINVALID_PURPOSE وINVALID_STATUS وINVALID_CHANNEL وINVALID_SOURCE وINVALID_EVIDENCE وINVALID_DATE.
POSThttps://api.envoisms.ma/v1/consents
curl -X POST "https://api.envoisms.ma/v1/consents" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+212612345678",
    "purpose": "marketing",
    "status": "granted",
    "channel": "whatsapp",
    "source": "form",
    "evidence": {
      "form": "checkout",
      "ip": "196.200.1.4"
    }
  }'
{
  "id": "cns_1b3d5f7a9c2e4b6d8f0a2c4e",
  "phone": "+212612345678",
  "channel": "any",
  "purpose": "marketing",
  "status": "granted",
  "source": "form",
  "evidence": { "text": "J’accepte de recevoir les offres par WhatsApp", "url": "https://example.ma/inscription" },
  "recorded_at": "2026-10-01T10:00:00.000Z",
  "created_at": "2026-10-01T10:00:00.000Z"
}
DocsContacts/consents/:phone
GEThttps://api.envoisms.ma/v1/consents/:phone
Bearer

حالة الموافقة وسجلها لرقم

يعيد الحالة الحالية لكل غرض (من أحدث حدث؛ unknown بلا سجل، ولا تُفترض الموافقة أبداً)، ووجود الرقم في قائمة إلغاء الاشتراك، والسجل (500 حدث كحد أقصى).

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: contacts.
GEThttps://api.envoisms.ma/v1/consents/:phone
curl -X GET "https://api.envoisms.ma/v1/consents/{phone}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "phone": "+212612345678",
  "opted_out": true,
  "opted_out_at": "2026-10-05T09:00:00.000Z",
  "state": {
    "marketing": { "status": "withdrawn", "channel": "whatsapp", "source": "whatsapp_keyword", "recorded_at": "2026-10-05T09:00:00.000Z", "record_id": "cns_9f2a4c6e8b0d1f3a5c7e9b2d" },
    "transactional": { "status": "unknown" },
    "otp": { "status": "unknown" },
    "service": { "status": "granted", "channel": "whatsapp", "source": "whatsapp_inbound", "recorded_at": "2026-07-01T09:00:00.000Z", "record_id": "cns_0a2c4e6b8d1f3a5c7e9b0d2f" }
  },
  "history": []
}
DocsCampaigns/campaigns
GEThttps://api.envoisms.ma/v1/campaigns
Bearer

قائمة الحملات

يعيد حملات الحساب من الأحدث إلى الأقدم، مع عداداتها.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 50 افتراضياً و200 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
  • الحالات: draft وscheduled وrunning وpaused وcompleted وfailed وcancelled.
GEThttps://api.envoisms.ma/v1/campaigns
curl -X GET "https://api.envoisms.ma/v1/campaigns?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f",
      "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
      "name": "Soldes d’automne",
      "channel": "sms",
      "list_id": "lst_f84b2d6a8c0e1f3b5d7a9c2e",
      "template_id": null,
      "body": "Bonjour {{name}}, -30% sur la collection avec le code AUT30.",
      "sender_id": "MABOUTIQUE",
      "status": "completed",
      "scheduled_at": null,
      "started_at": "2026-10-15 10:00:00",
      "completed_at": "2026-10-15 10:06:12",
      "total_count": 1420,
      "sent_count": 1412,
      "delivered_count": 1380,
      "failed_count": 8,
      "cost_eur": 102.24,
      "cost_mad": 1124.64,
      "created_at": "2026-10-14 16:30:00",
      "buttons": null,
      "template_variables": null
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
DocsCampaigns/campaigns
POSThttps://api.envoisms.ma/v1/campaigns
Bearer

إنشاء حملة

ينشئ حملة كمسودة، أو مجدولة إذا أُعطي scheduled_at. لا يُرسل شيء قبل POST /v1/campaigns/:id/send. يعيد 201.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
namestringمطلوباسم الحملة.
bodystringاختياري(SMS) نص الرسالة. يلزم body أو template_id.
template_idstringاختياريقالب من الحساب. إلزامي على واتساب، حيث يجب أن تكون Meta قد اعتمدته (400 TEMPLATE_NOT_APPROVED).
channelstringاختياري"sms" (الافتراضي) أو "whatsapp" (يتطلب رقم واتساب للأعمال متصلاً، وإلا 403 WHATSAPP_NOT_CONNECTED).
list_idstringاختياريقائمة المستلمين؛ لازمة لإطلاق الحملة (404 LIST_NOT_FOUND إن لم تكن لك).
sender_idstringاختياريSMS: مُعرّف المرسل (نفس قواعد POST /v1/messages؛ الافتراضي EnvoiSMS). واتساب: الرقم المتصل الذي يرسل (افتراضياً رقمك الافتراضي؛ و400 INVALID_WABA_SENDER إن لم يكن لك).
scheduled_atstringاختياريتاريخ ISO 8601؛ يجعل حالة الحملة scheduled.
template_variablesobjectاختياري(واتساب) قيمة كل معامل في القالب حسب المفتاح. المفتاح "1" و"2"… أو اسم المتغير: حقل من جهة الاتصال (name وphone وemail وcustom1 وcustom2 وcustom3) أو نص ثابت مسبوق بـ "static:". و"_header_media_url": رابط https لوسائط الترويسة (إلزامي لترويسة صورة أو فيديو أو مستند). و"_button_<i>": الجزء المتغير من زر الرابط ذي الفهرس i (ابتداءً من 0). وبلا قيمة يقرأ {{1}} الحقل name و{{2}} الحقل custom1 و{{3}} الحقل custom2.
consent_attestedbooleanاختياري(واتساب، قالب marketing) true: تشهد بأن كل جهة اتصال في القائمة وافقت على تلقي رسائل واتساب منك. إلزامي لقالب marketing (وإلا 400 CONSENT_ATTESTATION_REQUIRED)؛ ويُسجَّل تاريخ الإقرار.
buttonsarrayاختياري(واتساب) أزرار بنفس صيغة POST /v1/messages. مرفوضة في SMS ‏(400 BUTTONS_NOT_SUPPORTED).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
  • واتساب: يُتحقَّق عند الإنشاء من كل ما يتطلبه القالب لكل جهة اتصال؛ ويُسمّى الناقص في 400 MISSING_TEMPLATE_PARAMS. أخطاء أخرى: 400 MISSING_TEMPLATE و404 TEMPLATE_NOT_FOUND.
POSThttps://api.envoisms.ma/v1/campaigns
curl -X POST "https://api.envoisms.ma/v1/campaigns" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Summer sale",
    "channel": "sms",
    "body": "Summer sale: -20% until Sunday. Reply STOP to unsubscribe.",
    "list_id": "lst_…"
  }'
{
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f",
  "status": "draft"
}
DocsCampaigns/campaigns/:id
GEThttps://api.envoisms.ma/v1/campaigns/:id
Bearer

عرض حملة

يعيد حملة واحدة وحالتها وعدادات إرسالها. وإلا 404 NOT_FOUND.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
GEThttps://api.envoisms.ma/v1/campaigns/:id
curl -X GET "https://api.envoisms.ma/v1/campaigns/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f",
  "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
  "name": "Nouvelle collection",
  "channel": "whatsapp",
  "list_id": "lst_f84b2d6a8c0e1f3b5d7a9c2e",
  "template_id": "tpl_8e2a4c6b1d3f5a7c9e0b2d4f",
  "body": null,
  "sender_id": "+212522000000",
  "status": "running",
  "scheduled_at": null,
  "started_at": "2026-10-22 10:00:00",
  "completed_at": null,
  "total_count": 1420,
  "sent_count": 840,
  "delivered_count": 790,
  "failed_count": 3,
  "cost_eur": 0,
  "cost_mad": 0,
  "created_at": "2026-10-21 18:12:40",
  "buttons": null,
  "template_variables": "{\"1\":\"name\"}"
}
DocsCampaigns/campaigns/:id
PATCHhttps://api.envoisms.ma/v1/campaigns/:id
Bearer

تعديل حملة

يعدّل حملة مسودة أو مجدولة؛ لا يتغير إلا ما ترسله. يعيد الحملة بعد التحديث.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
name | body | sender_id | scheduled_atstringاختيارياسم أو نص أو مرسل أو تاريخ جدولة جديد (ISO 8601). القيمة الفارغة تترك الحقل دون تغيير.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
  • 409 CAMPAIGN_NOT_EDITABLE إذا لم تكن الحملة draft ولا scheduled؛ و404 NOT_FOUND إن لم تكن موجودة.
PATCHhttps://api.envoisms.ma/v1/campaigns/:id
curl -X PATCH "https://api.envoisms.ma/v1/campaigns/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scheduled_at": "2026-11-01T09:00:00Z"
  }'
{
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f",
  "account_id": "acct_7b2e4c6a8d0f1e3b5c7a9d2f",
  "name": "Soldes d’automne — relance",
  "channel": "sms",
  "list_id": "lst_f84b2d6a8c0e1f3b5d7a9c2e",
  "template_id": null,
  "body": "Dernier jour : -30% avec le code AUT30.",
  "sender_id": "MABOUTIQUE",
  "status": "scheduled",
  "scheduled_at": "2026-10-25T09:00:00Z",
  "started_at": null,
  "completed_at": null,
  "total_count": 0,
  "sent_count": 0,
  "delivered_count": 0,
  "failed_count": 0,
  "cost_eur": 0,
  "cost_mad": 0,
  "created_at": "2026-10-22 11:05:00",
  "buttons": null,
  "template_variables": null
}
DocsCampaigns/campaigns/:id
DELETEhttps://api.envoisms.ma/v1/campaigns/:id
Bearer

إلغاء حملة

يجعل حالة الحملة cancelled؛ وتبقى قابلة للعرض. يجب إيقاف الحملة الجارية مؤقتاً أولاً (409 CAMPAIGN_RUNNING).

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
DELETEhttps://api.envoisms.ma/v1/campaigns/:id
curl -X DELETE "https://api.envoisms.ma/v1/campaigns/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "deleted": true,
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f"
}
DocsCampaigns/campaigns/:id/send
POSThttps://api.envoisms.ma/v1/campaigns/:id/send
Bearer

إطلاق حملة

يطلق الحملة نحو أعضاء قائمتها الذين لم يلغوا اشتراكهم. يجري الإرسال في الخلفية؛ تابعه عبر GET /v1/campaigns/:id. يعيد 202.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
  • الأخطاء: 400 ALREADY_RUNNING و400 MISSING_LIST و400 EMPTY_LIST (لا مستلم مؤهل) و400 MISSING_BODY و404 NOT_FOUND. تُسعَّر كل رسالة وتُخصم كإرسال فردي.
POSThttps://api.envoisms.ma/v1/campaigns/:id/send
curl -X POST "https://api.envoisms.ma/v1/campaigns/{id}/send" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f",
  "status": "running",
  "total": 1420
}
DocsCampaigns/campaigns/:id/pause
POSThttps://api.envoisms.ma/v1/campaigns/:id/pause
Bearer

إيقاف حملة مؤقتاً

يوقف حملة جارية مؤقتاً. 409 NOT_RUNNING إن لم تكن جارية.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
POSThttps://api.envoisms.ma/v1/campaigns/:id/pause
curl -X POST "https://api.envoisms.ma/v1/campaigns/{id}/pause" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "paused": true,
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f"
}
DocsCampaigns/campaigns/:id/resume
POSThttps://api.envoisms.ma/v1/campaigns/:id/resume
Bearer

استئناف حملة

يستأنف حملة متوقفة مؤقتاً من حيث توقفت. 409 NOT_PAUSED إن لم تكن متوقفة.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: campaigns.
POSThttps://api.envoisms.ma/v1/campaigns/:id/resume
curl -X POST "https://api.envoisms.ma/v1/campaigns/{id}/resume" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "resumed": true,
  "id": "cmp_8d2a4c6e1b3f5a7c9e0b2d4f"
}
DocsWebhooks/webhooks
GEThttps://api.envoisms.ma/v1/webhooks
Bearer

قائمة Webhooks

يعيد Webhooks النشطة لديك. لا يظهر السر إلا مقنَّعاً (secret_hint)؛ ولا يُعرض كاملاً إلا عند الإنشاء والتدوير.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
GEThttps://api.envoisms.ma/v1/webhooks
curl -X GET "https://api.envoisms.ma/v1/webhooks" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e",
      "name": "Webhook Endpoint",
      "target_type": "custom",
      "format": "standard",
      "url": "https://example.ma/hooks/envoisms",
      "events": "[\"message.delivered\",\"message.failed\"]",
      "active": 1,
      "last_triggered_at": "2026-10-22 09:14:09",
      "last_status": 200,
      "created_at": "2026-10-01 10:00:00",
      "secret_hint": "••••9c2e"
    }
  ]
}
DocsWebhooks/webhooks
POSThttps://api.envoisms.ma/v1/webhooks
Bearer

إنشاء Webhook

يسجّل رابط HTTPS يستقبل الأحداث المختارة. يعيد 201 مع سر التوقيع، ويُعرض هذه المرة فقط.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
urlstringمطلوبرابط HTTPS عام (وإلا 400 INVALID_URL).
eventsstring[]اختياريmessage.sent وmessage.delivered وmessage.read وmessage.failed وmessage.undeliverable وmessage.fallback وmessage.inbound وmessage.reaction وcontact.optout وcontact.optin وlead.qualified؛ وأحرف البدل "message.*" و"*". الافتراضي: ["message.delivered"، "message.failed"].
secretstringاختياريسر التوقيع؛ يُولَّد (sec_…) إن لم يُرسل.
name | formatstringاختياريتسمية؛ والصيغة standard ‏({"event"، "data"، "timestamp"}) أو flat (حقول data في المستوى الأعلى أيضاً، لجدول بيانات).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
  • التوقيع: يحمل كل إرسال X-EnvoiSMS-Signature-256: t=<وقت يونكس>,v1=<HMAC-SHA256 ست عشري لـ "t.body" بالسر>، وX-EnvoiSMS-Event. ارفض كل طابع زمني أقدم من 5 دقائق. يُعاد الفشل (5xx أو 429 أو الشبكة) بعد 60 ثانية ثم 10 دقائق ثم ساعة: 4 محاولات إجمالاً.
  • يتوقف عدد Webhooks النشطة على الباقة (Starter ‏2، Business ‏5، Pro ‏15، Enterprise ‏50)؛ وما زاد 403 LIMIT_EXCEEDED.
POSThttps://api.envoisms.ma/v1/webhooks
curl -X POST "https://api.envoisms.ma/v1/webhooks" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.ma/webhooks/envoisms",
    "events": [
      "message.delivered",
      "message.failed",
      "message.inbound"
    ]
  }'
{
  "id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e",
  "name": "Webhook Endpoint",
  "target_type": "custom",
  "format": "standard",
  "url": "https://example.ma/hooks/envoisms",
  "events": ["message.delivered", "message.failed"],
  "secret": "sec_3d5f7a9c1e3b5d7f9a1c9c2e",
  "active": true
}
DocsWebhooks/webhooks/:id
PATCHhttps://api.envoisms.ma/v1/webhooks/:id
Bearer

تعديل Webhook

يعدّل رابط Webhook أو أحداثه أو اسمه أو صيغته أو حالة تفعيله؛ لا يتغير إلا ما ترسله.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
url | events | name | formatmixedاختيارينفس قواعد الإنشاء.
activebooleanاختياريالقيمة false توقف الإرسال إلى هذا Webhook.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
PATCHhttps://api.envoisms.ma/v1/webhooks/:id
curl -X PATCH "https://api.envoisms.ma/v1/webhooks/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "active": false
  }'
{
  "updated": true,
  "id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e"
}
DocsWebhooks/webhooks/:id
DELETEhttps://api.envoisms.ma/v1/webhooks/:id
Bearer

حذف Webhook

يعطّل Webhook: لا يُرسل إليه أي حدث بعد ذلك ويختفي من القائمة.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
DELETEhttps://api.envoisms.ma/v1/webhooks/:id
curl -X DELETE "https://api.envoisms.ma/v1/webhooks/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "deleted": true,
  "id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e"
}
DocsWebhooks/webhooks/:id/test
POSThttps://api.envoisms.ma/v1/webhooks/:id/test
Bearer

اختبار Webhook

يرسل حدثاً نموذجياً موقَّعاً كحدث حقيقي إلى رابط Webhook. يعيد 202 مع النموذج المرسل.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
eventstringاختيارياسم الحدث المراد محاكاته (الافتراضي: lead.qualified). البيانات النموذجية رسالة واردة مع message.inbound، وعميل مؤهل في غير ذلك.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
POSThttps://api.envoisms.ma/v1/webhooks/:id/test
curl -X POST "https://api.envoisms.ma/v1/webhooks/{id}/test" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "message.delivered"
  }'
{
  "queued": true,
  "id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e",
  "event": "message.inbound",
  "sample": {
    "event": "message.inbound",
    "data": {
      "message_id": "msg_demo_k3x9f2ab",
      "from": "+212612345678",
      "to": "+212708789095",
      "channel": "whatsapp",
      "text": "Bonjour, je souhaite des informations sur vos tarifs et solutions.",
      "contact_name": "Karim Bennani",
      "timestamp": "2026-10-22T09:30:00.000Z"
    },
    "timestamp": "2026-10-22T09:30:00.000Z"
  }
}
DocsWebhooks/webhooks/:id/rotate-secret
POSThttps://api.envoisms.ma/v1/webhooks/:id/rotate-secret
Bearer

تدوير سر Webhook

يستبدل سر التوقيع ويعيد السر الجديد هذه المرة فقط. تبقى الإرسالات الموجودة في قائمة الانتظار موقَّعة بالسر القديم: اقبل الاثنين بضع دقائق.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
POSThttps://api.envoisms.ma/v1/webhooks/:id/rotate-secret
curl -X POST "https://api.envoisms.ma/v1/webhooks/{id}/rotate-secret" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e",
  "secret": "sec_7a9c1e3b5d7f9a1c3e5b0d2f",
  "rotated": true
}
DocsWebhooks/webhooks/logs
GEThttps://api.envoisms.ma/v1/webhooks/logs
Bearer

سجل إرسالات Webhook

يعيد آخر 100 محاولة إرسال من الأحدث إلى الأقدم، مع النص المرسل واستجابة خادمك.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
webhook_idstringاختياريإرسالات هذا Webhook فقط.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
GEThttps://api.envoisms.ma/v1/webhooks/logs
curl -X GET "https://api.envoisms.ma/v1/webhooks/logs" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "0b6f3c2e-8a4d-4f1b-9c7e-2d5a1f8e6b30",
      "webhook_id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e",
      "event": "message.delivered",
      "url": "https://example.ma/hooks/envoisms",
      "payload": "{\"event\":\"message.delivered\",\"data\":{\"id\":\"msg_3f9a1c7e5b2d4a6f8e0c1b3d\",\"to\":\"+212612345678\",\"channel\":\"sms\",\"status\":\"delivered\"},\"timestamp\":\"2026-10-22T09:14:09.120Z\"}",
      "status_code": 500,
      "error_message": null,
      "attempt": 1,
      "delivered": 0,
      "created_at": "2026-10-22 09:14:09"
    }
  ],
  "max_attempts": 4
}
DocsWebhooks/webhooks/logs/:log_id/replay
POSThttps://api.envoisms.ma/v1/webhooks/logs/:log_id/replay
Bearer

إعادة إرسال Webhook

يعيد إرسال حدث مسجَّل — الحدث نفسه والبيانات نفسها بتوقيع جديد — إلى الرابط الحالي لـ Webhook مع المحاولات المعتادة. يعيد 202.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: webhooks.
  • 404 NOT_FOUND إذا كان السجل غير معروف أو حُذف Webhook الخاص به؛ و422 REPLAY_UNAVAILABLE إذا لم يُحفظ النص المرسل.
POSThttps://api.envoisms.ma/v1/webhooks/logs/:log_id/replay
curl -X POST "https://api.envoisms.ma/v1/webhooks/logs/{log_id}/replay" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "queued": true,
  "replay_of": "0b6f3c2e-8a4d-4f1b-9c7e-2d5a1f8e6b30",
  "webhook_id": "whk_5f2b7d9a1c3e5b7d9f1a3c5e",
  "event": "message.delivered"
}
DocsWebhooks/inbound-webhooks
GEThttps://api.envoisms.ma/v1/inbound-webhooks
Bearer

قائمة Webhooks الواردة

يعيد Webhooks الواردة لديك: روابط التقاط تحوّل نداءً من أداة خارجية (استمارة، Zapier، Make…) إلى رسالة مُرسلة.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • أي مفتاح API صالح: لا تُشترط صلاحية بعينها.
GEThttps://api.envoisms.ma/v1/inbound-webhooks
curl -X GET "https://api.envoisms.ma/v1/inbound-webhooks" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "inwh_9a8b7c6d5e4f3a2b1c0d9e8f",
      "name": "Formulaire de contact",
      "channel": "whatsapp",
      "template_id": "tpl_4c1e9a7b3d5f2e8a6c0b1d3f",
      "active": 1,
      "created_at": "2026-10-12 14:00:00"
    }
  ]
}
DocsWebhooks/inbound-webhooks
POSThttps://api.envoisms.ma/v1/inbound-webhooks
Bearer

إنشاء Webhook وارد

ينشئ رابط التقاط POST /v1/inbound-webhooks/catch/:id: كل نداء JSON يستقبله يرسل رسالة إلى الرقم المقروء من النص. يعيد 201.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
namestringمطلوبتسمية المصدر.
channelstringمطلوبsms أو whatsapp.
mapping_configobjectمطلوب{"to_path": "contact.phone"، "variables": {"1": "contact.name"}}: مسار الرقم في JSON المستلم، ومسار كل متغير في القالب.
template_idstringاختياريالقالب المراد إرساله (المعرّف أو الاسم).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • أي مفتاح API صالح: لا تُشترط صلاحية بعينها.
  • لا يتطلب رابط الالتقاط مفتاحاً: معرّفه بمثابة السر، فلا تنشره. يقبل 64 كيلوبايت كحد أقصى و120 نداءً في الدقيقة، ويعيد 202 {"success": true، "messageId"} ويخصم من رصيدك كإرسال عادي. الحذف عبر DELETE /v1/inbound-webhooks/:id.
POSThttps://api.envoisms.ma/v1/inbound-webhooks
curl -X POST "https://api.envoisms.ma/v1/inbound-webhooks" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Website form",
    "channel": "whatsapp",
    "mapping_config": {
      "to_path": "phone"
    }
  }'
{
  "id": "inwh_9a8b7c6d5e4f3a2b1c0d9e8f"
}
DocsBilling/billing/balance
GEThttps://api.envoisms.ma/v1/billing/balance
Bearer

الاطلاع على الرصيد

يعيد الرصيد المسبق الدفع بالدرهم واليورو، والباقة وتاريخ انتهائها.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: balance.
  • يعيد GET /v1/balance الحقول الأربعة الأولى بنفس الصلاحية.
GEThttps://api.envoisms.ma/v1/billing/balance
curl -X GET "https://api.envoisms.ma/v1/billing/balance" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "balance_mad": 1492.5,
  "balance_eur": 135.68,
  "primary_currency": "MAD",
  "plan": "business",
  "plan_expires_at": "2026-12-31 23:59:59",
  "plan_days_left": 70
}
DocsBilling/billing/transactions
GEThttps://api.envoisms.ma/v1/billing/transactions
Bearer

قائمة المعاملات

يعيد حركات الرصيد من الأحدث إلى الأقدم: الشحن والاستهلاك والاستردادات والتسويات والأرصدة الممنوحة، ولكل منها الرصيد بعدها.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
limitintegerاختياريعدد النتائج: 50 افتراضياً و200 كحد أقصى.
offsetintegerاختياريعدد النتائج التي يتم تخطيها (للتقسيم على صفحات). الافتراضي: 0.
typestringاختياريtopup أو usage أو refund أو adjustment أو grant (وإلا 400 INVALID_FIELD).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: billing.
GEThttps://api.envoisms.ma/v1/billing/transactions
curl -X GET "https://api.envoisms.ma/v1/billing/transactions?limit=50" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "tx_6e8a0c2e4b6d8f0a2c4e6b8d",
      "type": "usage",
      "status": "completed",
      "amount_eur": -0.072,
      "amount_mad": -0.792,
      "balance_after_eur": 135.68,
      "balance_after_mad": 1492.5,
      "payment_method": null,
      "description": "SMS +212612345678",
      "reference": "msg_3f9a1c7e5b2d4a6f8e0c1b3d",
      "stripe_invoice_id": null,
      "created_at": "2026-10-22 09:14:03"
    }
  ],
  "limit": 50,
  "offset": 0,
  "total": 1,
  "type": null
}
DocsMachine Payments/machine-payments/status
GEThttps://api.envoisms.ma/v1/machine-payments/status
Public

حالة المدفوعات الآلية

يبيّن ما إذا كان بإمكان وكيل بلا حساب أن يدفع مقابل الوصول إلى API بإيداع USDC ‏(HTTP 402، بروتوكول MPP)، وبأي شروط. بلا مصادقة.

الترويسات
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • عند التعطيل تكون الاستجابة {"enabled": false}.
  • المسار: استدعِ ‎/v1/messages أو ‎/v1/waba أو ‎/v1/verify أو ‎/v1/mcp بلا ترويسة Authorization ومع X-Payment-Method: mpp (أو Accept: application/problem+json)؛ فتكون الاستجابة 402 مع ترويسة WWW-Authenticate: Payment تصف الإيداع. أودِع deposit_usd بعملة USDC ثم أعد الاستدعاء مع Authorization: Payment <credential>. تحمل الاستجابة مفتاح API الممنوح في X-Machine-Session-Key (مرة واحدة) والإيصال في Payment-Receipt؛ ثم استعمل هذا المفتاح كمفتاح Bearer.
  • بدون X-Payment-Method أو Accept: application/problem+json يتلقى الاستدعاء غير المصادَق 401 UNAUTHORIZED. الإيداع غير المؤكد بعد يعطي 402 PAYMENT_NOT_SETTLED؛ وبيانات الاعتماد غير المقروءة 400 INVALID_CREDENTIAL. لا يحمل المفتاح الممنوح إلا الصلاحيات send وstatus وbalance وverify. وبحد أقصى 5 تحديات في الدقيقة لكل عنوان IP.
GEThttps://api.envoisms.ma/v1/machine-payments/status
curl -X GET "https://api.envoisms.ma/v1/machine-payments/status" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "enabled": true,
  "deposit_usd": 5,
  "credit_mad": 46.5,
  "networks": ["base", "tempo"],
  "permissions": ["send", "status", "balance", "verify"]
}
DocsAnalytics/analytics
GEThttps://api.envoisms.ma/v1/analytics
Bearer

إحصائيات الإرسال

يعيد خلال نافذة من الأيام الأحجام والتسليم المؤكد والإنفاق المخصوم وتوزيعها حسب القناة والمشغّل والحالة واليوم.

معلمات الاستعلام
المعلمةالنوعالحالةالوصف
daysintegerاختياريحجم النافذة، 30 افتراضياً و365 كحد أقصى.
campaign_idstringاختياريإحصائيات حملة واحدة (وتُسقط الاستجابة حينها error_diagnostics وwaba_breakdown).
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: analytics.
  • يُحسب delivery_rate على الرسائل التي أُكِّد تسليمها أو نُفي فقط؛ ويبيّن coverage_pct نسبة الرسائل التي حصلت على هذا التأكيد. القيمة المجهولة null وليست 100 أبداً. وcost_* هو ما خُصم بعد طرح الاستردادات. تُخزَّن الاستجابة مؤقتاً 60 ثانية (الترويسة X-Cache).
GEThttps://api.envoisms.ma/v1/analytics
curl -X GET "https://api.envoisms.ma/v1/analytics" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "window_days": 30,
  "campaign_id": null,
  "summary": {
    "total": 420,
    "delivered": 398,
    "failed": 6,
    "unconfirmed": 16,
    "delivery_rate": 98.51,
    "coverage_pct": 96.19,
    "cost_eur": 30.24,
    "cost_mad": 332.64,
    "avg_latency": 4.2
  },
  "channels": [
    { "channel": "sms", "total": 420, "cost_eur": 30.24, "cost_mad": 332.64, "fallback_sends": 0 }
  ],
  "operators": [
    { "operator": "Maroc Telecom", "total": 250, "delivered": 240, "failed": 2, "unconfirmed": 8, "cost_eur": 18, "cost_mad": 198, "delivery_rate": 99.17, "coverage_pct": 96.8, "avg_latency": null }
  ],
  "status_distribution": [
    { "status": "delivered", "total": 398 },
    { "status": "unconfirmed", "total": 16 },
    { "status": "failed", "total": 6 }
  ],
  "daily": [
    { "day": "2026-10-21", "total": 14, "sms_total": 14, "whatsapp_total": 0, "delivered": 13, "failed": 0, "unconfirmed": 1, "cost_eur": 1.008, "cost_mad": 11.088 }
  ],
  "error_diagnostics": [],
  "waba_breakdown": []
}
DocsAPI Keys/api-keys
GEThttps://api.envoisms.ma/v1/api-keys
Bearer

قائمة مفاتيح API

يعيد مفاتيح API في الحساب، النشطة والملغاة، دون قيمتها الكاملة أبداً.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: api_keys.
  • permissions وip_whitelist سلسلتا JSON (وip_whitelist تكون null بلا تقييد).
GEThttps://api.envoisms.ma/v1/api-keys
curl -X GET "https://api.envoisms.ma/v1/api-keys" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "data": [
    {
      "id": "key_e84c2a6b8d0f1e3c5a7b9d2f",
      "name": "Serveur de production",
      "key_prefix": "smr_a8f7d6c5",
      "ip_whitelist": "[\"196.200.1.4\"]",
      "rate_limit": 180,
      "permissions": "[\"send\",\"verify\",\"status\",\"balance\"]",
      "active": 1,
      "last_used_at": "2026-10-22 09:14:03",
      "created_at": "2026-10-01 08:00:00",
      "sandbox": false
    }
  ]
}
DocsAPI Keys/api-keys
POSThttps://api.envoisms.ma/v1/api-keys
Bearer

إنشاء مفتاح API

ينشئ مفتاحاً حقيقياً (smr_…) أو تجريبياً (env_test_…). يعيد 201؛ ولا تُعرض القيمة الكاملة (api_key) إلا مرة واحدة.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
namestringاختياريتسمية المفتاح (الافتراضي: "API key").
permissionsstring[]اختياريمن بين send وverify وstatus وbalance وcontacts وcampaigns وwebhooks وbilling وanalytics وapi_keys وoptouts وsender_id. الافتراضي: send وverify وstatus وbalance. تُتجاهل القيم غير المعروفة.
ip_whiteliststring[]اختياريعناوين IP الوحيدة المسموح لها باستعمال المفتاح.
rate_limitintegerاختياريعدد الطلبات في الدقيقة من 10 إلى 2000. الافتراضي حسب الباقة: Starter ‏60، Business ‏180، Pro ‏500، Enterprise ‏1200.
sandboxbooleanاختياريالقيمة true تنشئ مفتاح اختبار: تُتحقَّق الطلبات وتُسجَّل دون إرسال أو فوترة. ونمط المفتاح نهائي.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: api_keys.
  • يتوقف عدد المفاتيح الحقيقية النشطة على الباقة، وللمفاتيح التجريبية سقف خاص بها؛ وما زاد 403 LIMIT_EXCEEDED. ويضيف المفتاح التجريبي "note" إلى الاستجابة.
POSThttps://api.envoisms.ma/v1/api-keys
curl -X POST "https://api.envoisms.ma/v1/api-keys" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "OTP backend",
    "permissions": [
      "verify",
      "status"
    ],
    "sandbox": true
  }'
{
  "id": "key_e84c2a6b8d0f1e3c5a7b9d2f",
  "name": "Serveur de production",
  "key_prefix": "smr_a8f7d6c5",
  "api_key": "smr_a8f7d6c5…",
  "permissions": ["send", "verify", "status", "balance"],
  "rate_limit": 180,
  "sandbox": false,
  "warning": "The full API key is shown once. Store it securely."
}
DocsAPI Keys/api-keys/:id
PATCHhttps://api.envoisms.ma/v1/api-keys/:id
Bearer

تعديل مفتاح API

يعدّل اسم المفتاح أو صلاحياته أو عناوين IP المسموحة أو حد الطلبات أو حالة تفعيله.

نص الطلب (JSON)
الحقلالنوعالحالةالوصف
name | permissions | ip_whitelistmixedاختيارينفس قواعد الإنشاء.
rate_limitintegerاختياريعدد الطلبات في الدقيقة من 10 إلى 1000.
activebooleanاختياريالقيمة false تعلّق المفتاح.
الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: api_keys.
  • لا يتغير نمط المفتاح التجريبي أو الحقيقي: 400 SANDBOX_IMMUTABLE. أنشئ مفتاحاً جديداً.
PATCHhttps://api.envoisms.ma/v1/api-keys/:id
curl -X PATCH "https://api.envoisms.ma/v1/api-keys/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "OTP backend (rotated)"
  }'
{
  "updated": true,
  "id": "key_e84c2a6b8d0f1e3c5a7b9d2f"
}
DocsAPI Keys/api-keys/:id
DELETEhttps://api.envoisms.ma/v1/api-keys/:id
Bearer

إلغاء مفتاح API

يلغي مفتاحاً نهائياً: لم يعد يصادق أي طلب.

الترويسات
Authorization: Bearer smr_…
Content-Type: application/json
Accept: application/json
معلومات مفيدة
  • صلاحية مفتاح API المطلوبة: api_keys.
DELETEhttps://api.envoisms.ma/v1/api-keys/:id
curl -X DELETE "https://api.envoisms.ma/v1/api-keys/{id}" \
  -H "Authorization: Bearer $ENVOISMS_API_KEY"
{
  "revoked": true,
  "id": "key_e84c2a6b8d0f1e3c5a7b9d2f"
}