تخطَّ إلى المستندات
API

الإرسال إلى الجماهير

يرسل رسالة واحدة إلى كل من في جمهور أو أكثر، بنسخة منفصلة لكل شخص مخصصة من جهة اتصاله. لكل نسخة مستلم واحد بالضبط بلا cc ولا bcc، فلا يرى أحد لمن ذهبت أيضًا، وكل نسخة رسالة عادية لها معرّف `msg_` وأحداث وتتبع وخطافات ويب خاصة بها. يجيب الاستدعاء بـ `202` فورًا ويستمر الإرسال في الخلفية، فتابعه عبر `GET /broadcasts/{id}`.

POSTapi.openemail.uk/broadcasts

ينفّذ الاستدعاء الحقيقي على مساحة عملك، بمفتاحك أنت.

POST /broadcasts

يرسل رسالة واحدة إلى كل من في جمهور أو أكثر، بنسخة منفصلة لكل شخص مخصصة من جهة اتصاله. لكل نسخة مستلم واحد بالضبط بلا cc ولا bcc، فلا يرى أحد لمن ذهبت أيضًا، وكل نسخة رسالة عادية لها معرّف msg_ وأحداث وتتبع وخطافات ويب خاصة بها. يجيب الاستدعاء بـ 202 فورًا ويستمر الإرسال في الخلفية، فتابعه عبر GET /broadcasts/{id}.

مثال

يحتاج إلى emails:send وaudiences:read. يضم audienceIds من 1 إلى 10 معرّفات. يأتي المتن من html و/أو text، أو من template محفوظ، لا من الاثنين معًا، وsubject مطلوب ما لم يوفره القالب.

curl
curl -X POST "$OE/broadcasts" -H "$AUTH" -H 'content-type: application/json' -d '{  "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"],  "from": "Acme <[email protected]>",  "subject": "{{firstName|Hello}}, the September release is out",  "html": "<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>",  "text": "Hi {{firstName|there}}, here is what changed this month. Unsubscribe: {{unsubscribeUrl}}",  "tags": { "campaign": "release-2026-09" },  "scheduledAt": "PT2H"}'
الاستجابة
{  "object": "broadcast",  "id": "brd_5a8c1e3f7b2d94a06c8e1f3b",  "status": "scheduled",  "mode": "live",  "source": "api",  "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"],  "from": "Acme <[email protected]>",  "subject": "{{firstName|Hello}}, the September release is out",  "counts": {    "recipients": 412,    "created": 0,    "skipped": 0,    "failedToQueue": 0,    "queued": 0,    "sending": 0,    "sent": 0,    "failed": 0,    "cancelled": 0  },  "lastError": null,  "scheduledAt": "2026-09-23T14:00:00.000Z",  "startedAt": null,  "completedAt": null,  "cancelledAt": null,  "createdAt": "2026-09-23T12:00:00.000Z",  "updatedAt": "2026-09-23T12:00:00.000Z",  "replayed": false}

الرد هو queued، أو scheduled مع scheduledAt الذي يقبل لحظة بصيغة ISO 8601 أو مدة مثل PT2H، على ألا تتجاوز 365 يومًا. counts.recipients هو التقدير المأخوذ الآن، وتبدأ العدادات الأخرى من 0. وتسمّي الترويسة Location البث.

يمكن إعادة المحاولة بأمان مع ترويسة Idempotency-Key: المفتاح نفسه يجيب بـ 200 مع البث الذي أنشأه الاستدعاء الأول وIdempotency-Replayed: true، والمفتاح نفسه مع متن مختلف يعطي 422 idempotency_key_reuse. ومن دون مفتاح، إرسال المتن نفسه مرتين يرسل البث مرتين.

لا تُحفظ النسخ في مجلد المرسل، لأن البث هو السجل. GET /emails?broadcastId=brd_5a8c1e3f7b2d94a06c8e1f3b يعرضها، واحدة لكل شخص.

من يتلقاه

كل جهة اتصال في جمهور واحد على الأقل من الجماهير، تُحسب مرة واحدة مهما كان عدد الجماهير التي تضمها. ويُستبعد نوعان من جهات الاتصال: التي ألغت اشتراكها في كل جمهور مختار تنتمي إليه، والتي عنوانها في قائمة الحظر بعد ارتداد أو شكوى أو لأن أحدًا أضافه إليها. وجهة الاتصال المضافة إلى أحد الجماهير بعد الاستدعاء وقبل أن يصل إليها الإرسال تُشمل.

يمر الإرسال على الجماهير 50 شخصًا في كل مرة ويسلّم كل نسخة إلى المسار نفسه الذي يستخدمه POST /emails، فتُعاد محاولة كل نسخة وتُتتبع ويُبلَّغ عنها كأي رسالة أخرى. ويعيد POST /broadcasts/preview العدد الذي سيبدأ منه هذا الاستدعاء، دون إرسال أي شيء.

يُقارن الإرسال كله بعدد الرسائل الشهري في الخطة قبل كتابة أي شيء. والبث الذي لا تغطيه الحصة يُرفض بـ 429 send_quota_exceeded ولا يترك شيئًا خلفه. وتُحسب كل نسخة رسالة واحدة.

حقول الدمج

تُملأ subject وhtml وtext لكل شخص. ويقبل كل حقل قيمة بديلة بعد شرطة تُستخدم حين لا تكون لجهة الاتصال قيمة له، فيصير {{firstName|there}} "there" لجهة اتصال محفوظة بلا اسم. تُهرَّب القيم في html، وتُسمح المسافات داخل الأقواس، ويُترك أي {{…}} آخر كما كُتب تمامًا.

الحقليُملأ بـ
`{{firstName}}`الكلمة الأولى من اسم جهة الاتصال.
`{{lastName}}`بقية اسم جهة الاتصال بعد الكلمة الأولى.
`{{name}}`اسم جهة الاتصال كاملًا.
`{{email}}`العنوان الذي تذهب إليه النسخة.
`{{unsubscribeUrl}}`الرابط الذي يلغي اشتراك هذا الشخص في هذه الجماهير.

مع template بدلًا من متن، تُمرَّر القيم الخمس نفسها كخصائص، لكن فقط الخصائص التي يعلنها القالب. فالقالب الذي يعلن firstName يحصل عليها، والخاصية التي لا يعلنها لا تُرسل أبدًا، فلا تفشل النسخ أبدًا بسبب خاصية مجهولة. وكل ما تضعه في template.props يذهب إلى كل النسخ على حد سواء.

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

تحمل كل نسخة List-Unsubscribe وList-Unsubscribe-Post: List-Unsubscribe=One-Click. وهذا ما يتيح لبرنامج البريد عرض زر إلغاء الاشتراك الخاص به، وما يطلبه كبار مزودي صناديق البريد من البريد الجماعي.

المتن html أو text الذي لا يضع {{unsubscribeUrl}} بنفسه يحصل على تذييل من سطر واحد: "You are receiving this because you are on this mailing list. Unsubscribe". أما القالب فيُرسل كما هو تمامًا، فضع {{unsubscribeUrl}} في القالب.

يفتح الرابط صفحة فيها زر إلغاء الاشتراك، فماسح الروابط الذي يجلبه لا يلغي اشتراك أحد، بينما طلب النقرة الواحدة الذي يرسله برنامج البريد يلغي الاشتراك فورًا. وفي الحالتين يُعلَّم الشخص كملغٍ للاشتراك في كل جمهور ذهب إليه هذا البث، ويظهر ذلك كـ unsubscribedAt في GET /audiences/{id}/contacts. ولا تتأثر جماهيره الأخرى ولا جهة اتصاله ولا البريد المرسل إليه رسالةً رسالة.

حالات الرفض

الحالةالرمزمتى
403from_address_forbiddenلا يجوز للمفتاح الإرسال باسم from.
404audience_not_foundمعرّف في audienceIds لا يسمّي أي جمهور في مساحة العمل هذه.
409domain_not_sendableنطاق from لا يستطيع توقيع البريد بعد، كما في POST /emails.
422no_recipientsالجماهير فارغة، أو ألغى كل من فيها اشتراكه أو هو محظور.
422invalid_parameterلا متن، أو html أو text بجوار template، أو لا subject بلا قالب، أو أكثر من 10 جماهير أو 8 وسوم، أو scheduledAt ليس في المستقبل أو يتجاوز 365 يومًا.
422template_not_foundالقالب لا يُحَل. وحالات رفض القالب الأخرى تسمّي template.* أيضًا.
422capability_unsupportedالمفتاح مقصور على عناوين محددة. والجماهير ملك لمساحة العمل كلها.
429send_quota_exceededلا تستطيع الخطة تغطية نسخة للجميع هذا الشهر.

لا مرفقات ولا cc ولا bcc ولا ترجمة ولا تشفير. يقبل tags حتى 8، وتحمل كل نسخة أيضًا broadcast_id الذي يضيفه الخادم.