API والمطورون

مرجع API

تشرح هذه الصفحة كل نقاط النهاية (Endpoints) في API منصة ربط CRM، والصلاحيات التي يحتاجها كل منها، والأخطاء التي قد يعيدها. العنوان الأساسي هو https://rabtcrm.com/api/v1، والطلبات والاستجابات بصيغة JSON.

العقد نفسه منشور كمستند OpenAPI 3.1 على GET /api/v1/openapi.json.

في هذه الصفحة: المصادقة · الصلاحيات · الأخطاء · تقسيم النتائج إلى صفحات · حدود الطلبات · منع التكرار (Idempotency) · الفرق الموقوفة وميزات الباقة · التوافق · وكلاء الذكاء الاصطناعي (MCP) · نقاط النهاية


المصادقة

أرسل مفتاح API في ترويسة Authorization مع كل طلب:

Authorization: Bearer YOUR_API_KEY_HERE

أنشئ المفاتيح من الإعدادات ← المطورون (راجع المصادقة عبر API). الأمثلة في هذه الصفحة تقرأ المفتاح من متغير بيئة:

export RABT_API_KEY="YOUR_API_KEY_HERE"
  • كل نقاط النهاية ما عدا POST /api/v1/send تقبل مفتاح API فقط. جلسة الدخول إلى لوحة التحكم غير مقبولة، والطلب بدون الترويسة يعيد 401 invalid_api_key.
  • POST /api/v1/send تقبل مفتاح API يملك صلاحية messages:send، أو جلسة لوحة التحكم إذا لم تُرسل ترويسة Authorization.
  • مفتاح API يعمل باسم الفريق كله، ويرى ما يراه مالك الفريق.

الصلاحيات

لكل مفتاح قائمة صلاحيات (Scopes). لا تعمل نقطة النهاية إلا إذا كان المفتاح يملك الصلاحية التي تحتاجها، وإلا تعيد 403 insufficient_scope مع اسم الصلاحية الناقصة في details.requiredScope.

الصلاحيةما تسمح به
instances:readinstances.list، instances.get
contacts:readtags.list، customFields.list، contacts.list، contacts.get
contacts:writecontacts.update، contacts.import
chats:readchats.list
messages:readmessages.list
messages:sendmessages.send، templates.list
automations:readautomations.list، automations.get
automations:writeautomations.enable، automations.disable
ai_agents:readaiAgents.list، aiAgents.get
ai_agents:writeaiAgents.update

me.get لا تحتاج أي صلاحية: يستطيع أي مفتاح صالح استدعاءها.

  • الصلاحيات لا تشمل بعضها. صلاحية :write لا تتضمن صلاحية :read المقابلة لها، وchats:read لا تتضمن messages:read. امنح المفتاح كل صلاحية يحتاجها.
  • المفاتيح التي أُنشئت قبل نظام الصلاحيات تملك messages:send فقط، وتظهر في قائمة المفاتيح باسم إرسال فقط (مفتاح قديم).
  • الاختيارات الجاهزة: قراءة فقط تختار صلاحيات :read الست، ووصول كامل تختار الصلاحيات العشر كلها.

ضبط الصلاحيات

  1. انتقل إلى الإعدادات ← المطورون.
  2. عند إنشاء مفتاح (إنشاء مفتاح جديد) اختر صلاحياته في قسم الصلاحيات: حدّدها واحدة واحدة، أو استخدم قراءة فقط أو وصول كامل. يجب أن يملك المفتاح صلاحية واحدة على الأقل.
  3. لتغيير مفتاح موجود اضغط تعديل الصلاحيات بجانبه، واختر الصلاحيات، ثم اضغط حفظ. يسري التغيير من الطلب التالي للمفتاح، ويعمل هذا مع المفاتيح القديمة أيضًا.

الأخطاء

كل نقاط النهاية ما عدا POST /api/v1/send وopenapi.json العامة تعيد الأخطاء بهذا الشكل:

{
  "error": {
    "code": "insufficient_scope",
    "message": "This API key needs the contacts:read scope.",
    "details": { "requiredScope": "contacts:read" }
  },
  "requestId": "6f1c2a9e-3b7d-4c55-9a0e-2f8b1d4e7c10"
}
  • code ثابت لا يتغير، فاعتمد عليه في الكود. message نص للقراءة وقد يتغير.
  • details يظهر مع بعض الرموز فقط.
  • كل استجابة من هذه النقاط، ناجحة أو خاطئة، تحمل ترويسة X-Request-Id، وفي حالة الخطأ تكون بنفس قيمة requestId. أرفقها عند التواصل مع الدعم.
الحالةالرمزالمعنى
400validation_failedمعامل في المسار أو الاستعلام أو حقل في الجسم غير صالح. إن وُجد details.issues فهو يذكر path وcode لكل خطأ (ولا يعيد القيمة التي أرسلتها).
400invalid_jsonالجسم ليس JSON صالحًا.
400invalid_referenceمعرّف في الطلب يشير إلى شيء لا يملكه فريقك. إن وُجد details.field فهو يذكر اسم الحقل.
400invalid_idempotency_keyترويسة Idempotency-Key ليست من 1 إلى 255 حرف ASCII قابل للطباعة.
401invalid_api_keyالمفتاح مفقود أو بصيغة خاطئة أو غير موجود.
402team_suspendedالفريق موقوف. عمليات الكتابة مرفوضة، والقراءة تعمل.
403insufficient_scopeالمفتاح لا يملك الصلاحية المذكورة في details.requiredScope.
403feature_not_enabledباقتك لا تتضمن الميزة المذكورة في details.feature.
403contact_limit_reachedcontacts.import ستنشئ جهات اتصال أكثر مما تسمح به باقتك.
404not_foundالمعرّف غير موجود في فريقك. معرّفات الفرق الأخرى تعيد 404 أيضًا.
409idempotency_conflictطلب يحمل نفس Idempotency-Key ما زال قيد التنفيذ.
409import_in_progressعملية استيراد أخرى عبر API لفريقك ما زالت قيد التنفيذ.
409custom_fields_changedحقل مخصص حُذف أو تغيّر أثناء تنفيذ الطلب. لم يُحفظ شيء.
409agent_uses_prompt_blocksتعليمات وكيل الذكاء الاصطناعي يبنيها معالج الإعداد، فلا يمكن تعديل systemPrompt عبر API.
415unsupported_media_typeنقطة النهاية تأخذ جسمًا بصيغة JSON وContent-Type ليس application/json.
422idempotency_key_reusedهذا الـ Idempotency-Key استُخدم من قبل مع طلب مختلف.
422invalid_custom_valueقيمة حقل مخصص لا تناسب نوع الحقل.
429rate_limitedطلبات كثيرة. انتظر عدد الثواني المذكور في Retry-After.
500internal_errorحدث خطأ من جهتنا.

كل نقطة نهاية قد تعيد 401 invalid_api_key و429 rate_limited و500 internal_error، وكل نقطة تحتاج صلاحية قد تعيد أيضًا 403 insufficient_scope. أقسام نقاط النهاية أدناه تذكر الرموز الأخرى فقط.

تُفحص الطلبات بهذا الترتيب، ويعود إليك أول فحص يفشل: مفتاح API ← الصلاحية ← حد الطلبات ← الفريق الموقوف (للكتابة) ← ميزة الباقة ← معاملات المسار والاستعلام ← Content-Type ← صحة JSON ← حقول الجسم.

POST /api/v1/send تستخدم شكلًا مختلفًا للأخطاء: { "error": "<message>" }، أو { "error": "<message>", "code": "<code>" } عندما يوجد رمز ثابت. راجع messages.send.


تقسيم النتائج إلى صفحات

القوائم تعيد { "data": [...], "nextCursor": ... }.

contacts.list وchats.list وmessages.list مقسّمة إلى صفحات:

معامل الاستعلامالقاعدة
limitعدد العناصر في الصفحة، من 1 إلى 100. الافتراضي 50.
cursorقيمة nextCursor من الصفحة السابقة.
  • nextCursor تكون null في الصفحة الأخيرة.
  • قيمة المؤشر (Cursor) داخلية لا تُقرأ. أعدها كما هي ومعها نفس الفلاتر. المؤشر الذي لا يستطيع الخادم قراءته يعيد 400 validation_failed.

القوائم الصغيرة (instances.list، tags.list، customFields.list، automations.list، aiAgents.list، templates.list) لا تأخذ معاملات صفحات. تعيد حتى 500 عنصر، وnextCursor فيها دائمًا null.

الصفحة الأولى، ثم الصفحة التالية مع nextCursor من الاستجابة السابقة:

curl "https://rabtcrm.com/api/v1/contacts?limit=100" \
  -H "Authorization: Bearer $RABT_API_KEY"

curl "https://rabtcrm.com/api/v1/contacts?limit=100&cursor=NEXT_CURSOR_VALUE" \
  -H "Authorization: Bearer $RABT_API_KEY"

حدود الطلبات

تُحسب الحدود لكل مفتاح API، في نوافذ مدتها 60 ثانية:

الطلباتالحد
القراءة (GET)120 في الدقيقة
الكتابة (POST، PATCH)60 في الدقيقة
contacts.import6 في الدقيقة، إضافة إلى حد الكتابة

كل استجابة من كل نقاط النهاية ما عدا /send و/openapi.json تحمل:

الترويسةالمعنى
X-RateLimit-Limitعدد الطلبات المسموح بها في النافذة الحالية
X-RateLimit-Remainingعدد الطلبات المتبقية في النافذة الحالية
X-RateLimit-Resetوقت بداية النافذة التالية، بثواني Unix

عند تجاوز الحد تحصل على 429 rate_limited مع ترويسة Retry-After (عدد الثواني التي تنتظرها). في contacts.import تصف الترويسات حد الاستيراد، إلا إذا كان حد الكتابة هو الذي تجاوزته. استجابة 403 insufficient_scope لا تُحسب ضمن الحد.

محاولات المصادقة الفاشلة محدودة بـ 20 في الدقيقة لكل عنوان IP. لا يُحسب إلا الطلب الذي يرسل مفتاحًا غير موجود في Authorization: Bearer. المفتاح الصالح يُقبل دائمًا، حتى من عنوان IP تجاوز هذا الحد. بعد تجاوز الحد، المفتاح الخاطئ يحصل على 429 rate_limited مع Retry-After. في استجابة 401 وفي استجابة 429 هذه، تصف ترويسات X-RateLimit-* حد المصادقة الفاشلة.

POST /api/v1/send لا تستخدم حدود المفتاح المذكورة أعلاه:

  • حد الوسائط للفريق 5 في الدقيقة. يُحسب فيه كل طلب بصيغة multipart/form-data (يُفحص قبل قراءة الجسم)، وكل إرسال وسائط بصيغة JSON يُنزّل الخادم رابط mediaUrl الخاص به: في اتصالات واتساب من نوع WHATSAPP-BAILEYS وWHATSAPP-BUSINESS، وفي ماسنجر وإنستغرام. أما mediaUrl في اتصال WhatsApp Cloud API (META-CLOUD) فيُمرَّر إلى Meta ولا يُحسب، ولا يُحسب أيضًا رابط ترويسة القالب. عند تجاوز الحد تحصل على 429 مع Retry-After وX-RateLimit-*. هذه هي الاستجابة الوحيدة من /send التي تحمل X-RateLimit-*.
  • استجابة 429 من المزوّد نفسه (رفض الإرسال لكثرة الطلبات) تُعاد كما هي بدون Retry-After. انتظر قليلًا قبل إعادة المحاولة.
  • حد المصادقة الفاشلة يسري هنا أيضًا، واستجابة 429 الخاصة به تحمل Retry-After فقط.
  • ترويسة X-Request-Id لا تُرسل إلا عند الاستدعاء بمفتاح API مع ترويسة Idempotency-Key.

منع التكرار (Idempotency)

POST /api/v1/send وPOST /api/v1/contacts/import تقبلان ترويسة Idempotency-Key. بها لا تُرسل الرسالة مرتين ولا يتكرر الاستيراد إذا أعدت الطلب بعد خطأ في الشبكة.

Idempotency-Key: order-1042-confirmation
  • المفتاح من 1 إلى 255 حرف ASCII قابل للطباعة. غير ذلك يعيد 400 invalid_idempotency_key.
  • المفتاح فريد على مستوى الفريق، عبر كل مفاتيح API للفريق وعبر نقطتي النهاية معًا.
  • في /send لا تُستخدم الترويسة إلا عند الاستدعاء بمفتاح API. الاستدعاء بجلسة لوحة التحكم يتجاهلها.
  • لا يُسجَّل المفتاح إلا بعد نجاح المصادقة والصلاحية وحد الطلبات وفحص الطلب. الطلب الذي يفشل في هذه الفحوص لا يُحفظ، ويمكنك إرساله مرة أخرى بنفس المفتاح. في contacts.import يشمل هذا أيضًا instanceId غير المعروف و409 import_in_progress. وفي /send يقصد بفحص الطلب فحص حقول الجسم وقواعد الجمع بين الحقول فقط: أي رفض بعد ذلك (مثل اتصال غير موجود، أو إرسال text بدون message) يُعدّ نتيجة ويُحفظ، ما عدا 422 outside_service_window و422 recipient_ambiguous (أدناه).

ماذا يحدث إذا أرسلت نفس المفتاح مرة أخرى:

الحالةالاستجابة
نفس الطلب (نفس نقطة النهاية ونفس الجسم، وفي /send بصيغة multipart نفس الملف أيضًا)الحالة والجسم المحفوظان، مع Idempotent-Replayed: true وX-Request-Id الأصلي. لا يُنفَّذ شيء من جديد.
طلب مختلف422 idempotency_key_reused
الطلب الأول ما زال قيد التنفيذ409 idempotency_conflict

كل نتيجة نهائية لمدة 24 ساعة، بما فيها الأخطاء، مع خمسة استثناءات. أول استجابة لكل مفتاح (نجاح أو 4xx أو 5xx) تُحفظ وتُعاد كما هي لمدة 24 ساعة. استجابة 504 من /send تعني أن المزوّد تأخر في الرد، وقد تكون الرسالة وصلت فعلًا؛ إعادة نفس المفتاح تعيد نفس 504 ولا ترسل الرسالة مرة أخرى.

حالات الرفض الخمس التالية تحدث قبل إرسال أي شيء أو كتابته، لذلك لا تُحفظ. أعد المحاولة بنفس المفتاح بعد زوال السبب:

  • 429 الخاص بحد الوسائط للفريق في طلب /send بصيغة JSON يُنزّل الخادم رابط mediaUrl الخاص به. انتظر عدد الثواني في Retry-After.
  • 402 لفريق موقوف بالفعل عند وصول الطلب، في أي رسالة عبر /send: كل أنواع الاتصالات، والقوالب، والمستلمون في Messenger أو Instagram. وإذا بدأ الإيقاف أثناء تنفيذ الإرسال، فرسائل META-CLOUD والقوالب (في META-CLOUD وWHATSAPP-BUSINESS) ورسائل Messenger أو Instagram تعيد 402 يُحفظ مثل أي نتيجة أخرى، أما الرسائل النصية والوسائط عبر اتصال WHATSAPP-BAILEYS أو WHATSAPP-BUSINESS فلا تُفحص مرة أخرى وتُرسل.
  • 422 outside_service_window في رسالة حرة عبر واتساب في /send: أعد المحاولة بنفس المفتاح بعد أن يراسلك العميل، أو أرسل قالبًا.
  • 422 recipient_ambiguous في رسالة حرة عبر واتساب في /send: أرسل إلى رقم الهاتف الحالي للعميل، أو أرسل قالبًا.
  • 403 contact_limit_reached في الاستيراد.

وحد الوسائط عند رفع ملف بصيغة multipart يُفحص قبل تسجيل المفتاح، لذلك لا يُحفظ هو أيضًا.

لإعادة المحاولة عن قصد استخدم مفتاحًا جديدًا. إذا لم يتمكن الخادم من حفظ النتيجة، يبقى المفتاح يعيد 409 حتى تنتهي صلاحيته. بعد 24 ساعة يمكن استخدام المفتاح من جديد.


الفرق الموقوفة وميزات الباقة

  • الفريق الموقوف: كل عملية كتابة (POST وPATCH) تعيد 402 team_suspended، والقراءة تعمل. أما POST /api/v1/send فتعيد 402 بشكلها الخاص عندما يكون الفريق موقوفًا أو عند الوصول إلى حد التخزين. وفي /send يُفحص الإيقاف بعد التحقق من جسم الطلب وقبل البحث عن الاتصال أو القناة.
  • ميزات الباقة: بعض عمليات الكتابة تحتاج ميزة في باقتك، وبدونها تعيد 403 feature_not_enabled مع اسم الميزة في details.feature:
نقطة النهايةتحتاج
automations.enable، automations.disableميزة منشئ التدفقات (isFlowBuilderEnabled)
aiAgents.updateميزة الذكاء الاصطناعي (isAiEnabled)

قراءة الأتمتة ووكلاء الذكاء الاصطناعي لا تحتاج هذه الميزات.


التوافق

  • التغييرات التي تضيف ولا تكسر تصدر ضمن v1 بدون إشعار مسبق: نقاط نهاية جديدة، وحقول طلب اختيارية جديدة، وحقول استجابة جديدة، ورموز أخطاء جديدة، وقيم جديدة في القوائم المحددة (enum). يجب أن يتجاهل تطبيقك حقول الاستجابة ورموز الأخطاء والقيم التي لا يعرفها.
  • /send ونافذة واتساب (24 ساعة): كان /send يرد بـ 200 على رسالة حرة إلى عميل META-CLOUD أو WHATSAPP-BUSINESS خارج نافذة الـ 24 ساعة، ثم تفشل الرسالة. الآن يرد بـ 422 outside_service_window ولا يرسل شيئًا. اعتمد على code وليس على رمز الحالة وحده: 422 تعني أيضًا idempotency_key_reused أو recipient_ambiguous.
  • التغيير الذي يكسر التوافق يصدر في إصدار مسار جديد (/api/v2/...) ويُعلن عنه مسبقًا. وتُرسل نقطة النهاية القديمة في v1 بعدها ترويستي Deprecation وSunset حتى تُزال.

استخدام API من وكلاء الذكاء الاصطناعي (MCP)

تشغّل منصة ربط CRM خادم MCP (Model Context Protocol) عن بُعد، فيستطيع وكيل ذكاء اصطناعي مثل Claude Code استدعاء هذا الـ API كأدوات (Tools).

  • نقطة النهاية: https://rabtcrm.com/api/mcp، بنقل Streamable HTTP (استجابات JSON، بدون جلسات). إصدارات البروتوكول 2025-11-25 و2025-06-18. الأدوات فقط.
  • المصادقة: مفاتيح API نفسها الخاصة بالفريق، التي تُنشأ من الإعدادات ← المطورون، وتُرسل في كل طلب بالشكل Authorization: Bearer YOUR_API_KEY_HERE. الطلب بدون الترويسة أو بمفتاح غير صالح يعيد 401، وبعد 20 محاولة فاشلة في الدقيقة من عنوان IP واحد يعيد 429 مع Retry-After (راجع حدود الطلبات).

Claude Code:

claude mcp add --transport http rabtcrm https://rabtcrm.com/api/mcp \
  --header "Authorization: Bearer $RABT_API_KEY"

بعدها شغّل /mcp داخل Claude Code لترى أدوات ربط CRM.

عملاء MCP الآخرون يعملون إذا كانوا يستطيعون إرسال ترويسة Authorization مخصصة ولا يرسلون ترويسة Origin. الطلب الذي يحمل ترويسة Origin من موقع آخر يعيد 403، لذلك لا يمكن لعملاء MCP الذين يعملون داخل صفحة ويب الاتصال. الإعدادات التالية لم تُختبر:

Cursor (.cursor/mcp.json)، لم يُختبر:

{
  "mcpServers": {
    "rabtcrm": {
      "url": "https://rabtcrm.com/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY_HERE" }
    }
  }
}

VS Code (.vscode/mcp.json)، لم يُختبر:

{
  "servers": {
    "rabtcrm": {
      "type": "http",
      "url": "https://rabtcrm.com/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY_HERE" }
    }
  }
}

كلا الملفين يحتوي مفتاح API: لا تضفهما إلى نظام إدارة الإصدارات (أضفهما إلى .gitignore، أو ضع الخادم في إعدادات العميل على مستوى المستخدم بدل مجلد المشروع).

غير مدعوم بعد: الموصلات المخصصة (Custom connectors) في claude.ai وClaude Desktop، وموصلات ChatGPT. هذه لا تستطيع إرسال مفتاح API، وتحتاج OAuth الذي سيأتي في إصدار لاحق.

الأدوات

  • كل عملية في نقاط النهاية، ما عدا openapi.json، أداة واحدة. اسم الأداة هو اسم العملية مع استبدال . بـ _: me_get وcontacts_list وcontacts_update وaiAgents_update وهكذا. ومعاملاتها هي معاملات المسار ومعاملات الاستعلام وحقول الجسم الخاصة بنقطة النهاية، في كائن واحد.
  • messages_send ترسل رسالة عبر messages.send، وتحتاج صلاحية messages:send. الوسائط تعمل كرابط فقط (mediaUrl)، ورفع الملفات غير متاح عبر MCP.
  • templates_list تعرض القوالب التي يمكن إرسالها عبر messages_send (نفس الصلاحية messages:send). خارج نافذة واتساب (24 ساعة) تعيد messages_send الرمز outside_service_window، وعندها يرسل الوكيل أحد هذه القوالب.
  • صلاحيات المفتاح تحدد الأدوات التي يراها الوكيل. me_get تظهر دائمًا، وكل أداة أخرى لا تظهر إلا إذا كان المفتاح يملك صلاحيتها (راجع الصلاحيات). للتحليل استخدم مفتاحًا بالاختيار الجاهز قراءة فقط: لا يملك أدوات كتابة أو إرسال.
  • استدعاء الأداة الذي يفشل يعود كنتيجة أداة معلَّمة كخطأ، بجسم الخطأ الذي تعيده نقطة النهاية (راجع الأخطاء). أما الطلبات المرفوضة قبل تشغيل أي أداة فتعود كأخطاء JSON-RPC: أداة غير معروفة أو قيمة arguments ليست كائنًا (-32602)، وطلب غير صالح البنية (-32600)، وأخطاء HTTP المذكورة أعلاه (401 و403 و429) وأدناه (413). في messages_send يعود أي 5xx كرسالة ثابتة قصيرة بدون تفاصيل المزوّد. بعد أي 5xx ربما تكون الرسالة قد وصلت: لا تُعِد إرسالها دون تحقق، وراجع المحادثة أو اسأل المستخدم أولًا. الاستدعاء مرة أخرى بنفس idempotencyKey خلال 24 ساعة لا يرسل من جديد (يعيد النتيجة المحفوظة)، أما مفتاح جديد أو عدم إرسال مفتاح فقد يرسل رسالة مكررة.

التأكيد قبل الكتابة والإرسال

أدوات الكتابة والإرسال (contacts_update وcontacts_import وautomations_enable وautomations_disable وaiAgents_update وmessages_send) معلَّمة كأدوات مُغيِّرة (Destructive). سؤالك قبل تنفيذها يعتمد على إعدادات الموافقة في العميل الذي تستخدمه. منصة ربط CRM لا تفرض أي تأكيد في هذا الإصدار. فعّل الموافقة في العميل لأدوات الكتابة والإرسال، ولا تضفها إلى قائمة الموافقة التلقائية.

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

الحدود ومنع التكرار وسجل النشاط

  • استدعاءات الأدوات تخضع لنفس الصلاحيات وحدود الطلبات والفحوص التي تخضع لها نقاط نهاية REST، وتتشارك ميزانيات المفتاح: كل استدعاء أداة يُحسب ضمن حد القراءة أو الكتابة نفسه للمفتاح الذي يُحسب فيه طلب REST المقابل (راجع حدود الطلبات). messages_send تُحسب ضمن حد الكتابة للمفتاح. أما عرض قائمة الأدوات وبدء الاتصال فلهما حد خاص: 120 في الدقيقة لكل مفتاح.
  • حجم جسم طلب MCP محدود بـ 1 ميغابايت (1,048,576 بايت)، والطلب الأكبر يعيد HTTP 413 قبل تنفيذ أي شيء. قسّم دفعات contacts_import الكبيرة.
  • messages_send وcontacts_import تقبلان معاملًا اختياريًا idempotencyKey يُرسل كترويسة Idempotency-Key (راجع منع التكرار). أعد استخدام القيمة نفسها فقط عند إعادة محاولة الاستدعاء نفسه تمامًا. نتيجة الطلب الذي يحمل مفتاحًا تُحفظ لمدة 24 ساعة وتُعاد كما هي لنفس المفتاح.
  • عمليات الكتابة الناجحة تظهر في الإعدادات ← النشاط "عبر مفتاح API" مع اسم المفتاح، مثل الكتابة عبر REST. سجل الاستيراد الملخّص يُكتب بعد حفظ جهات الاتصال: إذا فشلت كتابته يبقى الاستيراد ناجحًا. عمليات الإرسال لا تظهر هناك.

نقاط النهاية

العمليةالطريقة والمسارالصلاحية
me.getGET /meلا شيء
instances.listGET /instancesinstances:read
instances.getGET /instances/{id}instances:read
tags.listGET /tagscontacts:read
customFields.listGET /custom-fieldscontacts:read
contacts.listGET /contactscontacts:read
contacts.getGET /contacts/{id}contacts:read
contacts.updatePATCH /contacts/{id}contacts:write
contacts.importPOST /contacts/importcontacts:write
chats.listGET /chatschats:read
messages.listGET /chats/{id}/messagesmessages:read
automations.listGET /automationsautomations:read
automations.getGET /automations/{id}automations:read
automations.enablePOST /automations/{id}/enableautomations:write
automations.disablePOST /automations/{id}/disableautomations:write
aiAgents.listGET /ai-agentsai_agents:read
aiAgents.getGET /ai-agents/{id}ai_agents:read
aiAgents.updatePATCH /ai-agents/{id}ai_agents:write
templates.listGET /templatesmessages:send
messages.sendPOST /sendmessages:send
openapi.jsonGET /openapi.jsonعامة، بدون مفتاح

المسارات نسبية إلى https://rabtcrm.com/api/v1. كل {id} رقم صحيح من 1 إلى 2147483647، وأي قيمة أخرى تعيد 400 validation_failed.


me.get

GET /api/v1/me · الصلاحية: لا شيء (أي مفتاح صالح)

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

الاستجابة

الحقلالنوعالوصف
team.idintegerمعرّف فريقك
team.namestringاسم فريقك
key.idintegerمعرّف المفتاح
key.namestringالاسم الذي أعطيته للمفتاح
key.scopesمصفوفة stringصلاحيات المفتاح. المفتاح القديم يظهر ["messages:send"].
curl https://rabtcrm.com/api/v1/me \
  -H "Authorization: Bearer $RABT_API_KEY"
{
  "team": { "id": 42, "name": "Acme Store" },
  "key": { "id": 7, "name": "Website", "scopes": ["contacts:read", "messages:send"] }
}

الأخطاء: الأخطاء العامة فقط (بدون 403).


instances.list

GET /api/v1/instances · الصلاحية: instances:read

تعرض اتصالات واتساب وقنوات ماسنجر وإنستغرام النشطة (ما يظهر في الاتصالات). اتصالات واتساب أولًا ثم القنوات، وكل منهما مرتب حسب المعرّف. حتى 500 عنصر في المجموع (بعد 500 تُترك القنوات الأخيرة)، وnextCursor دائمًا null.

الاستجابة: data تحتوي نوعين من العناصر، يميّز بينهما الحقل kind.

اتصال واتساب (kind: "whatsapp"):

الحقلالنوعالوصف
kindstring"whatsapp"
idintegerمعرّف الاتصال. يُستخدم في فلتر instanceId في chats.list، وفلتر instance في contacts.list، وفي contacts.import.
instanceNamestringأرسله في instanceName إلى messages.send.
displayNamestring أو nullالاسم المعروض للاتصال
integrationstringنوع الاتصال، مثل META-CLOUD
phoneNumberstring أو nullرقم الهاتف المتصل
lastConnectedAtstring (تاريخ ووقت) أو nullآخر وقت اتصل فيه. هذه ليست حالة الاتصال اللحظية.
createdAtstring (تاريخ ووقت)

قناة ماسنجر أو إنستغرام (kind: "channel"):

الحقلالنوعالوصف
kindstring"channel"
idintegerمعرّف القناة. عند الإرسال إلى عميل على ماسنجر أو إنستغرام، أرسله كنص في instanceName إلى messages.send.
channelTypestringFACEBOOK-MESSENGER أو INSTAGRAM-DM
displayNamestring أو nullالاسم المعروض للقناة
curl https://rabtcrm.com/api/v1/instances \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: الأخطاء العامة فقط.


instances.get

GET /api/v1/instances/{id} · الصلاحية: instances:read

تعيد اتصال واتساب واحدًا، بنفس حقول العنصر kind: "whatsapp" في instances.list. قنوات ماسنجر وإنستغرام متاحة في القائمة فقط.

معامل المسارالوصف
idمعرّف اتصال واتساب
curl https://rabtcrm.com/api/v1/instances/12 \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة id غير صالحة)، 404 not_found.


tags.list

GET /api/v1/tags · الصلاحية: contacts:read

تعرض وسوم جهات الاتصال مرتبة حسب المعرّف. حتى 500 عنصر، وnextCursor دائمًا null.

الحقلالنوعالوصف
idintegerمعرّف الوسم. يُستخدم في فلتر tag في contacts.list وفي tagIds في contacts.update.
namestring
colorstring أو null
curl https://rabtcrm.com/api/v1/tags \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: الأخطاء العامة فقط.


customFields.list

GET /api/v1/custom-fields · الصلاحية: contacts:read

تعرض الحقول المخصصة لجهات الاتصال مرتبة حسب المعرّف. حتى 500 عنصر، وnextCursor دائمًا null.

الحقلالنوعالوصف
idintegerمعرّف الحقل. contacts.update تأخذ القيم بهذا المعرّف.
namestringالاسم الظاهر في لوحة التحكم
keystringالمفتاح المستخدم في customData لجهة الاتصال وفي contacts.import
typestringنوع الحقل
curl https://rabtcrm.com/api/v1/custom-fields \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: الأخطاء العامة فقط.


contacts.list

GET /api/v1/contacts · الصلاحية: contacts:read

تعرض جهات الاتصال، الأحدث تعديلًا أولًا. مقسّمة إلى صفحات (راجع تقسيم النتائج إلى صفحات).

معامل الاستعلامالوصف
limitمن 1 إلى 100، الافتراضي 50
cursorقيمة nextCursor من الصفحة السابقة
searchنص يُبحث عنه في الاسم والهاتف واسم المستخدم
tagمعرّف وسم
stageمعرّف مرحلة في القمع، أو no_stage
agentمعرّف المستخدم المسؤول، أو unassigned
departmentمعرّف قسم، أو no_department
instanceمعرّف اتصال واتساب، أو no_instance

أي معامل استعلام آخر يعيد 400 validation_failed.

الاستجابة: data قائمة جهات اتصال:

الحقلالنوعالوصف
idintegerمعرّف جهة الاتصال
namestring
phonestring أو nullالجزء الذي يسبق @ في remoteJid: رقم الهاتف في واتساب، أو معرّف القناة (fb_...، ig_...، ...) في القنوات الأخرى. تكون null لجهة اتصال واتساب أخفت Meta رقمها، ولمحادثات دردشة الموقع.
remoteJidstring أو nullمعرّف محادثة جهة الاتصال: معرّف واتساب، أو معرّف قناة مثل fb_... (ماسنجر) أو ig_... (إنستغرام)
metaUsernamestring أو nullاسم مستخدم العميل على واتساب، إذا أرسلته Meta (WhatsApp Cloud API فقط)
instanceIdinteger أو nullاتصال واتساب الخاص بمحادثة جهة الاتصال
notesstring أو null
assignedUserIdinteger أو nullعضو الفريق المسؤول عن جهة الاتصال
assignedDepartmentIdinteger أو null
funnelStageIdinteger أو null
tagsمصفوفةكل وسم بالشكل { id, name, color }
customDataobjectقيم الحقول المخصصة، مفاتيحها هي key الخاص بكل حقل (راجع customFields.list)
createdAtstring (تاريخ ووقت)
updatedAtstring (تاريخ ووقت)
curl "https://rabtcrm.com/api/v1/contacts?limit=50&tag=12&stage=no_stage" \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة غير صالحة في limit أو cursor أو أحد الفلاتر، أو معامل استعلام غير معروف).


contacts.get

GET /api/v1/contacts/{id} · الصلاحية: contacts:read

تعيد جهة اتصال واحدة، بالحقول المذكورة في contacts.list.

معامل المسارالوصف
idمعرّف جهة الاتصال
curl https://rabtcrm.com/api/v1/contacts/1234 \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة id غير صالحة)، 404 not_found.


contacts.update

PATCH /api/v1/contacts/{id} · الصلاحية: contacts:write

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

حقل الجسمالنوعالقاعدة
namestringمن 1 إلى 100 حرف. لا يقبل null.
notesstring أو nullnull تمسح الملاحظات.
assignedUserIdinteger أو nullعضو في فريقك. null تلغي الإسناد.
assignedDepartmentIdinteger أو nullأحد أقسامك. null تمسحه.
funnelStageIdinteger أو nullإحدى مراحل القمع لديك. null تمسحها.
tagIdsمصفوفة integerحتى 500 معرّف وسم. تستبدل وسوم جهة الاتصال، و[] تحذفها كلها. كل معرّف يجب أن يكون من وسومك.
customFieldValuesobjectالمفاتيح هي معرّفات الحقول المخصصة كنص (من customFields.list)، والقيم string أو number أو boolean أو null. تتغير الحقول التي ترسلها فقط. null أو "" تمسح قيمة الحقل.

أنواع القيم: الحقل المنطقي (boolean) يقبل true وfalse و"true" و"false"، وباقي الحقول تقبل نصًا أو رقمًا. أي قيمة أخرى تعيد 422 invalid_custom_value.

الاستجابة: جهة الاتصال بعد التعديل، كما في contacts.list.

curl -X PATCH https://rabtcrm.com/api/v1/contacts/1234 \
  -H "Authorization: Bearer $RABT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "funnelStageId": 3,
    "tagIds": [12, 15],
    "customFieldValues": { "8": "Gold", "9": true }
  }'

الأخطاء: 400 validation_failed / invalid_json، 400 invalid_reference (مستخدم أو قسم أو مرحلة أو وسم أو حقل مخصص لا يملكه فريقك)، 402 team_suspended، 404 not_found، 409 custom_fields_changed، 415 unsupported_media_type، 422 invalid_custom_value.


contacts.import

POST /api/v1/contacts/import · الصلاحية: contacts:write · تقبل Idempotency-Key

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

حقل الجسمالنوعالقاعدة
instanceIdintegerاختياري. معرّف أحد اتصالات واتساب لديك. يُستخدم فقط للمحادثات التي ينشئها الاستيراد.
contactsمصفوفةمن 1 إلى 200 صف

كل صف (الحقول غير المعروفة مرفوضة):

الحقلالنوعالقاعدة
phonestringمطلوب، حتى 32 حرفًا
namestringمطلوب، حتى 255 حرفًا
notesstringحتى 10,000 حرف
stagestringاسم مرحلة في القمع (لا يفرّق بين الأحرف الكبيرة والصغيرة)، حتى 100 حرف
agentEmailstringبريد عضو في الفريق (لا يفرّق بين الأحرف الكبيرة والصغيرة)، حتى 255 حرفًا
departmentstringاسم قسم (لا يفرّق بين الأحرف الكبيرة والصغيرة)، حتى 100 حرف
tagsمصفوفة stringحتى 50 اسم وسم، كل اسم حتى 100 حرف. تُطابق الأسماء حرفيًا (مع التفريق بين الأحرف الكبيرة والصغيرة)، والوسوم غير الموجودة تُنشأ.
customDataobject50 مفتاحًا كحد أقصى. المفاتيح هي مفاتيح الحقول المخصصة (key، حتى 100 حرف)، والقيم نص (حتى 1,000 حرف) أو رقم أو قيمة منطقية.

كيف تُطبَّق الصفوف:

  • الصف الذي يطابق رقمه جهة اتصال موجودة يحدّثها: يُستبدل name، وتتغير notes وstage وagentEmail وdepartment فقط إذا أُرسلت وطابقت شيئًا، وتُدمج قيم الحقول المخصصة، وتُضاف الوسوم (الوسوم الحالية تبقى).
  • أي صف آخر ينشئ جهة اتصال جديدة.
  • قيمة stage أو agentEmail أو department التي لا تطابق شيئًا تُتجاهل. ومفتاح في customData ليس من حقولك المخصصة يُتجاهل. في الحقل المنطقي تعني القيم true و"true" و"yes" و"sim" و"1" القيمة true، وأي قيمة أخرى تعني false. وفي جهة اتصال موجودة، القيمة "" لحقل نصي تمسحه.
  • إذا تكرر نفس الرقم في الطلب يُستخدم الصف الأول، وتُحسب الصفوف التالية مكررة.
  • لا يعمل لكل فريق إلا استيراد واحد عبر API في الوقت نفسه. الاستيراد الثاني يعيد 409 import_in_progress.
  • قبل كتابة أي شيء يفحص الاستيراد باقتك: إذا كان سينشئ جهات اتصال أكثر مما تبقى في باقتك، يعيد 403 contact_limit_reached ولا يكتب شيئًا.
  • حد الطلبات: 6 عمليات استيراد في الدقيقة لكل مفتاح، إضافة إلى حد الكتابة.

الاستجابة

الحقلالنوعالوصف
importedintegerالصفوف التي أُنشئت أو حُدّثت
failedintegerالصفوف التي تعذّر استيرادها
duplicatesintegerالصفوف التي تُركت لأن رقمها ظهر قبلها في نفس الطلب
failuresمصفوفة{ row, reason } للصفوف الفاشلة والمكررة، 100 عنصر كحد أقصى

row هو ترتيب العنصر في contacts مضافًا إليه 2 (العنصر الأول هو الصف 2)، كما في استيراد ملف الجدول من لوحة التحكم حيث الصف 1 هو صف العناوين. reason واحدة من missing_name، missing_phone، invalid_phone، duplicate، save_error.

curl -X POST https://rabtcrm.com/api/v1/contacts/import \
  -H "Authorization: Bearer $RABT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: import-2026-11-09-batch-1" \
  -d '{
    "instanceId": 12,
    "contacts": [
      { "phone": "+201001234567", "name": "Sara Ali", "tags": ["VIP"], "customData": { "city": "Cairo" } },
      { "phone": "+966501234567", "name": "Omar Saleh", "stage": "Qualified" }
    ]
  }'
{ "imported": 2, "failed": 0, "duplicates": 0, "failures": [] }

الأخطاء: 400 validation_failed / invalid_json، 400 invalid_reference (instanceId)، 400 invalid_idempotency_key، 402 team_suspended، 403 contact_limit_reached، 409 import_in_progress، 409 idempotency_conflict، 415 unsupported_media_type، 422 idempotency_key_reused. راجع منع التكرار.


chats.list

GET /api/v1/chats · الصلاحية: chats:read

تعرض محادثات الرسائل المباشرة (بدون سلاسل التعليقات)، صاحبة أحدث رسالة أولًا. المحادثات التي لا تحتوي رسائل لا تظهر. مقسّمة إلى صفحات (راجع تقسيم النتائج إلى صفحات).

معامل الاستعلامالوصف
limitمن 1 إلى 100، الافتراضي 50
cursorقيمة nextCursor من الصفحة السابقة
instanceIdمحادثات اتصال واتساب هذا فقط

الاستجابة: data قائمة محادثات:

الحقلالنوعالوصف
idintegerمعرّف المحادثة. يُستخدم في messages.list.
namestring أو null
remoteJidstringمعرّف العميل: معرّف واتساب، أو معرّف قناة مثل fb_... (ماسنجر) أو ig_... (إنستغرام). في ماسنجر وإنستغرام أرسله في number إلى messages.send.
instanceIdinteger أو nullاتصال واتساب، لمحادثات واتساب
channelConnectionIdinteger أو nullالقناة المتصلة (ماسنجر، إنستغرام، تيليجرام، دردشة الموقع، ...)، للمحادثات من غير واتساب
unreadCountinteger
lastMessageAtstring (تاريخ ووقت)
curl "https://rabtcrm.com/api/v1/chats?limit=50&instanceId=12" \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة غير صالحة في limit أو cursor أو instanceId، أو معامل استعلام غير معروف)، 400 invalid_reference (instanceId ليس من اتصالاتك).


messages.list

GET /api/v1/chats/{id}/messages · الصلاحية: messages:read

تعرض رسائل محادثة واحدة، الأحدث أولًا. مقسّمة إلى صفحات (راجع تقسيم النتائج إلى صفحات).

المعاملالوصف
id (المسار)معرّف المحادثة من chats.list
limit (الاستعلام)من 1 إلى 100، الافتراضي 50
cursor (الاستعلام)قيمة nextCursor من الصفحة السابقة

الاستجابة: data قائمة رسائل:

الحقلالنوعالوصف
idstringمعرّف الرسالة لدى المزوّد (في واتساب: WAMID). فريد داخل محادثته فقط.
chatIdinteger
fromMebooleantrue إذا أرسلها طرفك
messageTypestring أو null
textstring أو null
mediaCaptionstring أو null
mediaUrlstring أو null
mediaMimetypestring أو null
statusstring أو nullحالة التسليم
timestampstring (تاريخ ووقت)
isInternalbooleantrue لملاحظة كتبها فريقك داخل المحادثة، ولم يرها العميل.
eventTypestring أو nullليست null عندما يكون الصف حدثًا من النظام سُجّل في المحادثة وليس رسالة. القيمة تذكر نوع الحدث.
isDeletedbooleantrue إذا حذف المرسل الرسالة

لإعادة بناء المحادثة كما رآها العميل، تجاهل الصفوف التي فيها isInternal تساوي true أو eventType ليست null.

curl "https://rabtcrm.com/api/v1/chats/5678/messages?limit=100" \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة غير صالحة في id أو limit أو cursor، أو معامل استعلام غير معروف)، 404 not_found.


automations.list

GET /api/v1/automations · الصلاحية: automations:read

تعرض أتمتة الرسائل لديك مرتبة حسب المعرّف. حتى 500 عنصر، وnextCursor دائمًا null. محتوى التدفق نفسه لا يُعاد.

الحقلالنوعالوصف
idintegerمعرّف الأتمتة
namestring
isActivebooleanهل الأتمتة مفعّلة
instanceIdinteger أو nullاتصال واتساب الذي تعمل عليه
channelConnectionIdinteger أو nullالقناة المتصلة (ماسنجر، إنستغرام، تيليجرام، ...) التي تعمل عليها
createdAtstring (تاريخ ووقت)
updatedAtstring (تاريخ ووقت)
curl https://rabtcrm.com/api/v1/automations \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: الأخطاء العامة فقط.


automations.get

GET /api/v1/automations/{id} · الصلاحية: automations:read

تعيد أتمتة رسائل واحدة، بالحقول المذكورة في automations.list.

curl https://rabtcrm.com/api/v1/automations/31 \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة id غير صالحة)، 404 not_found.


automations.enable

POST /api/v1/automations/{id}/enable · الصلاحية: automations:write · ميزة الباقة: منشئ التدفقات

تشغّل أتمتة رسائل. بدون جسم. تعيد الأتمتة كما في automations.list.

curl -X POST https://rabtcrm.com/api/v1/automations/31/enable \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة id غير صالحة)، 402 team_suspended، 403 feature_not_enabled، 404 not_found.


automations.disable

POST /api/v1/automations/{id}/disable · الصلاحية: automations:write · ميزة الباقة: منشئ التدفقات

توقف أتمتة رسائل. بدون جسم. تعيد الأتمتة كما في automations.list.

curl -X POST https://rabtcrm.com/api/v1/automations/31/disable \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة id غير صالحة)، 402 team_suspended، 403 feature_not_enabled، 404 not_found.


aiAgents.list

GET /api/v1/ai-agents · الصلاحية: ai_agents:read

تعرض وكلاء الذكاء الاصطناعي لديك مرتبين حسب المعرّف. حتى 500 عنصر، وnextCursor دائمًا null. بيانات الدخول إلى مزوّد الذكاء الاصطناعي لا تُعاد.

الحقلالنوعالوصف
idintegerمعرّف الوكيل
namestring
descriptionstring أو null
personastring أو null
isDefaultboolean
isActiveboolean
providerstringمزوّد الذكاء الاصطناعي
modelstringاسم النموذج
promptModestringmanual عندما تُكتب التعليمات مباشرة، وغير ذلك يعني أن معالج الإعداد يبني التعليمات
systemPromptstring أو null
temperaturenumber أو null
maxOutputTokensinteger أو null
ragEnabledbooleanهل البحث في قاعدة المعرفة مفعّل
createdAtstring (تاريخ ووقت) أو null
updatedAtstring (تاريخ ووقت) أو null
curl https://rabtcrm.com/api/v1/ai-agents \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: الأخطاء العامة فقط.


aiAgents.get

GET /api/v1/ai-agents/{id} · الصلاحية: ai_agents:read

تعيد وكيل ذكاء اصطناعي واحدًا، بالحقول المذكورة في aiAgents.list.

curl https://rabtcrm.com/api/v1/ai-agents/4 \
  -H "Authorization: Bearer $RABT_API_KEY"

الأخطاء: 400 validation_failed (قيمة id غير صالحة)، 404 not_found.


aiAgents.update

PATCH /api/v1/ai-agents/{id} · الصلاحية: ai_agents:write · ميزة الباقة: الذكاء الاصطناعي

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

حقل الجسمالنوعالقاعدة
namestringمن 1 إلى 100 حرف
descriptionstring أو nullnull أو "" تمسح الوصف
isActiveboolean
systemPromptstring أو nullفقط للوكلاء الذين promptMode لديهم manual. غير ذلك يعيد الطلب 409 agent_uses_prompt_blocks ولا يغيّر شيئًا.
temperaturenumberبين 0 و2، بخطوات 0.1 (مثل 0.7؛ القيمة 0.25 مرفوضة)
maxOutputTokensintegerمن 1 إلى 100,000

الاستجابة: الوكيل بعد التعديل، كما في aiAgents.list.

curl -X PATCH https://rabtcrm.com/api/v1/ai-agents/4 \
  -H "Authorization: Bearer $RABT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "isActive": true, "temperature": 0.5 }'

الأخطاء: 400 validation_failed / invalid_json، 402 team_suspended، 403 feature_not_enabled، 404 not_found، 409 agent_uses_prompt_blocks، 415 unsupported_media_type.


templates.list

GET /api/v1/templates · الصلاحية: messages:send

تعرض قوالب رسائل واتساب الخاصة بك، لإرسالها عبر messages.send (type: "template"). القوالب المؤرشفة لا تظهر. مرتبة حسب المعرّف، حتى 500 قالب، وnextCursor دائمًا null.

معامل الاستعلامالوصف
instanceIdاختياري. قوالب هذا الاتصال فقط. المعرّف الذي ليس من اتصالاتك يعيد قائمة فارغة.

الاستجابة: data تحتوي عنصرًا لكل قالب.

الحقلالنوعالوصف
idintegerمعرّف القالب
instanceIdintegerالاتصال الذي يتبع له القالب
instanceNamestringأرسله في instanceName إلى messages.send.
namestringأرسله في templateName.
languagestringأرسله في templateLanguage، مثل en_US.
categorystringمثل MARKETING أو UTILITY
statusstringحالة مراجعة Meta. لا يمكن إرسال إلا القوالب APPROVED.
headerobject أو nullnull إذا لم يكن للقالب رأس. وإلا: format (TEXT أو IMAGE أو VIDEO أو DOCUMENT أو LOCATION)، وtext (نص الرأس النصي، وإلا null)، وneedsVariable (رأس نصي فيه {{1}}: أرسل templateHeaderVariable)، وneedsMedia (أرسل templateHeader مع mediaUrl).
bodyTextstring أو nullنص الرسالة، ومتغيراته بالشكل {{1}} و{{2}} ...
bodyVariableCountintegerعدد العناصر المطلوبة في templateBodyVariables
curl https://rabtcrm.com/api/v1/templates \
  -H "Authorization: Bearer $RABT_API_KEY"
{
  "data": [
    {
      "id": 31, "instanceId": 4, "instanceName": "main-store", "name": "order_shipped", "language": "en_US",
      "category": "UTILITY", "status": "APPROVED", "header": null,
      "bodyText": "Hi {{1}}, your order {{2}} has shipped.", "bodyVariableCount": 2
    }
  ],
  "nextCursor": null
}

لإرساله: "type": "template" و"templateName": "order_shipped" و"templateLanguage": "en_US" و"templateBodyVariables": ["Sara", "#1042"].

الأخطاء: 400 validation_failed (instanceId غير صالح)، و403 insufficient_scope (المفتاح لا يملك messages:send)، والأخطاء العامة.


messages.send

POST /api/v1/send · الصلاحية: messages:send · تقبل Idempotency-Key

ترسل رسالة واتساب أو ماسنجر أو إنستغرام. المفاتيح القديمة تستطيع استدعاءها، وتقبل أيضًا جلسة لوحة التحكم إذا لم تُرسل ترويسة Authorization.

تحتفظ هذه النقطة بسلوكها الأصلي، وهو يختلف عن باقي النقاط:

  • الأخطاء بالشكل { "error": "<message>" } أو { "error": "<message>", "code": "<code>" }، وليس بالشكل الموصوف في الأخطاء.
  • لا تستخدم حدود المفتاح، ولا تُرسل X-RateLimit-* إلا مع 429 الخاص بحد الوسائط (راجع حدود الطلبات).
  • ترويسة X-Request-Id لا تُرسل إلا عند الاستدعاء بمفتاح API مع Idempotency-Key.

أرسل Content-Type: application/json مع الجسم أدناه، أو multipart/form-data بجزأين: payload (نفس JSON كنص) وfile اختياري (حتى 20 ميجابايت).

حقل الجسمالنوعالقاعدة
instanceNamestringمطلوب. قيمة instanceName لاتصال واتساب من instances.list. وعند الإرسال إلى عميل على ماسنجر أو إنستغرام: id القناة كنص، مثل "51".
numberstringمطلوب. رقم هاتف المستلم، أو في ماسنجر وإنستغرام قيمة remoteJid للمحادثة (fb_... أو ig_...)
typestringمطلوب. text أو image أو video أو document أو audio أو template
messagestringمطلوب مع text. ومع وسائط واتساب يكون التعليق على الوسائط. غير مسموح مع الوسائط في ماسنجر وإنستغرام (أرسل النص كرسالة text مستقلة).
mediaUrlstring (رابط)لأنواع الوسائط: رابط الملف. لا تجمعه مع رفع file.
fileNamestring
mimetypestring
templateNamestringمطلوب مع template
templateLanguagestringمطلوب مع template
templateHeaderVariablestringمع template فقط
templateBodyVariablesمصفوفة stringمع template فقط
templateHeaderobjectمع template فقط: { type: "image" | "video" | "document", mediaUrl?, fileName? }. mediaUrl مطلوب، إلا في اتصال META-CLOUD حيث يمكن رفع وسائط الترويسة في file بطلب multipart بدلًا منه. اتصال WHATSAPP-BUSINESS يرفض الترويسة المرفوعة بالخطأ 400، فاستخدم mediaUrl.

القواعد:

  • أنواع الوسائط تحتاج mediaUrl أو ملفًا مرفوعًا في file، ولا يجوز الاثنان معًا. والنوع text لا يقبل ملفًا.
  • حقول القوالب مسموحة فقط مع type: "template". القوالب تعمل فقط على اتصالات واتساب من نوع META-CLOUD وWHATSAPP-BUSINESS.
  • ماسنجر وإنستغرام: يجب أن يراسلك العميل أولًا، ولا يمكنك الرد إلا خلال نافذة الرد التي تحددها المنصة. خارجها تكون الاستجابة 409 مع code مثل AUTOMATION_OUTSIDE_STANDARD_WINDOW وlastCustomerMessageAt.
  • واتساب META-CLOUD وWHATSAPP-BUSINESS: الرسالة الحرة (text وimage وvideo وdocument وaudio) تحتاج أن يكون العميل قد راسل هذا الرقم خلال آخر 24 ساعة. وإلا تكون الاستجابة 422 مع code: "outside_service_window" وlastCustomerMessageAt (وقت آخر رسالة من العميل، أو null إذا لم تصل منه رسالة منذ ربط الرقم)، ولا يُرسل شيء. أرسل قالبًا معتمدًا بدلًا منها (templates.list)؛ وإرسال القالب لا يعيد فتح النافذة. وقد ترفض Meta رسالة أُرسلت في لحظة انتهاء النافذة نفسها؛ ويصل هذا الفشل لاحقًا كحالة رسالة فاشلة.
  • في هذه الاتصالات، يجد فحص نافذة الـ 24 ساعة محادثة العميل حتى إذا كتبت الرقم بصيغة شائعة أخرى (المكسيك 52/521، وأرقام الجوال في البرازيل مع الرقم التاسع أو بدونه، والأرجنتين 54/549 والصيغة المحلية 15)، وكذلك عبر محادثة برقم مخفي (BSUID) ربطها واتساب بذلك الرقم. وإذا كانت المحادثة الحديثة الوحيدة لا يُوصل إليها إلا عبر ربط يشير إلى أكثر من شخص (مثل BSUID مربوط برقمي هاتف بعد تغيير الرقم)، فإن إرسال رسالة نصية أو وسائط يعيد 422 recipient_ambiguous ولا يُرسل شيء؛ أرسل إلى رقم الهاتف الحالي للعميل، أو أرسل قالبًا.

الاستجابة (200)، أحد هذه الأشكال:

الشكلمتى
{ "success": true, "messageId": "...", "chatId": 123 }الإرسال عبر WhatsApp Cloud API (META-CLOUD) وكل إرسال لقالب
{ "success": true, "messageId": "...", "chatId": 123, "channelType": "FACEBOOK-MESSENGER" }الإرسال عبر ماسنجر وإنستغرام (channelType هي FACEBOOK-MESSENGER أو INSTAGRAM-DM)
{ "success": true, "data": { ... } }اتصالات واتساب الأخرى: استجابة المزوّد كما هي، ومعرّف الرسالة في data.key.id

messageId هو معرّف الرسالة لدى المزوّد، وchatId هو محادثة ربط CRM التي حُفظت فيها الرسالة.

curl -X POST https://rabtcrm.com/api/v1/send \
  -H "Authorization: Bearer $RABT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-confirmation" \
  -d '{
    "instanceName": "main-store",
    "number": "201001234567",
    "type": "text",
    "message": "Your order #1042 has shipped."
  }'

إرسال ملف بصيغة multipart:

curl -X POST https://rabtcrm.com/api/v1/send \
  -H "Authorization: Bearer $RABT_API_KEY" \
  -F 'payload={"instanceName":"main-store","number":"201001234567","type":"document","fileName":"invoice.pdf"}' \
  -F "file=@invoice.pdf"

الأخطاء (بالشكل القديم):

الحالةالمعنى
400جسم غير صالح (details تذكر أخطاء الحقول)، أو تركيبة حقول لا يسمح بها type، أو مستلم غير صالح، أو invalid_idempotency_key، أو قالب تعذّر بناؤه، أو ترويسة قالب مرفوعة في اتصال WHATSAPP-BUSINESS، أو mediaUrl تعذّر تنزيله
401مفتاح API مفقود أو غير صالح
402الفريق موقوف، أو وصلت إلى حد التخزين
403insufficient_scope (المفتاح لا يملك messages:send) أو recipient_blocked
404الاتصال أو القالب أو القناة غير موجود، أو conversation_not_found (يجب أن يراسلك العميل أولًا على ماسنجر أو إنستغرام)
409idempotency_conflict، أو رفض بسبب نافذة الرد في ماسنجر أو إنستغرام (مع lastCustomerMessageAt)
413الملف المرفوع أكبر من 20 ميجابايت، أو الوسائط أكبر من حد القناة (قيمة error هي media_too_large:<kind>:<MB>)
415Content-Type ليس application/json ولا multipart/form-data، أو صيغة الوسائط غير مدعومة (media_type_unsupported)
422idempotency_key_reused، أو outside_service_window: رسالة حرة عبر واتساب ونافذة الـ 24 ساعة مغلقة (مع lastCustomerMessageAt؛ لا يُرسل شيء)، أو recipient_ambiguous: رسالة حرة عبر واتساب محادثتها الحديثة الوحيدة مرتبطة بأكثر من شخص (لا يُرسل شيء)
429محاولات مصادقة فاشلة كثيرة من عنوان IP الخاص بك، أو تجاوز حد الوسائط للفريق (5 في الدقيقة، راجع حدود الطلبات): انتظر عدد الثواني في Retry-After. أو رفض المزوّد الإرسال بالحالة 429، وتُعاد بدون Retry-After.
500خطأ داخلي، أو قبل المزوّد الرسالة لكن تعذّر حفظها (قد تكون وصلت)
502فشل المزوّد أو أعاد ردًا غير متوقع
504تأخر المزوّد في الرد. قد تكون الرسالة وصلت.
حالات 4xx أخرىرفض المزوّد الرسالة، وتُعاد حالته كما هي بدون Retry-After

لا تُعد الإرسال تلقائيًا بعد 500 أو 504. أرسل مع Idempotency-Key، فإعادة الطلب بنفس المفتاح تعيد النتيجة المحفوظة بدلًا من الإرسال مرة أخرى (راجع منع التكرار).


openapi.json

GET /api/v1/openapi.json · عامة، لا تحتاج مفتاحًا

تعيد مستند OpenAPI 3.1 لهذا الـ API. يغطي كل نقاط النهاية الأخرى في هذه الصفحة مع مخططات الطلبات والاستجابات، وكل عملية فيه تحمل أيضًا x-required-scope. قد تُخزَّن الاستجابة مؤقتًا لمدة 5 دقائق (Cache-Control: public, max-age=300).

curl https://rabtcrm.com/api/v1/openapi.json

الخطوة التالية

← المصادقة عبر API