المصادقة
كل طلب يحمل بيانات اعتماد من نوع bearer في header الـ Authorization. لا توجد صيغة ثانية ولا header بديل — وهذه الصفحة تحدد أي بيانات تُستخدم أين، وماذا يحدث حين تصل الخاطئة.
Bearer فقط لا غير
المصادقة header واحد. يقرأ الخادم Authorization، ويطابق الصيغة دون حساسية لحالة الأحرف، ويأخذ بقية القيمة بيانات اعتماد.
Authorization: Bearer wa_live_<secret>لا يوجد header باسم x-api-key
النص x-api-key يظهر في backend هذه المنصة في موضع واحد فقط: قائمة أسماء الـ headers التي تُحجب من السجلات. لا مسار في الكود يقرؤه بيانات اعتماد. والطلب الذي يرسل ذلك الـ header وحده يُقابل بـ 401، ولن يخبرك الـ 401 بالسبب.
نوعان من بيانات الاعتماد، header واحد
الـ header نفسه يحمل إما API key لمساحة عمل، وإما access token لمستخدم. والاختيار بينهما يتبع: أيتصرف هنا جهاز أم إنسان.
| بيانات الاعتماد | الشكل | تُستخدم في |
|---|---|---|
| API key | wa_test_… / wa_live_… | التكاملات بين الخوادم. يسمّي مساحة عمله بنفسه ويحمل مجموعة صلاحيات ثابتة. |
| Access token للمستخدم | eyJhbGciOi… | لوحة التحكم، وكل ما يتصرف نيابة عن شخص مسجّل دخوله. قصير العمر، ويُستخرج من endpoint تسجيل الدخول. |
يميّز الخادم بينهما ببادئة بيانات الاعتماد، فلا تحتاج أن تعلن أيهما ترسل. وبعض النقاط تقبل نوعا واحدا فقط: إنشاء API key ومسارات ربط QR تتطلب access token، لأن بيانات الاعتماد الآلية لا شخص خلفها ولا متصفح.
مفاتيح test وlive
يُنشأ المفتاح في وضع واحد ويبقى فيه. الوضع جزء من بيانات الاعتماد، ظاهر في بادئتها، ويغيّر ما يُسمح للمفتاح بفعله.
| الوضع | البادئة | الوصف |
|---|---|---|
| test | wa_test_ | العمل على الـ Sandbox. مطلوب لكل عملية Sandbox، بما فيها الإرسال عبر قناة Sandbox. |
| live | wa_live_ | حركة الإنتاج. تَرفضه كل عمليات الـ Sandbox. |
مفتاح live لا يلمس الـ Sandbox
حجز جلسة Sandbox وتوثيقها وإلغاؤها والإرسال عبر قناتها كلها ترفض مفتاح live بـ SANDBOX_TEST_KEY_REQUIRED. وهذا مقصود: يجعل إرسال حركة اختبار على بيانات اعتماد إنتاجية أمرا مستحيلا بالخطأ.
الـ header المسمى X-Workspace-Id
كل endpoint مرتبط بمساحة عمل يحتاج أن يعرف في أي مساحة يتصرف. ومصدر ذلك يتبع نوع بيانات الاعتماد.
- مع
API key: مساحة العمل تأتي من المفتاح، والـ header اختياري. - مع
access token: الـ header مطلوب، لأن الشخص قد ينتمي إلى عدة مساحات. وإغفاله يعطي 400 برمزWORKSPACE_CONTEXT_REQUIRED. - إرسال header يخالف مساحة عمل الـ API key نفسه يعطي 403، لا تجاوزا صامتا.
# An API key already names its workspace, so the header is optional...
curl https://whats.azzamkh.sa/api/v1/channels \
-H "Authorization: Bearer $WA_API_KEY"
# ...but a USER access token belongs to a person, who may be in several.
curl https://whats.azzamkh.sa/api/v1/channels \
-H "Authorization: Bearer <access token>" \
-H "X-Workspace-Id: ws_..."
# Omitting it with a user token:
# 400 { "error": { "code": "WORKSPACE_CONTEXT_REQUIRED", ... } }الصلاحيات
يحمل الـ API key مجموعة صلاحيات ثابتة تُختار عند الإنشاء. والطلب خارجها يعطي 403 مع الصلاحيات المطلوبة في details.
| الصلاحية | الوصف |
|---|---|
| workspace.read | docs.pages.authentication.scopes.list.workspace.read |
| channels.read | docs.pages.authentication.scopes.list.channels.read |
| channels.manage | docs.pages.authentication.scopes.list.channels.manage |
| messages.read | docs.pages.authentication.scopes.list.messages.read |
| messages.send | docs.pages.authentication.scopes.list.messages.send |
| contacts.read | docs.pages.authentication.scopes.list.contacts.read |
| contacts.manage | docs.pages.authentication.scopes.list.contacts.manage |
| templates.manage | docs.pages.authentication.scopes.list.templates.manage |
| campaigns.read | docs.pages.authentication.scopes.list.campaigns.read |
| campaigns.manage | docs.pages.authentication.scopes.list.campaigns.manage |
| automations.manage | docs.pages.authentication.scopes.list.automations.manage |
| webhooks.manage | docs.pages.authentication.scopes.list.webhooks.manage |
المجموعة الافتراضية فيها ثغرة واحدة
إغفال scopes أو إرسال مصفوفة فارغة يمنح كل الصلاحيات عدا webhooks.manage. والمفتاح الذي يحتاج إدارة نقاط الـ webhook عليه أن يطلب تلك الصلاحية صراحة.
إنشاء مفتاح
POST/v1/api-keysتُنشأ المفاتيح بواسطة مستخدم مسجّل دخوله، لا بواسطة مفتاح آخر: فالمفتاح المخترق لا يستطيع أن يصكّ لنفسه مفتاحا أوسع.
# A key can only be minted by a signed-in user, never by another key.
curl -X POST https://whats.azzamkh.sa/api/v1/api-keys \
-H "Authorization: Bearer <access token>" \
-H "X-Workspace-Id: ws_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Order service (test)",
"mode": "test",
"scopes": ["messages.send", "messages.read"]
}'
# 201 Created — "secret" appears in THIS response and nowhere else.
# {
# "id": "key_...",
# "name": "Order service (test)",
# "mode": "test",
# "prefix": "wa_test",
# "last4": "9f3a",
# "scopes": ["messages.send", "messages.read"],
# "expires_at": null,
# "secret": "wa_test_..."
# }السر يُعرض مرة واحدة
تظهر بيانات الاعتماد كاملة في استجابة الإنشاء ولا تظهر في أي موضع آخر. لا يُخزَّن إلا التجزئة، فلا يمكن استرجاعها — وإن ضاعت فألغِ المفتاح وأنشئ غيره.
التدوير والإلغاء
لا يوجد endpoint للتدوير. التدوير هو إنشاء ثم إلغاء، وهو الشكل الأسلم أصلا: يبقى المفتاح القديم عاملا حتى يُنشر الجديد.
DELETE/v1/api-keys/{keyId}curl -X DELETE https://whats.azzamkh.sa/api/v1/api-keys/key_... \
-H "Authorization: Bearer <access token>" \
-H "X-Workspace-Id: ws_..."
# 200 OK — repeating this returns the ORIGINAL revoked_at, not an error.
# { "id": "key_...", "revoked_at": "2026-08-13T10:00:00.000Z" }بالترتيب:
- أنشئ مفتاحا جديدا بالصلاحيات والوضع نفسيهما.
- انشره، وتأكد أن الحركة تجري عليه.
- ألغِ المفتاح القديم. يسري الإلغاء فورا، وتكراره آمن: يعيد وقت الإلغاء الأصلي لا خطأ.
إخفاقات المصادقة
كل إخفاق يتبع الغلاف القياسي الموصوف في الأخطاء والحدود.
| HTTP | الرمز | متى يحدث |
|---|---|---|
| 401 | UNAUTHORIZED | لا بيانات اعتماد، أو بيانات مجهولة أو ملغاة أو منتهية، أو مفتاح مساحة عمله غير نشطة. وهذه كلها لا يمكن التمييز بينها عمدا. |
| 403 | FORBIDDEN | بيانات اعتماد صحيحة لكنها غير مسموحة هنا — صلاحية ناقصة، أو API key على مسار يتطلب جلسة مستخدم. |
| 400 | WORKSPACE_CONTEXT_REQUIRED | access token دون تسمية مساحة عمل في المسار أو في الـ header. |
| 403 | ACCOUNT_SUSPENDED | حساب المستخدم موقوف. |
| 403 | WORKSPACE_SUSPENDED | مساحة العمل موقوفة. |
التعامل مع المفاتيح
- اقرأ المفاتيح من بيئة التشغيل. لا تودع مفتاحا في مستودع، ولا تضعه في كود يعمل في المتصفح.
- هذه الـ API سطح بين الخوادم. والمفتاح في المتصفح مفتاح نشرته للعالم.
- اطلب الصلاحيات التي تستعملها فحسب. تكامل يرسل فقط لا يحتاج
contacts.manage. - ابنِ على مفتاح
test. والانتقال إلى live ينبغي أن يكون تغيير إعداد لا تغيير كود.