واجهة Brevo API: دليل عملي للمطورين

دليل Brevo API للمصادقة وتحديث جهات الاتصال وwebhooks وحدود المعدل وإعادة المحاولة الآمنة.

Brevo API

ما الإجابة المختصرة؟

استخدم https://api.brevo.com/v3/ وترويسة api-key لمفتاح API المعتاد. عند مزامنة جهات الاتصال، حدد معرّف مصدر ثابتًا وسمات معرّفة وقائمة واضحة، مع الحفاظ على إلغاء الاشتراك. تحقق من النتيجة وترويسات الحد، وقيد إعادة المحاولة بعد 429. تعامل مع webhooks بوصفها إشارات موثقة تحتاج إزالة التكرار والمطابقة.

معرفة المزيد
في هذه الصفحة

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

يبدأ الدليل بطلب كتابة يعمل، ثم يشرح فحوص مزامنة صغيرة قابلة للتكرار.

ما الذي تغطيه واجهة Brevo API

كل شيء يقع تحت مضيف واحد ومسار إصدار واحد. تقسّم وثائق المطورين السطح إلى أربعة مجالات منتجات:

  • المراسلة: البريد المعاملاتي، والرسائل النصية، و WhatsApp، بما في ذلك الإرسال الدفعي والجدولة ونشاط الرسائل.
  • منصّة التسويق: جهات الاتصال والقوائم والشرائح وحملات البريد الإلكتروني.
  • التجارة الإلكترونية: المنتجات والطلبات وتتبّع أحداث العملاء.
  • المحادثات: أداة الدردشة وإدارة المحادثات برمجيًا.

هذه المجالات تتشارك حسابًا واحدًا، وقاعدة جهات اتصال واحدة، ومفتاح API واحدًا. هذا مريح وخطير أحيانًا: نصّ برمجي كُتب على أساس تصوّر تجريبي للبيانات يتحدث في الواقع إلى جهات الاتصال نفسها التي ترسل إليها حملاتك.

المعاملاتي مقابل التسويقي

تختلف العائلتان في سلوكهما بما يكفي لجعل الخلط بينهما أكثر أخطاء التصميم شيوعًا.

معاملاتيتسويقي
نقطة النهاية الأساسيةPOST /v3/smtp/emailPOST /v3/emailCampaigns
تحديد المستلمينمستلمون صريحون في الطلبlistIds أو segmentIds
المُشغِّلتطبيقك، في الوقت الفعليمجدول أو يُرسَل عند الطلب
شكل الحجم المعتادمستمر، رسالة واحدة في كل مرةمتقطع، إرسالة واحدة كبيرة
موقف حدود المعدلمرتفع جدًا، 1,000 طلب في الثانية في المستوى العاممنخفض، نقاط نهاية الحملات تقع ضمن السقف العام

إذا كنت لا تزال تقرّر ما إذا كانت Brevo هي المنصّة المناسبة أصلًا، فإن نظرة عامة على المنصّة تغطي هذا الجانب.

المصادقة وإدارة المفاتيح

تستخدم Brevo مفتاح API بسيطًا داخل ترويسة مخصّصة. اسم الترويسة هو api-key، وليس Authorization، ولا توجد بادئة Bearer. هذه النقطة تُربك تقريبًا كل من استخدم واجهة مراسلة أخرى قبلها.

يمكن أن يستخدم OAuth رمز Bearer في العمليات المدعومة؛ ويبقى المفتاح المعتاد في ترويسة api-key.

Terminal window
curl https://api.brevo.com/v3/account \
-H "api-key: $BREVO_API_KEY"

تُنشأ المفاتيح داخل تطبيق Brevo ضمن إعدادات الحساب، في قسم SMTP and API، في تبويب API keys. امنح كل مفتاح اسمًا وصفيًا مرتبطًا بالنظام الذي يستخدمه. تُعرض قيمة المفتاح مرة واحدة فقط عند إنشائه، فإذا فقدتها تُنشئ مفتاحًا جديدًا بدل استرجاع القديم.

بعض القواعد العملية:

  • أصدر مفتاحًا منفصلًا لكل بيئة نشر ولكل خدمة. إبطال مفتاح مسرَّب يجب ألا يوقف ثلاثة أنظمة غير مرتبطة.
  • مفاتيح API القياسية تشمل الحساب كله. تعامل مع أي مفتاح على أنه وصول كامل إلى جهات الاتصال والإرسال وبيانات CRM.
  • تدعم Brevo أيضًا OAuth 2.0 للتطبيقات التي تعمل نيابة عن حسابات Brevo أخرى، وهو موصوف إلى جانب تدفق المفاتيح في مخططات المصادقة.
  • خادم MCP الذي تستخدمه مساعدات AI يأخذ رمزًا منفصلًا، وهو يستخدم فعلًا ترويسة bearer. يُنشأ ذلك الرمز في شاشة API keys نفسها لكنه غير قابل للتبادل مع مفتاح REST.

عنوان القاعدة والإصدارات وأول عملية كتابة

عنوان القاعدة هو https://api.brevo.com/v3/. رقم الإصدار في المسار وليس في ترويسة، و v3 هو الجيل الحالي. كل مسار في هذا الدليل نسبي لذلك العنوان.

استخدم في أول كتابة عنوانًا تجريبيًا تملكه، ومعرّف قائمة صالحًا، ومعرّف مصدر ثابتًا. أنشئ السمة FNAME في Brevo أولًا. باستخدام مفتاح حقيقي، يكتب هذا المثال مباشرة:

Terminal window
curl -X POST https://api.brevo.com/v3/contacts \
-H "api-key: $BREVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"ext_id": "test-source-contact-1",
"attributes": { "FNAME": "Dev" },
"listIds": [42],
"updateEnabled": true,
"getId": true
}'

استبدل 42 بمعرّف القائمة التجريبية. أعد قراءة جهة الاتصال وتحقق من المعرّف والاسم والقائمة والحظر. الرمز 2xx وحده لا يثبت النتيجة المتوقعة.

نقاط النهاية التي ستستخدمها فعلًا

جهات الاتصال

ينشئ POST /v3/contacts جهة اتصال. يقبل الطلب email وattributes المعرّفة وlistIds وext_id كمفتاح مصدر ثابت. يحدّث updateEnabled: true جهة موجودة، ويطلب getId: true المعرّف النهائي. يوثق Brevo هذه الحقول. استخدم قيمة ext_id نفسها في كل تشغيل واحفظ الربط بين معرّف المصدر ومعرّف Brevo.

قبل الكتابة، حدد النظام المسؤول عن كل سمة والقائمة التي تستقبل جهات الاتصال التي وافقت. اذكر listIds صراحة. لا ترسل emailBlacklisted: false في التحديث المعتاد. يحذر Brevo من أن تغيير بريد جهة محظورة قد يرفع الحظر؛ تعامل مع تغيير العنوان منفصلًا. تحقق من الحظر وإلغاء الاشتراك قبل الإضافة إلى قائمة تسويقية. قد تتغير الحالة بين القراءة والكتابة؛ إذا احتجت ضمانًا صارمًا فتحقق مرة أخيرة قبل الإرسال.

تمر القراءات عبر GET /v3/contacts، الذي يرقّم النتائج باستخدام limit (الافتراضي 50، والحد الأقصى 1000) و offset، ويدعم modifiedSince و createdSince بتوقيت UTC. عمليات المزامنة التزايدية يجب أن تعتمد على modifiedSince بدل المرور على القائمة كاملة. لاحظ أن المعامل filter يدعم عامل المساواة فقط، لذا فإن أي شيء أكثر تعبيرًا مكانه شريحة.

للتحميل الجماعي، يقبل POST /v3/contacts/import القيم fileUrl أو fileBody أو jsonBody، ويستهدف listIds، ويعمل بشكل غير متزامن مُعيدًا processId. توثّق Brevo حدًا أقصى للجسم يبلغ 10 ميجابايت وتنصح بالبقاء قرب 8 ميجابايت لأن التحليل يضخّم الحمولة. مرّر notifyUrl كي تعرف النتيجة بدل الاستعلام المتكرر.

البريد المعاملاتي

POST /v3/smtp/email هو حصان العمل. إلى جانب sender و to و subject و htmlContent، الحقول التي تستحق المعرفة هي:

  • templateId مع params، وهو يستبدل المحتوى المضمَّن بقالب Brevo واستبدالات متغيراته. حدود معاملات النسخة الواحدة 100 كيلوبايت، والمجموع التراكمي 1000 كيلوبايت.
  • messageVersions، الذي يرسل نسخًا مخصّصة في استدعاء واحد، بحد أقصى 99 مستلمًا لكل نسخة.
  • قد تساعد tags في ربط أحداث التسليم بسير العمل في التطبيق الذي أنشأها.
  • scheduledAt مع batchId، للإرسالات المستقبلية التي قد ترغب في إلغائها كمجموعة.
  • headers، بصيغة Title-Case، لترويسات SMTP المخصّصة.

يقبل الطلب الواحد 2,000 مستلم كحد أقصى. وللفرق بين هذه النقطة وإرسال الحملات، يقدّم دليل البريد المعاملاتي وجهة نظر استراتيجية المراسلة.

حملات البريد الإلكتروني

يتطلب POST /v3/emailCampaigns الحقلين name و sender، إضافة إلى مصدر محتوى واحد بالضبط: htmlContent (10 أحرف كحد أدنى، وأقل من 1 ميجابايت)، أو htmlUrl، أو templateId. يوضع الجمهور في recipients بصيغة listIds أو segmentIds، ويستخدم scheduledAt صيغة YYYY-MM-DDTHH:mm:ss.SSSZ بتوقيت UTC. وتغطي المسارات المرافقة الإرسال الفوري، وإرسال اختبار، وتحديث الحالة، وسحب تقرير الحملة.

الشركات والصفقات والكائنات

يمتلك نظام CRM في Brevo مسارَي كتابة متداخلين، والاختيار الصحيح بينهما مهم.

مسارات CRM هي POST /v3/companies و PATCH /v3/companies/{id} و DELETE /v3/companies/{id}، والمجموعة المكافئة للصفقات. هذه المسارات متزامنة. يعيد PATCH الحالة 204 بمجرد تطبيق التغيير.

أما واجهة الكائنات فهي المسار الجماعي: POST /v3/objects/{object_type}/batch/upsert يأخذ حتى 1000 سجل و 1 ميجابايت لكل طلب، وحتى 500 سمة لكل سجل، وحتى 10 سجلات ارتباط لكل نوع كائن في السجل الواحد. يعيد 202 مع processId، أي مقبول لا مطبَّق.

Terminal window
curl -X POST https://api.brevo.com/v3/objects/company/batch/upsert \
-H "api-key: $BREVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"records": [
{
"identifiers": { "id": 12345 },
"attributes": { "domain": "acme.example", "industry": "retail" }
}
]
}'

يغطي دليل Brevo CRM نموذج الكائنات من زاوية المشغّل.

حزم SDK الرسمية

تحافظ Brevo على عملاء برمجيين ضمن منظمة getbrevo على GitHub:

اللغةالمستودع
Node.jsgithub.com/getbrevo/brevo-node
Pythongithub.com/getbrevo/brevo-python
PHPgithub.com/getbrevo/brevo-php
Javagithub.com/getbrevo/brevo-java
C#github.com/getbrevo/brevo-csharp
Gogithub.com/getbrevo/brevo-go
Rubygithub.com/getbrevo/brevo-ruby

يُثبَّت عميل Node باسم @getbrevo/brevo:

Terminal window
npm install @getbrevo/brevo
import { BrevoClient } from "@getbrevo/brevo";
// Reconcile uncertain send outcomes before retrying.
const brevo = new BrevoClient({ apiKey: process.env.BREVO_API_KEY, maxRetries: 0 });
const result = await brevo.transactionalEmails.sendTransacEmail({
subject: "Order confirmed",
htmlContent: "<html><body><p>Thanks for your order.</p></body></html>",
sender: { name: "Acme", email: "[email protected]" },
to: [{ email: "[email protected]", name: "Customer" }],
tags: ["order-confirmation"],
});
console.log("Message ID:", result.messageId);

يُثبَّت عميل Python عبر pip install brevo-python. وإذا كنت تفضّل ألا تحمل اعتمادية SDK من أجل نقطتَي نهاية فقط، فإن سطح HTTP الخام صغير بما يكفي لاستدعائه مباشرة، وهذا يعزلك أيضًا عن تقلّبات إصدارات SDK:

ثبّت عميل Python بالأمر pip install brevo-python. ويمكن استخدام HTTP مباشرة لعدد قليل من نقاط النهاية:

import os
import requests
BASE = "https://api.brevo.com/v3"
HEADERS = {"api-key": os.environ["BREVO_API_KEY"]}
def upsert_consented_contact(source_id, email, first_name, list_id, consent):
if not consent:
raise ValueError("No marketing consent in the source")
if not source_id or not isinstance(list_id, int):
raise ValueError("Stable source ID and numeric list ID required")
# Configure FNAME in Brevo before using this explicit field mapping.
response = requests.post(
f"{BASE}/contacts",
headers=HEADERS,
json={
"email": email,
"ext_id": source_id,
"attributes": {"FNAME": first_name},
"listIds": [list_id],
"updateEnabled": True,
"getId": True,
},
timeout=30,
)
response.raise_for_status()
return response.json().get("id") if response.content else None

قد يعيد التحديث الناجح ردًا فارغًا 204. عندئذ تعني None أن عليك قراءة جهة الاتصال مرة أخرى للحصول على المعرّف.

يفترض المثال أن المستدعي تحقق من الموافقة والحظر في Brevo مسبقًا. لا يطلب رفع الحظر. يكتب المفتاح الحقيقي إلى الحساب؛ اختبر أولًا بردود وهمية. قد يعيد تعارض المعرّفات رموز 4xx مختلفة. اقرأ الرد وطابق المعرّفات بدل افتراض 409 دائمًا.

الـ webhooks

الـ webhooks هي وسيلتك لمعرفة ما حدث بعد الإرسال. ينشئ POST /v3/webhooks واحدًا، مع url و events و type، واختياريًا channel (email أو sms)، و batched، وترويسات headers مخصّصة، وكائن auth.

هناك ثلاثة أنواع من الـ webhooks بمفردات أحداث مختلفة:

  • معاملاتي: sent، request، delivered، hardBounce، softBounce، blocked، spam، invalid، deferred، click، opened، uniqueOpened، unsubscribed.
  • تسويقي: spam، opened، click، hardBounce، softBounce، unsubscribed، listAddition، delivered، contactUpdated، contactDeleted.
  • وارد: inboundEmailProcessed و reply، وهما يتطلبان إضافة domain.
Terminal window
curl -X POST https://api.brevo.com/v3/webhooks \
-H "api-key: $BREVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.example/hooks/brevo",
"type": "transactional",
"events": ["delivered", "hardBounce", "spam", "unsubscribed"],
"description": "Deliverability signals"
}'

لتغييرات جهات الاتصال، سجل webhook تسويقيًا يتضمن contactUpdated. يسمي Brevo الحدث داخل الحمولة contact_updated. وثق المستقبِل برمز bearer من auth أو بترويسات مخصصة وفق دليل الأمان. تحقق من السر قبل المعالجة ولا تسجله.

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

حدود المعدل ومعالجة الأخطاء

حدود المعدل في Brevo محدَّدة لكل نقطة نهاية ولكل مستوى خطّة، والفارق بين نقاط النهاية هائل.

نقطة النهايةGeneral (كل الخطط)Advanced (Professional و Enterprise)
POST /v3/smtp/email1,000 طلب في الثانية2,000 طلب في الثانية
POST /v3/transactionalSMS/send150 طلبًا في الثانية200 طلب في الثانية
/v3/contacts/...10 في الثانية، 36,000 في الساعة20 في الثانية، 72,000 في الساعة
POST /v3/events10 في الثانية، 36,000 في الساعة20 في الثانية، 72,000 في الساعة
GET /v3/smtp/emails2 في الثانية، 7,200 في الساعة3 في الثانية، 10,800 في الساعة
نقاط النهاية التي ليس لها حد خاص بها100 في الساعة200 في الساعة

يوثق Brevo ترويسات x-sib-ratelimit-limit وx-sib-ratelimit-remaining وx-sib-ratelimit-reset لنقاط النهاية المحدودة. اقرأها حتى في الردود الناجحة. بعد 429 انتظر إعادة الضبط، ثم أعد المحاولة ضمن حد ثابت للوقت والمحاولات. قيمة reset مدة بوحدة نافذة الحد، وغالبًا بالثواني، وليست وقت Unix.

async function callBrevo(path, init) {
for (let attempt = 0; attempt < 3; attempt++) {
const response = await fetch(`https://api.brevo.com/v3${path}`, {
...init,
headers: { "api-key": process.env.BREVO_API_KEY, ...init.headers },
});
if (response.status !== 429 || attempt === 2) return response;
const raw = Number(response.headers.get("x-sib-ratelimit-reset"));
const seconds = Number.isFinite(raw) && raw > 0 ? raw : 2 ** attempt;
const delayMs = (seconds + 2 ** attempt) * 1000;
if (delayMs > 60_000) return response;
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}

إذا تجاوز الانتظار المطلوب 60 ثانية، تعيد الدالة 429. حدد محاولة جديدة لاحقًا.

استخدم الدالة المساعدة فقط للطلبات التي تأكدت أن تكرارها آمن. بعد فشل إرسال ملتبس، طابق معرّف رسالتك قبل الإرسال مرة أخرى. سجل الحالة وترويسات الحد، لا المفتاح أو بيانات الاتصال.

لا تكرر كل 4xx دون فحص. يذكر مرجع إنشاء جهة اتصال 400 و425؛ ولا يلزم أن يكون التعارض 409. بعد 5xx في الكتابة، تحقق هل طُبق التغيير بالفعل.

ما الحالة التي عادت؟

  1. 429

    انتظر ضمن الحد

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

  2. 5xx بعد الكتابة

    تحقق من النتيجة

    قد يكون الخادم كتب قبل الخطأ.

  3. 400

    صحح الطلب

    غالبًا المدخل غير صالح.

  4. تعارض المعرّف

    طابق المعرّفات

    لا تضمن الواجهة رمزًا واحدًا للتعارض.

الاختبار دون إرسال بريد

أضف الترويسة X-Sib-Sandbox بالقيمة drop إلى طلب إرسال معاملاتي. تتحقق Brevo من صحة الطلب، وتعيد 201 مع messageId، ولا تسلّم شيئًا، ولا تكتب أي سجل بريد.

Terminal window
curl -X POST https://api.brevo.com/v3/smtp/email \
-H "api-key: $BREVO_API_KEY" \
-H "X-Sib-Sandbox: drop" \
-H "Content-Type: application/json" \
-d '{ "sender": { "email": "[email protected]" }, "to": [{ "email": "[email protected]" }], "subject": "Sandbox", "htmlContent": "<p>hi</p>" }'

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

تحقق قبل مزامنة جهات الاتصال

  • اختر معرّف مصدر ثابتًا لـ ext_id واحفظ معرّف Brevo.
  • عرّف السمات قبل الكتابة ثم أعد قراءة جهة الاتصال التجريبية.
  • استخدم قائمة محددة ودليل موافقة موثوقًا؛ تجاوز المحظورين والملغين لاشتراكهم.
  • احسب الكتابات المقبولة والمطبقة والمتجاوزة والفاشلة منفصلة. يعني 202 أولًا قبول الطلب فقط.
  • وثق webhooks التسويقية، وأزل التكرار وطابق الحالة.
  • راقب ترويسات الحد وتوقف بعد محاولات محددة.

يزامن Tajo بيانات التجارة مع Brevo. إذا بنيت هذا المسار بنفسك فراجع دليل الموصلات.

الأسئلة المتكررة

ما هو عنوان القاعدة لواجهة Brevo API؟

كل استدعاءات REST في Brevo تذهب إلى https://api.brevo.com/v3/. رقم الإصدار جزء من المسار، و v3 هو الجيل الحالي، لذا فإن نقطة نهاية مثل الإرسال المعاملاتي تكون بالمسار الكامل https://api.brevo.com/v3/smtp/email.

كيف تتم المصادقة مع واجهة Brevo API؟

أرسل مفتاحك في ترويسة HTTP اسمها api-key. لا تستخدم Brevo ترويسة Authorization أو Bearer لمفاتيح API القياسية. تُنشَأ المفاتيح ضمن إعدادات الحساب، ثم SMTP and API، ثم API keys، وتُعرض القيمة مرة واحدة فقط.

ما هي حدود المعدل في واجهة Brevo API؟

الحدود محدَّدة لكل نقطة نهاية ولكل مستوى من مستويات حدود المعدل. في المستوى العام، الذي تحصل عليه كل الخطط، تسمح نقطة نهاية الإرسال المعاملاتي بـ 1,000 طلب في الثانية، وتسمح نقاط نهاية جهات الاتصال بـ 10 في الثانية، أما نقاط النهاية التي ليس لها حد خاص بها فمحدودة بـ 100 طلب في الساعة. يمكن لخطّتَي Professional و Enterprise استخدام المستوى المتقدم (Advanced)، ولخطة Enterprise المستوى الموسّع (Extended). تجاوز الحد يعيد 429.

هل لدى Brevo حزم SDK رسمية؟

نعم. تنشر Brevo عملاء برمجيين للغات Node.js و Python و PHP و Java و C# و Go و Ruby ضمن منظمة getbrevo على GitHub. حزمة Node هي @getbrevo/brevo على npm، وحزمة Python هي brevo-python على PyPI.

كيف أختبر واجهة Brevo API دون إرسال بريد حقيقي؟

أضف الترويسة X-Sib-Sandbox بالقيمة drop إلى طلب إرسال معاملاتي. تتحقق Brevo من صحة الطلب، وتعيد 201 مع messageId، ولا ترسل شيئًا، ولا تكتب أي سجل بريد. هذا يفحص صيغة الطلب فقط، لا قابلية التسليم.

ما أحداث الـ webhook التي تدعمها Brevo؟

تغطي webhooks الخاصة بالرسائل المعاملاتية التسليم والارتداد وإلغاء الاشتراك. تتضمن webhooks التسويقية contactUpdated وcontactDeleted. يوثق Brevo الحدث inboundEmailProcessed للبريد الوارد.

كيف يحافظ تحديث جهة الاتصال على إلغاء الاشتراك السابق؟

استخدم معرّف مصدر ثابتًا وسمات معرّفة. لا ترسل emailBlacklisted: false في التحديث المعتاد. تحقق من جهة الاتصال ومصدر الموافقة قبل إضافتها إلى قائمة تسويقية.

هل يكفي webhook للمزامنة ثنائية الاتجاه؟

لا. تحقق من هوية المستقبِل، وأزل التسليمات المكررة، وطابق الأحداث المفقودة أو غير المرتبة مع مصدر موثوق. يشير webhook إلى تغيير، ولا يثبت تطابق حالة النظامين.

اطلب الوصول المبكر

أدخل اسمك الأول وعنوان بريدك الإلكتروني للعمل. سنرسل إليك رابطًا لتأكيد طلب الوصول إلى Tajo.

احصل على Brevo