انتقل للمحتوى

    عربي أو إنجليزي · ↑↓ للتنقل · Enter للفتح · Esc للقفل

    English
    في الصفحة دي

    الحملات (إرسال جماعي)

    إنشاء وتشغيل حملة

    POST/v2/campaigns
    • الصلاحية:campaigns:write
    • Idempotency-Key:إجباري
    • بيبعت رسايل

    المحتوى: نص، صورة/فيديو/صوت/ملف (media.url)، موقع، جهة اتصال، زرار رابط، أزرار، قائمة. المستلمين في الطلب (لحد 10,000 بمتغيرات) أو contactListId أو audience.

    البارامترات

    الهيدرز

    الاسمالنوعالقيودالوصف
    Idempotency-Keyإجباريالنوعstringالقيود≤ 191 حرفالوصفid فريد من عندك للعملية دي (حد أقصى 191 حرف ASCII). لو كررت بنفس المفتاح ونفس الـ body بيرجعلك أول رد ومعاه Idempotent-Replayed: true — عمرها ما تتنفذ مرتين. بيتحفظ 24 ساعة.
    X-Request-Idاختياريالنوعstringالقيود—الوصفاختياري: id الطلب بتاعك وبيرجعلك (غير كده بنعمل req_…). اديه للدعم لو احتجت.

    الـ Body

    الاسمالنوعالقيودالوصف
    numberIdإجباريالنوعstringالقيود—الوصفالرقم اللي هتشتغل عليه (الـ id من GET /v2/numbers). المفتاح المقصور على أرقام معينة يستخدمها هي بس.
    nameإجباريالنوعstringالقيود≤ 120 حرفالوصفاسم الحملة للتقارير (حد أقصى 120).
    contentإجباريالنوعobjectالقيود—الوصفالمحتوى: { type, … } بنص أو image / video / audio / document (media.url) أو location أو contact أو cta_url أو buttons أو list. استخدم {متغير|بديل} و [[صيغة|تانية]] عشان النصوص تختلف.
    recipientsاختياريالنوعobject[]القيود≤ 10000 عنصرالوصفالجمهور مباشرة (حد أقصى 10,000). أو استخدم contactListId / audience بدلها.
    recipients[].phoneاختياريالنوعstringالقيود—الوصفرقم المستلم، دولي. الأرقام الغلط واللي لغت اشتراكها بتتخطى ومش بيتبعتلها.
    recipients[].variablesاختياريالنوعobjectالقيود—الوصفقيم الـ {متغيرات} في المحتوى، مثلًا { "name": "منى" }.
    contactListIdاختياريالنوعstringالقيود—الوصفابعت لقائمة جهات اتصال محفوظة بدل الأرقام المباشرة.
    audienceاختياريالنوعobjectالقيود—الوصفاختار جهات الاتصال بالقوايم والتاجز.
    audience.listIdsاختياريالنوعarrayالقيود—الوصفقوايم جهات الاتصال اللي تدخل.
    audience.tagsاختياريالنوعarrayالقيود—الوصفجهات الاتصال اللي عليها أي تاج من دول.
    audience.excludeTagsاختياريالنوعarrayالقيود—الوصفتخطى جهات الاتصال اللي عليها أي تاج من دول.
    optInConfirmedإجباريالنوعbooleanالقيودلازم trueالوصفلازم true: بتأكد إن كل المستلمين وافقوا يستقبلوا منك. إجباري في كل حملة.
    speedاختياريالنوعstringالقيودواحد من: SAFE · NORMAL · FASTالوصفسرعة الإرسال (الافتراضي NORMAL). SAFE الأبطأ وأحسن اختيار للأرقام الجديدة؛ وكل السرعات جوه حدود حماية الرقم.
    scheduleAtاختياريالنوعstring (date-time)القيود—الوصفابدأ بعدين (ISO 8601). ساعات الهدوء بتتطبق برضه.
    startاختياريالنوعbooleanالقيودالافتراضي trueالوصفfalse بيعمل مسودة؛ ابدأها بعدين بـ POST /v2/campaigns/{id}/start. المسودات اللي ما بدأتش بتتمسح بعد 30 يوم.

    الطلب

    curl -X POST "https://mursilat.com/api/v2/campaigns" \
      -H "Authorization: Bearer $WASLA_API_KEY" \
      -H "Idempotency-Key: order-1042-confirm" \
      -H "Content-Type: application/json" \
      -d '{
      "numberId": "cm1abcd2345efgh6789ijkl",
      "name": "عرض الجمعة",
      "content": {
        "type": "cta_url",
        "body": {
          "text": "أهلاً {name|عميلنا} 👋 خصم 20% لحد الجمعة"
        },
        "cta": {
          "title": "شوف العرض",
          "url": "https://example.com/offer?ref={name}"
        }
      },
      "recipients": [
        {
          "phone": "201001234567",
          "variables": {
            "name": "منى"
          }
        },
        {
          "phone": "966501234567"
        }
      ],
      "optInConfirmed": true,
      "speed": "SAFE"
    }'
    الطلب — JSON
    {
      "numberId": "cm1abcd2345efgh6789ijkl",
      "name": "عرض الجمعة",
      "content": {
        "type": "cta_url",
        "body": {
          "text": "أهلاً {name|عميلنا} 👋 خصم 20% لحد الجمعة"
        },
        "cta": {
          "title": "شوف العرض",
          "url": "https://example.com/offer?ref={name}"
        }
      },
      "recipients": [
        {
          "phone": "201001234567",
          "variables": {
            "name": "منى"
          }
        },
        {
          "phone": "966501234567"
        }
      ],
      "optInConfirmed": true,
      "speed": "SAFE"
    }

    الرد

    201مثال

    201 — application/json
    {
      "id": "cm2camp0001xyz",
      "numberId": "cm1abcd2345efgh6789ijkl",
      "name": "عرض الجمعة",
      "status": "scheduled",
      "contentType": "cta_url",
      "createdVia": "api",
      "speed": "SAFE",
      "scheduledAt": null,
      "startedAt": "2026-10-13T09:00:00.000Z",
      "pausedAt": null,
      "completedAt": null,
      "pause": null,
      "progress": {
        "total": 500,
        "queued": 380,
        "sent": 120,
        "delivered": 115,
        "read": 70,
        "replied": 9,
        "failed": 0,
        "skipped": 3,
        "optOuts": 1,
        "percent": 24
      },
      "replies": null,
      "eta": {
        "remaining": 380,
        "perDayCap": 200,
        "remainingToday": 80,
        "estimatedMinutesToday": 34,
        "extraDays": 2,
        "note": "Estimate from the number warm-up caps and pacing."
      },
      "purged": false,
      "purgedAt": null,
      "createdAt": "2026-10-13T08:55:00.000Z",
      "updatedAt": "2026-10-13T09:30:00.000Z",
      "recipientsUpload": {
        "total": 2,
        "invalid": 0,
        "notOnWhatsApp": 0,
        "unchecked": 0
      }
    }

    شكل الرد

    حقول الرد في المثال. افتح الكائنات والقوايم.

    • responseobject20 حقل
      • idstring "cm2camp0001xyz"
      • numberIdstring "cm1abcd2345efgh6789ijkl"
      • namestring "عرض الجمعة"
      • statusstring "scheduled"
      • contentTypestring "cta_url"
      • createdViastring "api"
      • speedstring "SAFE"
      • scheduledAtnull null
      • startedAtstring "2026-10-13T09:00:00.000Z"
      • pausedAtnull null
      • completedAtnull null
      • pausenull null
      • progressobject10 حقل
        • totalinteger 500
        • queuedinteger 380
        • sentinteger 120
        • deliveredinteger 115
        • readinteger 70
        • repliedinteger 9
        • failedinteger 0
        • skippedinteger 3
        • optOutsinteger 1
        • percentinteger 24
      • repliesnull null
      • etaobject6 حقل
        • remaininginteger 380
        • perDayCapinteger 200
        • remainingTodayinteger 80
        • estimatedMinutesTodayinteger 34
        • extraDaysinteger 2
        • notestring "Estimate from the number warm-up caps and pacing."
      • purgedboolean false
      • purgedAtnull null
      • createdAtstring "2026-10-13T08:55:00.000Z"
      • updatedAtstring "2026-10-13T09:30:00.000Z"
      • recipientsUploadobject4 حقل
        • totalinteger 2
        • invalidinteger 0
        • notOnWhatsAppinteger 0
        • uncheckedinteger 0

    الأخطاء

    غير أخطاء المصادقة وحدود الطلبات والتحقق اللي ممكن ترجع من أي endpoint:

    الأخطاء →

    حماية الرقم والسلوك

    الحملات لأكتر من 50 رقم جديد محتاجة {متغير} أو [[spintax]] عشان النصوص تختلف.

    حماية الرقم بتنظم سرعة الحملة (السرعة المختارة جوه حدود التسخين)، وبتستنى في ساعات الهدوء (الافتراضي 10 بالليل لـ 9 الصبح)، وبتتخطى الأرقام الغلط واللي لغت اشتراكها.

    بتوقف الحملة لوحدها لو التسليم قليل (أقل من 80% في آخر ساعة) أو الإلغاءات كتير (أكتر من 3 من كل 100) أو واتساب حد السرعة — ساعة، وبعدها 24 ساعة. بيوصلك campaign.status بالسبب؛ وإيقاف المنصة مينفعش يتشال بدري (CAMPAIGN_RESUME_BLOCKED).

    جرّب

    ابعت الطلب ده من متصفحك لـ API مرسلات.

    مثال موثّق

    معاينة — النسخة دي من التوثيق مش على mursilat.com، فالكونسول بيعرض المثال الموثّق بدل ما يكلم الـ API.

    الطلبات الحقيقية بتستخدم رقمك وباقتك الحقيقيين: ممكن تبعت رسايل واتساب وتصرف من رصيدك وتمسح بيانات. (بيبعت رسايل)

    متخزن في ذاكرة التبويب ده بس: عمره ما بيتحفظ ولا بيتحط في الرابط، وبيتبعت لـ mursilat.com بس. لو عملت reload بيتنسي.

    تبعت الطلب ده بجد؟

    ده هيبعت رسالة واتساب حقيقية (أو حملة / كود) من رقمك وهيصرف من رصيد باقتك.

    POST /v2/campaigns