Suppressions API
تدير Suppressions API قوائم مساحات العمل لعناوين Email وأرقام الهواتف التي لن يرسل Joryio إليها. الحظر بوابة صارمة: ما دام معرّف ما محظورًا في قناة، تُتخطى كل رسالة إليه في تلك القناة، مهما كانت الحملة أو الرحلة التي تحاول الوصول إليه.
تعكس API واجهة Audience ← Suppression Lists في لوحة التحكم. استخدمها لتدقيق المحظورين أو ترحيل قائمة عناوين غير صالحة من منصة أخرى أو احترام طلب موافقة من أنظمتك أو رفع الحظر بعد حل ارتداد دائم.
جميع نقاط النهاية في هذه الصفحة نسبية إلى عنوان الأساس: https://api-eu1.joryio.com/api. راجع نظرة API العامة.
المصادقة
يُصادَق كل طلب بمفتاح API يحمل نطاق قابلية التسليم ذي الصلة، أو بجلسة dashboard، JWT. بيانات الحظر ضمن مساحة العمل؛ ولا يرى المفتاح أو يحرر إلا قوائم مساحة عمله.
Authorization: Bearer jry_live_your_api_key_here
Content-Type: application/json
النطاقات لكل نقطة نهاية
تحدد القناة النطاق المطلوب. تحتاج نقاط Email نطاق email_suppression:*، وتحتاج SMS وWhatsApp إلى sms_suppression:*.
| نقطة النهاية | قناة Email | قناة SMS / WhatsApp |
|---|---|---|
GET /suppressions | email_suppression:read | sms_suppression:read |
GET /suppressions/{identifier} | email_suppression:read | sms_suppression:read |
POST /suppressions | email_suppression:write | sms_suppression:write |
POST /suppressions/hard-bounce | email_suppression:write | -، Email فقط |
POST /suppressions/import | email_suppression:write | sms_suppression:write |
DELETE /suppressions/{identifier} | email_suppression:write | sms_suppression:write |
المفاهيم الأساسية
اقرأ هذا القسم قبل استدعاء نقاط الكتابة؛ لا معنى لباقي API قبل وضوح الفرق بين reason وsource.
reason، لماذا، مقابل source، من أين جاء
يحمل كل صف حظر حقلين مستقلين:
reason: لماذا حُظر المعرّف. إحدى القيم:unsubscribeأوhard_bounceأوcomplaintأوmanual.source: من أين جاء الحظر، أي أصله. إحدى القيم:deliveryأوapiأوimportأو مصدر موافقة مثلunsubscribe_link.
الحقلان متعامدان. قد يأتي hard_bounce من مصادر مختلفة: الارتداد الذي يراه مسار الإرسال لدينا يحمل source: "delivery"، أما الارتداد الذي تؤكده عبر API فيحمل source: "api". يبين reason معنى التسليم/الموافقة، ويبين source مقدار الثقة وهل يدخل في مقاييس السمعة.
أسباب الموافقة مقابل أسباب قابلية التسليم
تنقسم الأسباب الأربعة إلى عائلتين مختلفتي السلوك:
| العائلة | الأسباب | المعنى | هل تبقى بعد إعادة الاشتراك؟ |
|---|---|---|---|
| الموافقة | unsubscribe, manual | طلب المستلم، أو طلبت أنت نيابة عنه، عدم الاتصال. | لا - إعادة الاشتراك تسمح لجهة الاتصال تلك وحدها بالمرور (وتبقى الجهات الأخرى بالعنوان نفسه محظورة)؛ ويرفعه DELETE /suppressions. |
| قابلية التسليم | hard_bounce, complaint | العنوان/الرقم غير صالح أو علّمنا كرسائل مزعجة. | نعم؛ تبقى حتى عند إعادة الاشتراك. |
منع قابلية التسليم حقيقة تقنية عن العنوان وليس تفضيلاً، لذا لا ترفعه إعادة اشتراك المستلم - ولا الـ API أو الاستيراد أو لوحة التحكم. لا يرفع الارتداد الدائم أو شكوى البريد العشوائي إلا دعم Joryio (أو انتقال جهة الاتصال إلى عنوان بريد جديد).
لا يمكنك اختلاق ارتداد
مسارات الكتابة العادية، POST /suppressions وPOST /suppressions/import، تقيّد reason إلى manual أو unsubscribe. لا يمكنها ماديًا إنشاء صف hard_bounce أو complaint. الارتداد شيء تلاحظه المنصة، لا شيء يقرره العميل دون قيد.
المسار الوحيد الذي يسمح بتأكيد ارتداد هو POST /suppressions/hard-bounce، وحتى هناك يحمل الصف source: "api" فلا يختلط بارتداد رأيناه نحن.
الارتدادات الحقيقية فقط تؤثر في السمعة
يحتسب معدل الارتداد المبلغ عنه ومقاييس قابلية التسليم/السمعة في حسابك ارتدادات source: "delivery" فقط، أي ما رآه مسار الإرسال عند طبقة SMTP. الحظر المؤكد من API، source: "api"، أو المستورد، source: "import"، يمنع الإرسال لكنه لا يضخم معدل الارتداد المبلغ عنه. يمكنك بذلك تحميل العناوين المعروفة غير الصالحة مسبقًا لحماية سمعة المرسل من دون تلويث المقياس نفسه.
يتبع الحظر العنوان أو الرقم
يُفهرس الحظر بعنوان Email مطبّع أو رقم هاتف، لكل مساحة عمل، وليس بسجل جهة اتصال. لذلك يغطي عنوان واحد محظور كل جهات الاتصال المكررة التي تشاركه. احظر [email protected] مرة واحدة فتُمنع جميع جهات الاتصال بهذا العنوان على قناة Email في مساحة العمل.
تُقرأ أرقام الهاتف بالطريقة التي تُخزَّن بها في جهات الاتصال: الرقم بدون رمز الدولة (0501234567) يُقرأ وفق الدولة الافتراضية لأرقام الهاتف في مساحة العمل، ويُخزَّن الحظر تحت هذا الرقم (+972501234567) وتحت الصيغة الأقدم التي قد تحملها السجلات القديمة معًا، فيحظر كل جهة اتصال بهذا الرقم. والرقم غير الصالح إطلاقًا يُخزَّن أيضًا - لا يُحذف أبدًا.
الرقم الملتبس (الصالح كرقم محلي للدولة الافتراضية وكرقم لدولة أخرى معًا) يُرفض (400) عند إضافته أو إزالته، ويُتخطى (ويُحتسب في ambiguous) في الاستيراد المجمّع، لأن إحدى القراءتين قد تكون رقم شخص آخر: أرسله مع رمز الدولة (+...).
مرجع reason / source
قيم reason
reason | العائلة | ينشأ من |
|---|---|---|
unsubscribe | موافقة | رابط إلغاء الاشتراك أو POST /suppressions أو POST /suppressions/import |
manual | موافقة | إجراء المشغل أو POST /suppressions أو POST /suppressions/import |
hard_bounce | قابلية التسليم | مسار الإرسال أو POST /suppressions/hard-bounce |
complaint | قابلية التسليم | مسار الإرسال، feedback loops |
قيم source
source | المعنى | هل يدخل في السمعة؟ |
|---|---|---|
delivery | رصده مسار الإرسال/الاستقبال لدينا، ارتداد أو شكوى حقيقيان. | نعم |
api | تم تأكيده عبر REST API. | لا |
import | حُمّل عبر POST /suppressions/import، ترحيل مجمع. | لا |
unsubscribe_link، ومصادر موافقة أخرى | تغير موافقة يبدأه المستلم. | لا |
سرد عمليات الحظر
أعد قائمة مرقمة بالمعرفات المحظورة في قناة.
نقطة النهاية
GET /suppressions
معاملات الاستعلام
| المعامل | النوع | الافتراضي | الوصف |
|---|---|---|---|
channel | string | - | email أو sms أو whatsapp. مطلوب. |
reason | string | - | فلتر اختياري: unsubscribe أو hard_bounce أو complaint أو manual. |
limit | number | 100 | الصفوف في الصفحة، حتى 1000. |
offset | number | 0 | إزاحة الترقيم. |
طلب مثال
curl -X GET "https://api-eu1.joryio.com/api/suppressions?channel=email&reason=hard_bounce&limit=50" \
-H "Authorization: Bearer jry_live_your_api_key"
الاستجابة
{
"items": [
{
"channel": "email",
"identifierType": "email",
"reason": "hard_bounce",
"source": "delivery",
"scope": "channel",
"listId": null,
"createdAt": "2026-06-30T12:04:11.000Z"
},
{
"channel": "email",
"identifierType": "email",
"reason": "unsubscribe",
"source": "unsubscribe_link",
"scope": "group",
"listId": "grp_newsletter",
"createdAt": "2026-07-02T09:20:00.000Z"
}
],
"total": 214,
"limit": 50,
"offset": 0
}
فحص معرّف واحد
تحقق مما إذا كان معرّف واحد محظورًا في قناة.
نقطة النهاية
GET /suppressions/{identifier}
معامل المسار {identifier} هو عنوان Email أو رقم هاتف بترميز URL.
معاملات الاستعلام
| المعامل | النوع | الافتراضي | الوصف |
|---|---|---|---|
channel | string | - | email أو sms أو whatsapp. مطلوب. |
طلب مثال
-H "Authorization: Bearer jry_live_your_api_key"
الاستجابة: محظور
{
"suppressed": true,
"reason": "hard_bounce",
"source": "delivery",
"scope": "channel",
"listId": null,
"createdAt": "2026-06-30T12:04:11.000Z"
}
الاستجابة: غير محظور
{
"suppressed": false
}
إضافة حظر
أضف حظر موافقة أو يدويًا. استخدمه لاحترام إلغاء اشتراك وصل عبر أنظمتك الخاصة، كتذكرة دعم أو علم CRM أو تغير مركز تفضيلات لديك.
نقطة النهاية
POST /suppressions
نص الطلب
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
channel | string | نعم | email أو sms أو whatsapp. |
identifier | string | نعم | عنوان Email أو رقم هاتف لحظره. |
reason | string | لا | manual، الافتراضي، أو unsubscribe. مقيّد؛ يُرفض أي شيء آخر. |
scope | string | لا | channel، الافتراضي، أي كل القوائم على القناة، أو group مع listId لقائمة واحدة. |
كل بيانات اعتماد على نقطة النهاية هذه تحمل مساحة عمل واحدة: مفتاح الـAPI يخزّن workspaceId واحدًا، وجلسة لوحة التحكم تعمل داخل مساحة عملها الحالية. أما الحظر على مستوى المؤسسة كلها - الذي يُسكت معرّفًا في كل مساحات العمل - فليس له هنا مستدعٍ يمثّل المؤسسة، ولذلك لا يمكن إنشاؤه عبر هذه الواجهة.
وقد كان هذا هو الوضع الافتراضي سابقًا، ما يعني أن تكاملًا لعلامة تجارية واحدة كان يُسكت معرّفًا لدى العلامات الشقيقة دون أن يطلب ذلك.
الصفوف على مستوى المؤسسة التي أُنشئت قبل هذا التغيير ما زالت تُقرأ وتُحترم عند الإرسال. ويمسح DELETE صفوف مساحة العمل هذه فقط - ولا يمسح أبدًا صفًا على مستوى المؤسسة، لأن ذلك سيرفع الحظر في كل مساحات العمل الأخرى أيضًا. لرفع صف قديم على مستوى المؤسسة، تواصل مع دعم Joryio.
| listId | string | لا | مطلوب عندما يكون scope هو group: المجموعة/القائمة التي ينطبق عليها الحظر. يجب أن تكون قائمة في مساحة العمل هذه - غياب listId أو استخدام قائمة مساحة عمل أخرى يعيد 400. |
يسجل source للصف المنشأ هنا دائمًا كـ api. لا يمكن لنقطة النهاية هذه إنشاء hard_bounce أو complaint.
طلب مثال
curl -X POST https://api-eu1.joryio.com/api/suppressions \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channel": "email",
"identifier": "[email protected]",
"reason": "unsubscribe",
"scope": "group",
"listId": "grp_newsletter"
}'
الاستجابة
{
"channel": "email",
"identifierType": "email",
"reason": "unsubscribe",
"source": "api",
"scope": "group",
"listId": "grp_newsletter",
"createdAt": "2026-07-11T08:15:00.000Z"
}
reason: "unsubscribe" يحدّث جهات الاتصال أيضاًمع reason: "unsubscribe"، تُضبط أيضاً كل جهة اتصال في مساحة العمل بذلك البريد أو الهاتف على unsubscribed في القناة (أو، مع scope: "group"، في تلك القائمة)، مع سجل. أما المنع manual فيحظر الإرسال دون تغيير حالة جهات الاتصال نفسها.
تأكيد ارتداد دائم
سجل ارتدادًا دائمًا لعنوان Email. هذا هو المسار الوحيد في API الذي يسمح بتأكيد حظر قابلية تسليم، وهو منفصل ومقيّد عمدًا.
لماذا هذه النقطة منفصلة؟
- الارتداد شيء يرصده Joryio عادة وقت الإرسال، لا شيء يعلنه المستدعي. فصل تأكيد الارتداد عن مسارات الإضافة/الاستيراد يمنع الاختلاق العرضي أو غير المتحفظ.
- لأنك تؤكد بدل أن نرصد، يحمل الصف
source: "api". يمنع الإرسال تمامًا كارتداد حقيقي لكنه لا يختلط بما رأيناه نحن ولا يدخل في معدل الارتداد المبلغ عنه أو مقاييس سمعة المرسل. - هو Email فقط؛ لا مكافئ لأرقام الهاتف، إذ إن عدم تسليم SMS/WhatsApp يُنمذج بطريقة مختلفة.
نقطة النهاية
POST /suppressions/hard-bounce
نص الطلب
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
identifier | string | نعم | عنوان Email الذي ارتد ارتدادًا دائمًا. |
تكون القناة email ضمنية. يسجل الصف بـ reason: "hard_bounce" وsource: "api".
طلب مثال
curl -X POST https://api-eu1.joryio.com/api/suppressions/hard-bounce \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"identifier": "[email protected]"
}'
الاستجابة
{
"channel": "email",
"identifierType": "email",
"reason": "hard_bounce",
"source": "api",
"scope": "channel",
"listId": null,
"createdAt": "2026-07-11T08:20:00.000Z"
}
الاستيراد المجمع
حمّل قائمة حظر قائمة، مثلًا عند الترحيل من منصة أخرى.
نقطة النهاية
POST /suppressions/import
نص الطلب
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
channel | string | نعم | email أو sms أو whatsapp. |
entries | array | نعم | حتى 5000 كائن، كل واحد { identifier, reason? }. |
يُقيّد reason لكل إدخال إلى manual، الافتراضي، أو unsubscribe؛ ويحوّل أي قيمة أخرى إلى manual. يسجل كل صف مستورد بـ source: "import". ومثل نقطة الإضافة، لا يستطيع الاستيراد إنشاء ارتداد أو شكوى.
طلب مثال
curl -X POST https://api-eu1.joryio.com/api/suppressions/import \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channel": "email",
"entries": [
{ "identifier": "[email protected]" },
{ "identifier": "[email protected]", "reason": "unsubscribe" },
{ "identifier": "[email protected]" }
]
}'
الاستجابة
{
"channel": "email",
"received": 3,
"imported": 3,
"skipped": 0,
"source": "import"
}
إزالة حظر، إلغاء الحظر
أزل حظرًا ليسمح Joryio بالإرسال إلى المعرّف مجددًا.
نقطة النهاية
DELETE /suppressions/{identifier}
معاملات الاستعلام
| المعامل | النوع | الافتراضي | الوصف |
|---|---|---|---|
channel | string | - | email أو sms أو whatsapp. مطلوب. |
يزيل هذا صفوف منع الموافقة (unsubscribe وmanual) للمعرّف في القناة، في مساحة العمل هذه فقط. لا يزيل أبداً إلغاءً بكلمة STOP أو صف hard_bounce / complaint - تُذكر هذه في kept. تبقى جهات الاتصال التي ضُبطت حالتها على unsubscribed ملغاة؛ أعد اشتراك جهة اتصال عبر Subscriptions API.
طلب مثال
-H "Authorization: Bearer jry_live_your_api_key"
الاستجابة
{
"removed": 1,
"kept": { "deliverability": 1 }
}
يمثل removed عدد صفوف الحظر المحذوفة؛ فقد يحمل معرّف واحد صف موافقة بنطاق مجموعة وصف قابلية تسليم عالميًا في وقت واحد.
يعدّ kept (يظهر فقط عند الاحتفاظ بشيء) الصفوف التي لا يحق لهذا الـ API إزالتها: stop_keyword (إزالته سترفع الحظر عن الرقم لكل جهة اتصال تشترك فيه - أعد اشتراك جهة الاتصال الواحدة عبر Subscriptions API، أو يرسل الشخص START) وdeliverability (ارتداد دائم أو شكوى بريد عشوائي - لا يرفعه إلا دعم Joryio).
يعدّ legacy_twin (للهاتف فقط) الإدخالات المحفوظة تحت الصيغة المحلية القديمة للرقم (+10612345678 للرقم +31612345678): لا تُرفع إلا عندما يكون لمساحة العمل دولة افتراضية لأرقام الهاتف تقرؤها على أنها هذا الرقم تمامًا، لأن الأرقام المحلية نفسها قد تكون رقمًا لدولة أخرى. ويتبع START القاعدة نفسها، ولا يرفع مثل هذا الإدخال أبدًا عند إلغاء الحظر على مستوى المؤسسة.
ترحيل قائمة حظر قائمة
عند الانتقال إلى Joryio من منصة Email أو SMS أخرى، أحضر قائمة الحظر في اليوم الأول كي لا تعيد الإرسال إلى عناوين تعرف أنها غير صالحة أو ملغية الاشتراك.
- استورد القائمة كاملة عبر
POST /suppressions/import. تصل الإدخالات كـmanual، أوunsubscribeإن علّمتها، معsource: "import". تمنع الإرسال وتحمي سمعة المرسل في أول إرسال، من دون تضخيم معدل الارتداد المبلغ عنه لأن الصفوف المستوردة لا تدخل في السمعة. - فقط إذا احتجت تحديدًا إلى أن تُبلغ هذه العناوين كارتدادات، مثل الاستمرار في تحليلات الارتداد بعد الترحيل، أكدها فرديًا عبر
POST /suppressions/hard-bounce. ستبقىsource: "api"، فتمنع الإرسال وتظهر كارتدادات في قائمة الحظر دون أن تدخل كارتدادات رصدناها.
في معظم عمليات الترحيل، الخطوة 1 وحدها هي الاختيار الصحيح: توقف الإرسال وتحافظ على نظافة مقاييس السمعة.
استجابات الأخطاء
تشترك الأخطاء في الشكل القياسي. لا توجد مفردات مستقلة لرموز خطأ قابلة للقراءة آليًا؛ استخدم حالة HTTP وحقل message. راجع استجابة الخطأ في نظرة API. تضيف أخطاء التحقق، 400، مصفوفة errors برسالة لكل حقل فاشل:
{
"statusCode": 400,
"message": "Bad Request Exception",
"timestamp": "2026-07-12T09:00:00.000Z",
"path": "/suppressions",
"errors": [
"reason must be one of the following values: manual, unsubscribe"
]
}
ملحوظة مهمة: تفرض API نطاقات دقيقة حسب القناة. يحصل مفتاح API الذي يحمل نطاق SMS فقط على 403 عند لمس حظر Email، والعكس:
{
"statusCode": 403,
"message": "API key missing required scope 'email_suppression:write' for channel 'email'",
"timestamp": "2026-07-12T09:00:00.000Z",
"path": "/suppressions"
}