نوعان من المفاتيح.
مفتاح المنصة (خادم إلى خادم، CRUD كامل)
استخدم Bearer token من خادمك الخلفي:
Authorization: Bearer <key_id>.<key_secret>
الشكل هو key_id.key_secret، وكلا الجزأين مطلوب. وkey_id هو المعرّف المكوّن من 24 حرفًا والذي يبدأ أصلًا بـdzpk_live_ (مثال: dzpk_live_xxxxxxxxxxxxxx.<48-hex secret>)، لذا لا تُضِف البادئة مرة أخرى. أما سر المفتاح فطوله 48 حرفًا ست عشريًا ويُعرض مرة واحدة فقط عند الإنشاء ولن يظهر مجددًا.
المفتاح العام (المواقع والتطبيقات الخارجية؛ موقّع بـ HMAC)
لعدّ اشتراكات المستخدمين النهائيين وأحداثهم المخصصة من موقع أو تطبيق تديره خارج DZBuild. يستدعي خادمك الخلفي POST /v1/signups أو POST /v1/events ويوقّع كل طلب — لا تكشف سر التوقيع للمتصفح أبدًا.
الرؤوس:
Authorization: DZ-Public <key_id> X-DZ-Timestamp: <unix_seconds> X-DZ-Nonce: <32-hex> X-DZ-Signature: hex(hmac_sha256(signing_secret, key_id + "\n" + nonce + "\n" + ts + "\n" + sha256(body)))
هنا أيضًا يبدأ key_id أصلًا بـdzpub_live_ — مرّره كما أُرجع لك تمامًا. وسر التوقيع طوله 64 حرفًا ست عشريًا.
الـ nonce يُستخدم مرة واحدة فقط لكل مفتاح ولمدة ساعة، ويمنع إعادة التشغيل. الطابع الزمني يجب أن يكون ضمن ±5 دقائق.
⚠️ تنبيه — المفتاح العام الجديد يبقى معطّلًا حتى يُفعَّل
المفتاح من نوع type: public الذي تُنشئه عبر POST /v1/keys سيُرجع 401 إلى أن يُفعَّل لاستقبال حركة الواجهة البرمجية. راسل الدعم مباشرة بعد إنشائه لتفعيله. أما مفاتيح المنصة (Bearer) فلا يشملها ذلك — تعمل فورًا.
الصلاحيات (Scopes)
كل مفتاح له قائمة من الصلاحيات. صلاحيات منصة افتراضية: store:read, store:write, products:read, products:write, orders:read, orders:write, customers:read, landing_pages:read, landing_pages:write, promos:read, promos:write, pixels:read, pixels:write, shipping:read, shipping:write, webhooks:read, webhooks:write, usage:read, analytics:read, whatsapp:read, whatsapp:send. المفتاح الذي يُنشأ من لوحة التحكم يحصل على هذه القائمة بالضبط. وهي لا تضم delivery:send ولا ai:generate، لذا فالمفتاح المُنشأ من لوحة التحكم أو عبر POST /v1/keys يتلقى 403 على POST /v1/orders/{id}/send-to-delivery وPOST /v1/landing-pages/generate.
صلاحيات عامة افتراضية: signups:write, events:write.
تُفحَص الصلاحيات في القراءة كما في الكتابة: المفتاح الذي لا يملك orders:read يتلقى 403 مع الرسالة Missing scope: orders:read على GET /v1/orders. والصلاحية store:write تشمل كتابات إعدادات المتجر وتصميمه وقالبه وأقسام صفحته الرئيسية. أما signups:write وevents:write فتخصّان POST /v1/signups وPOST /v1/events.
إدارة المفاتيح (/v1/keys) محكومة بـنوع المفتاح لا بصلاحياته: المفتاح العام الذي يستدعيها يتلقى 403 — "Key management requires a platform key".
مفتاح المنصة الذي يُنشأ عبر POST /v1/keys لا يحصل إلا على الصلاحيات التي يملكها المفتاح المستدعي أصلًا (403 إن لم تجمعهما أي صلاحية مشتركة). أما المفتاح من نوع type: public فيحصل دائمًا على signups:write وevents:write.
إنشاء مفتاح
ينشئ مالك متجر على خطة Enterprise سارية مفاتيحه الشخصية من لوحة التحكم عبر الإعدادات ← واجهة API (/dashboard/api). يُسجَّل المفتاح الجديد في البرنامج التجريبي تلقائيًا ويعمل فورًا، فلا شيء تطلبه من الدعم. تعرض الصفحة قيمتين، مرة واحدة فقط، عند إنشاء المفتاح:
مفتاح الوصول (Bearer token): هو بيانات الاعتماد كاملة، وهو أصلًا بالشكل
key_id.key_secret. أرسله كما هو،Authorization: Bearer <bearer token>، دون أن تضيف إليه شيئًا.سر التوقيع (Signing secret): لا يوضع أبدًا في رأس
Authorization، ونداءاتBearerلا تستعمله. احفظه سرًّا مثل مفتاح الوصول.
يحتفظ المتجر بـ 3 مفاتيح شخصية نشطة كحد أقصى. والمفاتيح التي تحملها التطبيقات المثبّتة أو Copilot أو أحد الموصلات لا تشغل أيًّا من هذه الأماكن.
اتصالات المساعدين
الاتصال الذي يُنشأ لـ Copilot أو لمساعد ذكاء اصطناعي متصل (Claude أو ChatGPT) يمكن أن يغطي عدة متاجر للتاجر، بمفتاح لكل متجر. وتسمح نقطتا نهاية للمفتاح الذي يحمله اتصال كهذا بقراءة المتاجر التي يغطيها وبتغيير المتجر النشط منها. أما أي مفتاح آخر، بما في ذلك المفتاح المُنشأ من لوحة التحكم، فيتلقى 404 not_found مع This key does not belong to an assistant connection.
GET /v1/connection
يحتاج إلى store:read.
curl https://api.dzbuild.app/v1/connection \ -H "Authorization: Bearer $DZ_KEY"
{ "data": { "connection_id": 100, "client_name": "Claude", "active_store_id": 10,
"stores": [ { "id": 10, "name": "My store", "slug": "my-store" },
{ "id": 20, "name": "My second store", "slug": "my-second-store" } ] },
"meta": { "request_id": "...", "api_version": "v1" } }
client_name هو اسم تطبيق المساعد. والاتصال الذي تمّت الموافقة عليه قبل أن تصبح الاتصالات قادرة على تغطية عدة متاجر يسرد متجره الوحيد.
POST /v1/connection/active-store
يحتاج إلى store:write وإلى Idempotency-Key. ويحدّد store_id في الجسم المتجر الذي يصبح نشطًا.
curl -X POST https://api.dzbuild.app/v1/connection/active-store \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: active-store-20" \
-d '{"store_id": 20}'
الاستجابة هي الاتصال بعد النقل، بالشكل نفسه الذي يُرجعه GET /v1/connection. المتجر النشط مؤشّر وليس صلاحية: كل طلب يبقى يعمل على المتجر الوحيد الذي ينتمي إليه مفتاحه. والمتجر الذي لا يدخل في الاتصال يُرجع 403 store_not_in_connection، والجسم الذي لا يحمل store_id يُرجع 400 bad_request.