واجهة marv.Inbox للمطورين
اربط أي نظام CRM أو نقطة بيع أو نظام ERP أو تطبيق داخلي بصندوق واتساب وماسنجر الخاص بفريقك. واجهة REST فوق OAuth2 لقراءة البيانات وكتابتها، إضافة إلى webhooks موقّعة تدفع الأحداث إليك في الوقت الفعلي. تستطيع كل مساحة عمل إنشاء بيانات الاعتماد الخاصة بها من الإعدادات، المطورون. بلا برنامج شركاء وبلا مكالمة مبيعات.
عنوان الأساس: https://api.marvinbox.com
ما الذي يمكنك بناؤه
مزامنة جهات الاتصال والمحادثات
حدّث جهات الاتصال من نظام CRM لديك، وابحث عنها بالهاتف أو بمعرّفك الخاص، واقرأ المحادثات وسجل الرسائل.
إرسال الرسائل والحملات
أرسل ردًا أو قالب واتساب معتمدًا داخل محادثة، أو أطلق حملة صادرة إلى قائمة جهات اتصال.
إنشاء المهام وتسجيل الأحداث
افتح مهامًا لفريقك واكتب أحداث الجدول الزمني لنظام CRM، مثل طلب تم أو فاتورة متأخرة، على جهة اتصال.
استقبال webhooks في الوقت الفعلي
اشترك في الرسائل الواردة وتغيرات المحادثات وتحديثات المهام وأحداث الحملات. كل عملية تسليم موقّعة بـ HMAC.
عنوان الأساس والوصول
الواجهة فعّالة في الإنتاج اليوم. لا تحتاج إلى ترقية أو حساب مطورين منفصل.
- عنوان الأساس
https://api.marvinbox.com- الحصول على بيانات الاعتماد
- سجّل الدخول إلى app.marvinbox.com وافتح الإعدادات، المطورون. أنشئ integration client للحصول على client id و client secret للواجهة، وسجّل webhook endpoint لاستقبال الأحداث. تتطلب إدارة الاثنين دور مشرف مساحة العمل.
بداية سريعة
ثلاث خطوات من الصفر إلى أول طلب موثّق.
أنشئ integration client
من الإعدادات، المطورون، Integration clients، أنشئ client واختر الـ scopes التي يحتاجها. انسخ client id و client secret. يظهر الـ secret مرة واحدة فقط.
بدّل بيانات الاعتماد برمز وصول
استدعِ نقطة نهاية الرمز بـ client id و secret. ستحصل على bearer token قصير العمر، صالح لساعة واحدة.
استدعِ الواجهة
أرسل الرمز في ترويسة Authorization مع كل طلب. الرمز يحدّد مساحة عملك أصلًا، لذا لا توجد ترويسة tenant لضبطها.
curl -X POST https://api.marvinbox.com/external/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "marv_ic_live_...",
"client_secret": "marv_cs_..."
}'الرد
{
"access_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "customers:write messages:write"
}curl -X POST https://api.marvinbox.com/external/v1/customers/upsert \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: <unique-key>" \
-d '{
"phone": "+972501234567",
"name": "Jane Doe",
"externalCustomerId": "crm-001"
}'المصادقة
تعتمد المصادقة على منح client credentials في OAuth2. أرسل client id و secret إلى نقطة نهاية الرمز واحصل على bearer token، وهو JWT موقّع، صالح لمدة 3600 ثانية.
أرسل هذا الرمز بصيغة Authorization: Bearer <token> مع كل طلب إلى external/v1. الرمز مرتبط بمساحة العمل المالكة للـ client، فلا يمكن لرمز مساحة أن يقرأ مساحة أخرى، ولا ترسل معرّف tenant.
تُفحص الـ scopes مقابل الـ client في الوقت الفعلي عند كل طلب، لذا يسري تضييق أي scope أو تدوير الـ secret فورًا.
Scopes
امنح الـ client الـ scopes التي يحتاجها فقط. تذكر كل نقطة نهاية أدناه الـ scope المطلوب لها.
| Scope | يمنح |
|---|---|
customers:read | Look up contacts |
customers:write | Create and update contacts |
conversations:read | List and read conversations |
conversations:write | Reserved for future use |
messages:read | Read message history |
messages:write | Send messages and templates |
events:write | Ingest CRM timeline events |
tasks:read | List and read tasks |
tasks:write | Create and update tasks |
campaigns:write | Create outbound campaigns |
نقاط نهاية REST
كل نقاط النهاية تحت عنوان الأساس أعلاه. تقبل طلبات الكتابة ترويسة Idempotency-Key.
| الطريقة | نقطة النهاية | Scope |
|---|---|---|
| POST | /external/oauth/tokenExchange client credentials for an access token | none |
| POST | /external/v1/customers/upsertCreate or update a contact by phone or external id | customers:write |
| GET | /external/v1/customers/lookupFind a contact by phone or external id | customers:read |
| GET | /external/v1/contactsList contacts (org, chat-window flag, last message), by last activity | customers:read |
| POST | /external/v1/contacts/messagesRead a contact’s messages grouped per phone | messages:read |
| GET | /external/v1/templatesList approved WhatsApp templates (with template id) | messages:read |
| POST | /external/v1/messages/sendSend by phone: a text reply or an approved template | messages:write |
| POST | /external/v1/eventsLog a CRM timeline event (alias /interactions) | events:write |
| POST | /external/v1/outbound/campaignsCreate an outbound campaign | campaigns:write |
| POST | /external/v1/tasksCreate a task | tasks:write |
| GET | /external/v1/tasksList tasks | tasks:read |
| PATCH | /external/v1/tasks/:idUpdate a task | tasks:write |
Idempotency
أرسل ترويسة Idempotency-Key مع أي طلب كتابة. إذا أعدت المحاولة بالمفتاح نفسه، تعيد marv.Inbox النتيجة المحفوظة للطلب الأول بدل تنفيذ العملية مرتين. استخدم مفتاحًا فريدًا جديدًا لكل عملية منطقية.
حدود المعدل وقائمة عناوين IP المسموح بها
كل client محدود بـ 120 طلبًا في الدقيقة افتراضيًا. تحمل الردود X-RateLimit-Limit و X-RateLimit-Remaining، ويُعاد 429 عند تجاوز الحد. يمكنك أيضًا تقييد client بقائمة نطاقات IP مسموح بها (CIDR) عند الإنشاء.
Webhooks
تدفع الـ webhooks الأحداث إلى خادمك لحظة وقوعها، فلا تحتاج إلى polling.
تسجيل endpoint
من الإعدادات، المطورون، Webhooks، أضف عنوان المستقبِل لديك واختر الأحداث المطلوبة. انسخ الـ secret الخاص بالتوقيع الظاهر عند الإنشاء. يمكنك تسجيل حتى عشرة endpoints، وتفعيل أو تعطيل كل واحد، ومراجعة محاولات التسليم الأخيرة في الشاشة نفسها.
كيف تصل عمليات التسليم
كل حدث هو طلب POST بجسم JSON والترويسات التالية:
POST /your-receiver HTTP/1.1
Content-Type: application/json
X-Marv-Event: message.created
X-Marv-Delivery: 7c9e6679-7425-40de-944b-e07fc1f90ae7
X-Marv-Timestamp: 2026-06-15T10:23:45.123Z
X-Marv-Signature: v1=3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d...يشير رد 2xx إلى تسليم ناجح. تنتظر marv.Inbox حتى 10 ثوانٍ لردك وتعيد المحاولة مرة واحدة بعد 5 ثوانٍ عند الفشل. يجب أن تكون عناوين المستقبِل عامة. تُرفض العناوين الخاصة وعناوين loopback.
أنواع الأحداث
اشترك في أي مجموعة من هذه الأحداث.
| الحدث | متى يُرسل |
|---|---|
message.created | A message was sent or received |
conversation.updated | Conversation metadata changed |
conversation.assigned | Conversation assignment changed |
conversation.closed | A conversation was closed |
conversation.reopened | A closed conversation was reopened |
التحقق من التسليم
كل تسليم موقّع كي تثق بأنه جاء من marv.Inbox. يُحسب التوقيع على جسم الطلب الخام:
v1=HMAC-SHA256(secret, "{X-Marv-Timestamp}.{X-Marv-Delivery}.{rawBody}")أعد حسابه مقابل البايتات الدقيقة التي استقبلتها، قبل تحليل JSON، وارفض أي تسليم يكون فيه ختم الوقت أقدم من خمس دقائق، وأزل التكرار حسب X-Marv-Delivery، وقارن بزمن ثابت.
import { createHmac, timingSafeEqual } from 'crypto';
// marv.Inbox signs every delivery:
// v1=HMAC-SHA256(secret, `${timestamp}.${deliveryId}.${rawBody}`)
// Verify against the EXACT raw request body, before JSON parsing.
export function verifyMarvWebhook(headers, rawBody, secret) {
const signature = headers['x-marv-signature']; // "v1=<hex>"
const timestamp = headers['x-marv-timestamp']; // ISO 8601
const deliveryId = headers['x-marv-delivery']; // UUID, dedupe on this
// Reject anything older than 5 minutes (replay protection).
if (Math.abs(Date.now() - Date.parse(timestamp)) > 300_000) return false;
const expected = 'v1=' + createHmac('sha256', secret)
.update(`${timestamp}.${deliveryId}.${rawBody}`)
.digest('hex');
const a = Buffer.from(signature ?? '', 'utf8');
const b = Buffer.from(expected, 'utf8');
return a.length === b.length && timingSafeEqual(a, b);
}الأخطاء
تستخدم الأخطاء رموز حالة HTTP القياسية مع جسم JSON يصف المشكلة.
| الرمز | المعنى |
|---|---|
400 | Invalid request body or a missing required field |
401 | Missing, invalid, or expired access token |
403 | Token lacks the required scope, or the caller IP is not allowlisted |
404 | Unknown workspace or resource |
409 | Conflict, for example a colliding externalCustomerId |
429 | Rate limit exceeded (see X-RateLimit-Remaining) |
الأسئلة الشائعة
هل أحتاج إلى برنامج شركاء أو مكالمة مبيعات لاستخدام الواجهة؟+
لا. تستطيع أي مساحة عمل إنشاء integration clients و webhook endpoints من الإعدادات، المطورون. لا توجد عملية تقديم والواجهة غير محصورة بخطة أعلى.
كيف أربط نظام CRM أو مكتب دعم بـ marv.Inbox؟+
حدّث جهات الاتصال عبر customers/upsert، وسجّل النشاط عبر events، وافتح المتابعات عبر tasks، وأرسل الردود أو القوالب المعتمدة عبر messages/send. ولاستقبال الرسائل الواردة والتحديثات في نظامك، سجّل webhook endpoint واشترك في الأحداث التي تهمك.
كيف أتحقق من أن الـ webhook جاء فعلًا من marv.Inbox؟+
أعد حساب توقيع HMAC-SHA256 على "{timestamp}.{deliveryId}.{rawBody}" باستخدام secret نقطة النهاية وقارنه بترويسة X-Marv-Signature بزمن ثابت. ارفض عمليات التسليم التي يكون فيها X-Marv-Timestamp أقدم من خمس دقائق وأزل التكرار حسب X-Marv-Delivery.
ما الفرق بين integration client و webhook endpoint؟+
الـ integration client هو بيان الاعتماد الذي يستخدمه كودك لاستدعاء الواجهة: صادر، منك إلى marv.Inbox. و webhook endpoint هو عنوان تستدعيه marv.Inbox عند وقوع شيء: وارد، من marv.Inbox إليك. تستخدم معظم عمليات الدمج الاثنين معًا.
كيف أدوّر الوصول أو ألغيه؟+
دوّر secret الخاص بـ integration client أو ألغِ الـ client بالكامل من الإعدادات، المطورون. يبطل التدوير الـ secret القديم فورًا. أما الـ webhooks، فعطّل أو احذف الـ endpoint لإيقاف عمليات التسليم.
هل يحترم إرسال الرسائل نافذة الـ 24 ساعة في واتساب؟+
نعم. لا يُسمح برسالة واتساب حرة إلا خلال 24 ساعة من آخر رسالة للعميل. خارج النافذة، أرسل قالبًا معتمدًا بدلًا من ذلك. تفرض الواجهة ذلك نيابة عنك.
ابدأ البناء
أنشئ أول integration client و webhook endpoint في التطبيق، أو أخبرنا بما تربطه وسنساعدك في تحديد نطاقه.