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"import os
import requests
response = requests.get(
"https://wbiztool.com/api/v2/me",
headers={"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"},
timeout=30,
)
print(response.status_code, response.json())// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/me", {
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
console.log(response.status, await response.json());<?php
$ch = curl_init('https://wbiztool.com/api/v2/me');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), "\n";
print_r($body);
curl_close($ch);{
"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 أو مسار أو جسم مختلف يُرجع
422idempotency_key_reused. - ما زال قيد التنفيذ: ما دام الطلب الأول بهذه القيمة قيد المعالجة، تُرجع إعادة المحاولة
409idempotency_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 واحد تُرجع
429too_many_auth_failuresمعRetry-After: 60. - الرسائل لكل رقم: يرسل الرقم 1,000 رسالة على الأكثر خلال 24 ساعة (الاستخدام العادل). والإرسال الذي يتجاوز ذلك يُرجع
429number_daily_cap_reached.
التقسيم إلى صفحات#
تأتي القوائم التي يمكن أن تكبر (GET /messages و/reminders و/media و/number-checks و/results لفحص ما) في صفحات، الأحدث أولًا:
{
"data": [ … ],
"next_cursor": "eyJpZCI6OTgxNzI2MywidCI6IjIwMjYtMTAtMThUMTA6MTU6MDIuMzExWiIsImYiOiI0NGIxMzZmYTM1NWIifQ"
}
-
limitيحدّد حجم الصفحة، من 1 إلى 100 (الافتراضي 25). - للحصول على الصفحة التالية، أرسل الطلب نفسه مع
cursorمضبوطًا علىnext_cursorمن الصفحة السابقة. وتكون قيمةnext_cursorهيnullفي الصفحة الأخيرة. - أبقِ عوامل التصفية الأخرى كما هي: المؤشر المستخدم مع عوامل تصفية مختلفة يُرجع
400invalid_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فتعمل. - تُرفض عمليات الكتابة الأخرى مع
403test_mode_unsupported: ربط رقم، وإنشاء التذكيرات أو تغييرها أو حذفها، ورفع الوسائط أو حذفها، وبدء فحص أرقام، وإضافة نقاط استقبال webhook أو إزالتها أو تدوير سرّها أو اختبارها. - لا تُرسَل أحداث webhook لرسائل الاختبار.
- تُحفظ رسائل الاختبار 30 يومًا.
الموارد#
- الرسائل: أرسل الآن أو لاحقًا، وأرسل إلى ما يصل إلى 1,000 مستلم، واقرأ السجل، وألغِ.
- الأرقام: اعرض أرقام WhatsApp وحسابات Telegram الخاصة بك، واربط رقم WhatsApp برمز QR أو برمز الربط.
- التذكيرات: رسائل متكررة وفق جدول cron.
- الوسائط: ارفع الملفات مرة واحدة وأرسلها باستخدام
media_id. - فحص الأرقام: اعرف أي الأرقام على WhatsApp.
- Webhooks: أحداث موقّعة عندما تُرسَل رسالة أو تفشل أو تُلغى أو تنتهي صلاحيتها.
- الأخطاء: كل رموز الأخطاء.
- الانتقال من v1 إلى v2: كل نقطة نهاية وحقل في v1، وما يقابله في v2.
