انتقل إلى المحتوى
WbizTool

API v2 (تجريبي)

API v2

‏API v2 هو REST API الجديد من WbizTool: مفتاح واحد لكل تطبيق لا يملك إلا الصلاحيات التي يحتاج إليها، وعناوين URL على نمط الموارد، ورموز حالة HTTP حقيقية، وwebhooks بصيغة JSON موقّعة، وإعادة محاولة آمنة. تشرح هذه الصفحة ما تشترك فيه كل الطلبات، وتشرح صفحات الموارد كل نقطة نهاية.

عنوان URL الأساسي#

https://wbiztool.com/api/v2

لا تنتهي المسارات بشرطة مائلة (/api/v2/messages)، لكنها تُقبل أيضًا. والعنوان غير الموجود يُرجع 404 بالرمز not_found.

مثال سريع#

تحقّق من مفتاحك باستخدام GET /me. يعمل مع أي نطاق ولا يرسل شيئًا:

curl https://wbiztool.com/api/v2/me \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"
{
  "workspace": { "id": 5012, "name": "Acme Bakery" },
  "key": {
    "id": 7,
    "name": "Order system",
    "mode": "live",
    "scopes": ["messages:send", "messages:read"],
    "limited_to_numbers": false,
    "number_ids": [],
    "expires_at": null
  },
  "plan": { "name": "Starter" },
  "limits": {
    "requests_per_minute": 60,
    "requests_per_day": 10000,
    "messages_per_number_per_day": 1000,
    "messages_remaining": null
  }
}

تكون قيمة messages_remaining هي null عندما ترسل الباقة رسائل غير محدودة. وتكون قيمة plan هي null عندما لا تكون لمساحة العمل باقة نشطة.

المفاتيح#

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

Authorization: Bearer wbz_live_…

لا يوجد client_id: فالمفتاح يحدّد مساحة عمله. يبدأ مفتاح v2 بـwbz_live_ أو wbz_test_، ويليه 38 حرفًا ورقمًا. لا تعمل مفاتيح v1 مع v2 (تحصل على v1_key_on_v2)، ولا تعمل مفاتيح v2 مع v1.

إنشاء مفتاح#

ينشئ المالكون المفاتيح في Settings → API keys (الإعدادات ← مفاتيح API)، في بطاقة مفاتيح API v2: انقر على إنشاء مفتاح v2، ثم اختر:

  • الاسم: التطبيق الذي سيستخدمه، بحد أقصى 50 حرفًا.
  • نوع المفتاح: فعلي يرسل رسائل حقيقية؛ وتجريبي يتحقق من كل شيء ولا يرسل شيئًا (راجع وضع الاختبار).
  • ما يمكنه فعله: النطاقات، أو كل شيء.
  • الأرقام التي يمكنه استخدامها: كل الأرقام، بما فيها التي تُضاف لاحقًا، أو بعضها فقط (راجع المفاتيح المقيدة ببعض الأرقام).
  • الانتهاء: بلا انتهاء، أو بعد 30 يومًا أو 90 يومًا أو سنة.

يُعرض المفتاح مرة واحدة فقط. انسخه فورًا واحفظه على خادمك، في متغير بيئة مثلًا. لا يحتفظ WbizTool إلا ببصمة (hash) للمفتاح وبآخر أربعة أحرف منه، لذا لا يمكن عرض المفتاح المفقود مرة أخرى: أبطِله وأنشئ مفتاحًا جديدًا.

يمكن أن تملك مساحة العمل حتى 10 مفاتيح v2 غير مُبطلة. تعرض البطاقة لكل مفتاح آخر أربعة أحرف منه، ونطاقاته، وأرقامه، وتاريخ انتهائه، ومتى استُخدم آخر مرة ومن أي عنوان IP. يوقف إبطال المفتاح فورًا، ومعه نقاط استقبال webhook التي أنشأها. والمفتاح الذي تجاوز تاريخ انتهائه يحصل على api_key_expired.

النطاقات#

لا يستطيع كل مفتاح إلا ما تسمح به نطاقاته. والطلب الخارج عنها يُرجع 403 مع missing_scope، ويوضّح required_scope في الخطأ النطاق المطلوب.

النطاقما يسمح به
messages:sendإرسال الرسائل والدفعات، وإلغاء الرسائل المنتظرة: POST /messages وPOST /messages/batch وDELETE /messages/{id}
messages:readقراءة الرسائل وحالاتها (GET /messages وGET /messages/{id})، وإدارة نقاط استقبال webhook
remindersإنشاء التذكيرات وعرضها وتغييرها وإيقافها مؤقتًا وحذفها
numbersعرض الأرقام، ورؤية حالة اتصالها، وربط أرقام WhatsApp
mediaرفع الملفات في مكتبة الوسائط وعرضها وحذفها
contactsفحص الأرقام (تأتي نقاط نهاية جهات الاتصال لاحقًا)

لا يحتاج GET /me إلى نطاق معيّن. والإرسال إلى جهة اتصال محفوظة باستخدام to.contact_id لا يحتاج إلا إلى messages:send.

المفاتيح المقيدة ببعض الأرقام#

المفتاح المقيد ببعض الأرقام لا يعمل إلا معها:

  • لا يرسل إلا من تلك الأرقام، ولا يعرض ولا يقرأ ولا يلغي إلا رسائلها. ويحصل أي رقم آخر في from على number_not_allowed.
  • لا يعرض GET /numbers إلا تلك الأرقام. ويمكن للمفتاح إعادة ربطها، لكنه لا يستطيع إضافة رقم جديد.
  • لا يرى ولا يغيّر إلا التذكيرات التي تُرسَل من تلك الأرقام، ويجب أن يحدّد التذكير الجديد أحدها في from.
  • لا يستطيع إدارة نقاط استقبال webhook إطلاقًا، لأنها تستقبل أحداث مساحة العمل كلها.

يعرض GET /me قيمة limited_to_numbers وnumber_ids التي يمكن للمفتاح استخدامها.

الطلبات#

  • JSON في الطلب والاستجابة. أرسل الأجسام بـContent-Type: application/json. الاستثناء الوحيد هو رفع ملف، الذي يستخدم multipart/form-data. وكل استجابة بصيغة JSON، بما في ذلك الأخطاء.
  • أسماء الحقول بصيغة snake_case، وتُرفض الحقول غير المعروفة: خطأ إملائي مثل txt يُرجع validation_failed بدلًا من تجاهله.
  • أرقام الهواتف بالصيغة الدولية مع + (E.164)، مثل ‎+919876543210. المسافات والشرطات مسموح بها؛ والرقم بدون + يُرفض مع invalid_phone.
  • الأوقات بصيغة ISO 8601 مع فرق التوقيت، مثل 2026-10-20T09:30:00+05:30 أو 2026-10-20T04:00:00Z. والوقت بدون فرق توقيت يُرفض مع invalid_datetime. الأوقات في الاستجابات بتوقيت UTC وتنتهي بـZ، باستثناء next_run_at للتذكير، فهو بالمنطقة الزمنية للتذكير.
  • المعرّفات أعداد صحيحة، مثل id للرقم (وهو from عند الإرسال) أو id للرسالة.
  • رموز الحالة تعني ما تقوله: 200 نجاح، و201 تم الإنشاء، و202 تم القبول (في قائمة الانتظار)، و400 الطلب خاطئ، و401 المفتاح خاطئ، و402 لم تتبقَّ رسائل، و403 غير مسموح، و404 غير موجود، و409 تعارض، و413 كبير جدًا، و415 نوع محتوى خاطئ، و422 قيمة لا يمكن استخدامها، و429 طلبات كثيرة جدًا، و5xx خطأ من جهتنا.

تحمل الاستجابات Cache-Control: no-store.

الأخطاء#

لكل الأخطاء الشكل نفسه:

{
  "error": {
    "code": "invalid_phone",
    "message": "This is not a valid phone number. Write it in international format with +, e.g. +919876543210.",
    "field": "to.phone",
    "docs": "https://wbiztool.com/docs/api/v2/errors/#invalid_phone",
    "request_id": "req_4f1c2a9b8e7d6c5b4a392817"
  }
}
  • ‏code ثابت: اعتمد عليه في منطق شيفرتك. أما message فهو نص إنجليزي موجّه للمطوّر وقد يتغيّر.
  • ‏field يحدّد الحقل الذي يخصّه الخطأ (to.phone وto[3].phone وschedule.cron)، أو يكون null.
  • ‏docs يربط إلى الرمز في صفحة الأخطاء.
  • ‏request_id مطابق لترويسة X-Request-Id. اذكره إذا تواصلت معنا.
  • تضيف بعض الأخطاء تفاصيل، مثل status في not_cancellable أو used وlimit في storage_full. وعندما يحتوي الطلب على عدة مشكلات، يسرد errors المشكلات الأخرى، لكل منها field وmessage.

كل رمز، وحالة HTTP الخاصة به، وما يجب فعله، موجودة في صفحة الأخطاء.

Idempotency-Key#

خطأ في الشبكة أو انتهاء مهلة يتركانك غير متأكد مما إذا كان الطلب قد نجح. أرسل ترويسة Idempotency-Key مع طلب POST ينشئ شيئًا، وستتمكن من إرساله مرة أخرى بأمان:

curl -X POST https://wbiztool.com/api/v2/messages \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-ready" \
  -d '{"to": {"phone": "+919876543210"}, "text": "Hi Asha, your order #1042 is ready."}'
  • القيمة من اختيارك: أي سلسلة فريدة من 1 إلى 255 حرفًا قابلًا للطباعة، مثل UUID أو معرّف طلبك الخاص. أنشئ قيمة جديدة لكل طلب جديد، ولا تُعِد استخدامها إلا لإعادة محاولة الطلب نفسه.
  • تحصل إعادة المحاولة على الاستجابة الأولى مع الترويسة Idempotent-Replayed: true. لا يُنفَّذ أي شيء مرتين: لا رسالة ثانية، ولا تذكير، ولا ملف، ولا نقطة استقبال.
  • تبقى القيم 24 ساعة من الطلب الأول، وتخصّ مفتاح API الخاص بك: يمكن لمفتاح API آخر في مساحة العمل استخدام القيمة نفسها دون تعارض.
  • القيمة نفسها لطلب مختلف: الطلب بقيمة استُخدمت من قبل مع method أو مسار أو جسم مختلف يُرجع 422 idempotency_key_reused.
  • ما زال قيد التنفيذ: ما دام الطلب الأول بهذه القيمة قيد المعالجة، تُرجع إعادة المحاولة 409 idempotency_in_progress مع Retry-After: 1. انتظر لحظة وأرسله مرة أخرى.
  • لا تُحفظ الأخطاء. إذا أُرجع خطأ في الطلب الأول، فلا يُخزَّن شيء: أصلح الطلب وأرسله مرة أخرى بالقيمة نفسها.
  • لا تُعاد الأسرار. إعادة POST /webhooks لا تتضمن secret نقطة الاستقبال، الذي لا يُعرض إلا في الاستجابة الأولى.

تعمل مع POST /messages وPOST /messages/batch وPOST /numbers وPOST /reminders وPOST /media وPOST /number-checks وPOST /webhooks، وهي اختيارية في كل منها. وتتجاهل الطلبات الأخرى هذه الترويسة. والقيمة الفارغة أو الطويلة جدًا تُرجع 400 invalid_idempotency_key.

حدود المعدل#

يمكن لكل مفتاح إجراء 60 طلبًا في الدقيقة و10,000 طلب في اليوم. هذه نوافذ ثابتة: تبدأ نافذة الدقيقة مع بداية الدقيقة على الساعة، ونافذة اليوم عند 00:00 بتوقيت UTC. وعند تجاوز حدّ، يُرجع الطلب 429 rate_limited.

تحمل استجابات الطلبات بمفتاح صالح هذه الترويسات:

الترويسةالمعنى
RateLimit-Limitالطلبات المسموح بها في النافذة الحالية (60، أو 10000 بعد بلوغ حدّ اليوم)
RateLimit-Remainingالطلبات المتبقية في تلك النافذة
RateLimit-Resetالثواني المتبقية حتى تبدأ تلك النافذة من جديد
RateLimit-Policyالحدّان معًا: 60;w=60, 10000;w=86400
Retry-Afterمع 429: الثواني التي تنتظرها قبل المحاولة مجددًا

وبمعزل عن هذه الحدود:

  • المفاتيح الخاطئة: أكثر من 30 طلبًا في الدقيقة بمفتاح خاطئ من عنوان IP واحد تُرجع 429 too_many_auth_failures مع Retry-After: 60.
  • الرسائل لكل رقم: يرسل الرقم 1,000 رسالة على الأكثر خلال 24 ساعة (الاستخدام العادل). والإرسال الذي يتجاوز ذلك يُرجع 429 number_daily_cap_reached.

التقسيم إلى صفحات#

تأتي القوائم التي يمكن أن تكبر (GET /messages و/reminders و/media و/number-checks و/results لفحص ما) في صفحات، الأحدث أولًا:

{
  "data": [ … ],
  "next_cursor": "eyJpZCI6OTgxNzI2MywidCI6IjIwMjYtMTAtMThUMTA6MTU6MDIuMzExWiIsImYiOiI0NGIxMzZmYTM1NWIifQ"
}
  • ‏limit يحدّد حجم الصفحة، من 1 إلى 100 (الافتراضي 25).
  • للحصول على الصفحة التالية، أرسل الطلب نفسه مع cursor مضبوطًا على next_cursor من الصفحة السابقة. وتكون قيمة next_cursor هي null في الصفحة الأخيرة.
  • أبقِ عوامل التصفية الأخرى كما هي: المؤشر المستخدم مع عوامل تصفية مختلفة يُرجع 400 invalid_cursor. ابدأ من جديد بدون مؤشر.
  • تعامل مع المؤشر كسلسلة معتمة لا تفسّرها. والعناصر التي تُضاف أثناء التنقل بين الصفحات لا تزحزح الصفحات.
curl "https://wbiztool.com/api/v2/messages?limit=100&cursor=eyJpZCI6OTgxNzI2MywidCI6..." \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

يُرجع GET /numbers وGET /webhooks كل شيء في قائمة data واحدة.

معرفات الطلبات#

لكل استجابة، بما في ذلك الأخطاء، ترويسة X-Request-Id مثل req_4f1c2a9b8e7d6c5b4a392817. وتحمل الأخطاء القيمة نفسها في request_id. سجّلها، واذكرها إذا تواصلت معنا: فهي تتيح لنا العثور على الطلب في سجلاتنا، التي تسجّل معرّف مفتاحك لكن لا تسجّل المفتاح أبدًا.

إذا أرسلت X-Request-Id خاصًا بك (حتى 100 حرف قابل للطباعة)، فإنه يعود في X-Client-Request-Id، لتتمكن من مطابقة الاستجابات مع سجلاتك.

وضع الاختبار#

يتيح لك مفتاح الاختبار (wbz_test_…) بناء تكامل واختباره دون إرسال أي شيء. أنشئه في Settings → API keys (الإعدادات ← مفاتيح API) مع نوع المفتاح: تجريبي. ويعرض GET /me القيمة "mode": "test".

ما يفعله مفتاح الاختبار مثل المفتاح الفعلي:

  • يتحقق POST /messages وPOST /messages/batch من كل ما يتحقق منه الإرسال الفعلي: المستلم، والنص، والوسائط، وsend_at وexpires_at، والرقم المرسِل، ونطاقات المفتاح وأرقامه. والأخطاء نفسها تحصل على الأخطاء نفسها.
  • تعمل النطاقات والأرقام وحدود المعدل وIdempotency-Key بالطريقة نفسها.
  • كل قراءة لبقية مساحة العمل (GET /me و/numbers و/reminders و/media و/number-checks و/webhooks) تعرض بياناتها الحقيقية، للقراءة فقط.

ما يختلف:

  • لا يُرسَل شيء. يُحفظ الإرسال التجريبي بدلًا من ذلك كرسالة اختبار، ولا يستهلك رسائل الباقة ولا حدّ الرقم اليومي البالغ 1,000، لذا لا يحصل أبدًا على no_credits أو number_daily_cap_reached.
  • تتقدّم حالتها من تلقاء نفسها: queued، ثم sent بعد 5 ثوانٍ، وdelivered بعد 15 ثانية من إنشائها (تُحسب من send_at للرسالة المجدولة). والرسالة التي يحلّ expires_at الخاص بها قبل موعد إرسالها تصبح expired. ولا تصبح رسائل الاختبار أبدًا read أو failed.
  • لا يرى مفتاح الاختبار إلا رسائل الاختبار الخاصة به. يعرضها GET /messages وGET /messages/{id} ولا شيء غيرها، ويلغي DELETE /messages/{id} إحداها ما دامت queued أو scheduled. ولا ترى المفاتيح الفعلية رسائل الاختبار أبدًا. عامل التصفية status في GET /messages غير مدعوم لمفاتيح الاختبار ويُرجع test_mode_unsupported؛ أما number وsince وuntil فتعمل.
  • تُرفض عمليات الكتابة الأخرى مع 403 test_mode_unsupported: ربط رقم، وإنشاء التذكيرات أو تغييرها أو حذفها، ورفع الوسائط أو حذفها، وبدء فحص أرقام، وإضافة نقاط استقبال webhook أو إزالتها أو تدوير سرّها أو اختبارها.
  • لا تُرسَل أحداث webhook لرسائل الاختبار.
  • تُحفظ رسائل الاختبار 30 يومًا.

الموارد#

  • الرسائل: أرسل الآن أو لاحقًا، وأرسل إلى ما يصل إلى 1,000 مستلم، واقرأ السجل، وألغِ.
  • الأرقام: اعرض أرقام WhatsApp وحسابات Telegram الخاصة بك، واربط رقم WhatsApp برمز QR أو برمز الربط.
  • التذكيرات: رسائل متكررة وفق جدول cron.
  • الوسائط: ارفع الملفات مرة واحدة وأرسلها باستخدام media_id.
  • فحص الأرقام: اعرف أي الأرقام على WhatsApp.
  • Webhooks: أحداث موقّعة عندما تُرسَل رسالة أو تفشل أو تُلغى أو تنتهي صلاحيتها.
  • الأخطاء: كل رموز الأخطاء.
  • الانتقال من v1 إلى v2: كل نقطة نهاية وحقل في v1، وما يقابله في v2.