التحقق من الأرقام
سؤال واتساب عمّا إذا كان الرقم موجودًا، عبر قناة متصلة. وهو جواب عن لحظة بعينها ولا يضمن التسليم أبدًا — ويجيب بثلاث حالات لا اثنتين.
الاستعلام
يستهلك جلسة القناة الحيّة، ولذلك فهو محدود بـ 60 طلبًا في الدقيقة لكل مساحة عمل وليس مما يُستدعى مع كل ضغطة مفتاح. وحذف channel_id يترك للواجهة اختيار قناة مؤهلة.
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
| numbers | string[] | مطلوب | الأرقام المطلوب فحصها، بصيغة E.164. |
| channel_id | string | اختياري | القناة التي يُسأل عبرها. وتُختار لك عند حذفها. |
يتطلب contacts.read وmessages.send معًا — وهو أحد عمليتين فقط في الواجهة كلها تسمّيان نطاقين، لأن الاستعلام يستهلك قناة إرسال. انظر المصادقة.
الأجوبة الثلاثة
| الحالة | الوصف |
|---|---|
| exists | الرقم مسجّل على واتساب. |
| not_exists | الرقم غير مسجّل. |
| unknown | لم يُحسم الاستعلام. وهذا ليس جوابًا عن الرقم. |
unknown ليست not_exists مخفّفة
هذه أهم حقيقة في هذه الصفحة. فالعميل الأساسي يرشّح الأرقام غير الموجودة ولا يعيد شيئًا لاستعلام عاد فارغًا، فيصل الاثنان بالغياب نفسه. اعرض ثلاثة أجوبة بثلاث نبرات، ولا تجمع unknown مع not_exists أبدًا — فمعاملة استعلام لم يُحسم كرقم ميت تحذف عملاء حقيقيين من القائمة بصمت.
| reason | الوصف |
|---|---|
| invalid_number | الرقم ليس رقم E.164 صالحًا أصلًا. |
| lookup_failed | أخفق الاستعلام نفسه. |
| no_answer | لم تُعِد القناة شيئًا لهذا الرقم. |
| timeout | لم يُجب الاستعلام في الوقت المحدد. |
curl -X POST https://whats.azzamkh.sa/api/v1/contacts/validate \
-H "Authorization: Bearer $WA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "numbers": ["+9665XXXXXXXX", "+9665YYYYYYYY"], "channel_id": "ch_..." }'
# 200 OK
# {
# "channel_id": "ch_...",
# "results": [
# { "e164": "+9665XXXXXXXX", "status": "exists" },
# { "e164": "+9665YYYYYYYY", "status": "unknown",
# "reason": "no_answer" }
# ],
# "summary": { "checked": 2, "exists": 1, "not_exists": 0, "unknown": 1 }
# }
# A refused LOOKUP is not an answer about the number:
# 409 { "error": { "code": "CHANNEL_NOT_CONNECTED", ... } }يعدّ summary القيم checked وexists وnot_exists وunknown. والأربع منفصلة، ومجموع الثلاث الأخيرة يساوي checked.
ما لا يخبرك به
- الفحص قدرة على القناة:
check_number. وهو صحيح على QR والمهايئات المحاكاة وخاطئ على Meta. وغيابه يعني ألا تعرض الفحص، لا أن الفحص سيفشل — انظر القنوات. - الوجود ليس موافقة. فالرقم الموجود الذي ليست حالته
opted_inتُرفض له الرسالة التسويقية. - الجواب صحيح في لحظة السؤال. ولا شيء منه مخزَّن نيابةً عنك، ولا شيء منه وعد بالتسليم.
- الاستعلام المرفوض ليس جوابًا عن الرقم أبدًا. فـ
CHANNEL_NOT_CONNECTEDوRATE_LIMITEDوFEATURE_TEMPORARILY_UNAVAILABLEكلها تعني أن الفحص تعذّر، ولا مكان لأيٍّ منها في صندوق الكتابة كخطأ أحمر على المستلم. - 60 طلبًا في الدقيقة لكل مساحة عمل، مهما كان حجم الدفعة.
فحص الحملة
تجري الحملة الاستعلام نفسه على عيّنة محدودة من جمهورها المُحلّ، كجزء اختياري من فحص ما قبل الإطلاق. أرسل validate_numbers: true — فهو لا يُفهم ضمنًا من validate أبدًا، تحديدًا لأنه يستهلك جلسة القناة الحيّة. انظر الحملات.
كتلة number_check
| الحقل | الوصف |
|---|---|
| status | checked أو unavailable أو unsupported. والأولى وحدها تحمل نتيجة حقيقية. |
| sampled, eligible | كم رقمًا أُخذ في العيّنة، وكم كان مؤهلًا لأخذ العيّنة منه. |
| summary | الأعداد الأربعة نفسها كما في الاستعلام المباشر. |
| results | المدخلات لكل رقم، حين تكون العيّنة صغيرة بما يكفي لإعادتها. |
| truncated, results_truncated | هل اقتُطعت العيّنة أو اقتُطعت النتائج المعادة. |
يبلّغ ولا يمنع
وجود not_exists في العيّنة لا يخرج أحدًا من ready. فالكتلة موجودة ليقرر إنسان، لا لتقرر المنصّة عنه — ولأن العيّنة محدودة، فنسبها تقدير على الجمهور لا حكم عليه.
الأخطاء المهمة هنا
| الرمز | HTTP | متى يحدث |
|---|---|---|
| CHANNEL_NOT_CONNECTED | 409 | القناة غير متصلة، فلا يمكن إجراء استعلام. |
| CHANNEL_NOT_FOUND | 404 | لا توجد قناة بهذا المعرّف، أو لا قناة مؤهلة عند حذف channel_id. |
| FEATURE_TEMPORARILY_UNAVAILABLE | 503 | القدرة موقوفة مؤقتًا. وقابل لإعادة المحاولة. |
| RATE_LIMITED | 429 | أكثر من 60 استعلامًا في الدقيقة. |
| VALIDATION_ERROR | 422 | رقم ليس E.164 صالحًا، أو دفعة فارغة. |
كل رمز وحالته في صفحة الأخطاء.