للمطوّرين
نداءان بينك وبين مستخدم موثّق.
أرسل الرمز بطلب verify/start، وتحقق منه بطلب verify/check.
توكيد للتحقق واجهة API لرموز OTP في السعودية.
بوابة المطوّرين الكاملةأدلة، ومرجع تفاعلي تستدعيه من الصفحة، وكل صفحة بصيغة Markdown، وخادم MCP لمساعدك البرمجي، بالإنجليزية.فتح docs.tawked.comالبداية السريعة
- 01
أنشئ مفتاح API
أنشئ مفتاح tk_test_ من تبويب «المفاتيح» في تطبيقك. يعمل قبل اعتماد التطبيق.
- 02
أرسل الرمز
أرسل طلب POST إلى /v1/verify/start برقم الوجهة، فيعود إليك id وموعد الانتهاء.
- 03
تحقق من الرمز
أرسل طلب POST إلى /v1/verify/check بالمعرّف نفسه والرمز الذي كتبه المستخدم.
القنوات
تُتاح رموز التحقق عبر واتساب قريبًا، ورسائل SMS تعمل اليوم. ولرسائل قوالب واتساب، مثل تحديثات الطلبات والتذكيرات، نقطتها الخاصة أدناه، من رقمك المربوط.
| القناة | قيمة channel | صيغ الوجهة المقبولة | ملاحظات | السعر |
|---|---|---|---|---|
| SMS | sms | +966512345678, 966512345678, 00966512345678, 0512345678, 512345678 | تُحوَّل أي صيغة محلية تلقائيًا إلى +9665XXXXXXXX قبل الإرسال. | 0.09 ر.س لكل رمز يُرسَل |
المصادقة
مرّر مفتاحك في ترويسة Authorization بصيغة Bearer، أو في ترويسة x-api-key إن تعذّر ذلك. وإن وُجدت الترويستان فالأولوية لترويسة Authorization.
المفتاح الفعلي
Authorization: Bearer tk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6مفتاح التجربة
Authorization: Bearer tk_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6مفتاح الشريك
Authorization: Bearer tk_partner_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6يمرّر مفتاح الشريك التطبيق في حقل application داخل جسم الطلب، أو في حقل service باسمه القديم، لأن مفتاحًا واحدًا يغطي كل متاجر الشريك.
تعزيز المفاتيح ونطاق صلاحياتها
تُضبط عند إنشاء المفتاح من اللوحة، وكلها اختيارية.
- الحقل expires_at اختياري: بعد انقضائه يعيد كل استدعاء بهذا المفتاح 401 key_expired، ويُفحص فور التعرف على المفتاح قبل أي شيء آخر.
- الحقل ip_allowlist اختياري: عناوين IP محددة أو نطاقات CIDR، بصيغتي IPv4 وIPv6. وإن كان فارغًا أو غائبًا سُمح لكل العناوين، ويُرد على المستدعي من خارجه بالخطأ 403 ip_not_allowed.
- الصلاحية: للمفتاح صلاحية كاملة، تشمل كل المنتجات وما يُضاف لاحقًا، أو صلاحية مخصّصة تقتصر على ما مُنح له من كل منتج. التحقق: «بلا» أو «تحقق فقط» أو «إرسال وتحقق». الإشعارات: «بلا» أو «قراءة فقط» أو «إرسال». وأيًّا كانت صلاحيته يبقى المفتاح سرًّا في خادمك: لا تضعه في متصفح ولا في تطبيق جوال.
- وراء هذه المستويات أربع صلاحيات. تتيح verify:check استدعاء POST /v1/verify/check، GET /v1/verify/{id}. وتتيح verify:send استدعاء POST /v1/verify/start، POST /v1/verify/{id}/resend، POST /v1/verify/{id}/cancel، وتشمل verify:check. وتتيح notifications:read استدعاء GET /v1/whatsapp/messages/{id}، GET /v1/whatsapp/templates، GET /v1/whatsapp/templates/{template_id}. وتتيح notifications:send استدعاء POST /v1/whatsapp/messages، وتشمل notifications:read. وصلاحية خامسة ليست من مستويات تلك الصفحة: تتيح notifications:templates استدعاء POST /v1/whatsapp/templates، PATCH /v1/whatsapp/templates/{template_id}، DELETE /v1/whatsapp/templates/{template_id}، وتشمل notifications:read. لا يحملها أي مفتاح يُنشأ من صفحة «مفاتيح API»، ولو كان بصلاحية كاملة، فتعيد هذه الاستدعاءات الثلاثة لمثله 403 insufficient_scope. ويحملها مفتاح التطبيق المربوط.
- الاستدعاء الخارج عن صلاحية المفتاح يعيد 403 بالجسم {"error":"insufficient_scope"}، وتذكر ترويسة الاستجابة الصلاحية التي يحتاج إليها: WWW-Authenticate: Bearer error="insufficient_scope", scope="verify:send". ويُفحص ذلك فور التعرف على المفتاح، بعد الأخطاء unauthorized، key_expired، ip_not_allowed، وقبل account_not_active وشكل الطلب.
- مفتاح «تحقق فقط» المُنشأ قبل تحديد الصلاحية لكل منتج يعمل كما كان: يحمل verify:check، notifications:read، فيتحقق من الرموز ويقرأ الحالات والقوالب في المنتجين، ولا يرسل في أي منهما.
- لا يُمنح مفتاح التجربة صلاحية على الإشعارات: لا بيئة تجربة لواتساب، وترفض /v1/whatsapp/* كل مفتاح تجربة.
- البريد: «بلا» أو «قراءة فقط» أو «إرسال». تتيح email:read استدعاء GET /v1/email/messages/{id}. وتتيح email:send استدعاء POST /v1/email/messages، وتشمل email:read. ولا يُمنح مفتاح التجربة صلاحية على البريد: لا بيئة تجربة للبريد، وترفض /v1/email/* كل مفتاح تجربة.
- تُضبط عند إنشاء المفتاح من صفحة «مفاتيح API» للتطبيق في لوحة العميل (إنشاء مفتاح). ولا تتغير صلاحية المفتاح بعد إنشائه: أنشئ مفتاحًا جديدًا بالصلاحية التي تحتاج إليها. ويستطيع الشريك عند تدوير مفتاحه ضبط تاريخ الانتهاء والقائمة المسموحة أيضًا، ومفتاح الشريك بصلاحية كاملة دائمًا، ولا يُقيَّد بمنتج.
بيئة التجربة
أنشئ مفتاح tk_test_ من اللوحة قبل اعتماد التطبيق. يستخدم نقاط النهاية وصيغ الطلبات نفسها.
tk_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6- تنشئه بنفسك قبل اعتماد التطبيق: من صفحة «مفاتيح API» للتطبيق (إنشاء مفتاح، من نوع تجربة)، أو يُنشأ لك عند أول إرسال من «التحقق ← التجربة» في اللوحة.
- يستدعي النقاط نفسها بأشكال الطلب والاستجابة نفسها.
- يرسل رسائل حقيقية، لكن إلى رقم واحد فقط: جوال مالك الحساب الذي وثّقه عند التسجيل، ولا تُضاف وجهات أخرى.
- تحمل كل رسالة ختمًا ثابتًا لا يُحذف: [تجريبي] في الرسالة العربية، والختم [TEST] في الإنجليزية.
- يُخصم من الرصيد المسبق نفسه كأي إرسال آخر، بسقف مدى الحياة لكل تطبيق قدره 10، حتى لا تستهلك التجربة الرصيد الترحيبي كله.
- لا بيئة تجربة لواتساب: ترفض /v1/whatsapp/* كل مفتاح تجربة بالخطأ 403 live_key_required، أو 403 insufficient_scope لمفتاح التجربة ذي الصلاحية المخصّصة، إذ لا يحمل صلاحية الإشعارات أبدًا.
رسائل جاهزة للإكمال التلقائي
يُشتق نطاق الإكمال التلقائي من موقع تطبيقك بعد المراجعة. أضف بصمة تطبيق أندرويد لدعم SMS Retriever من Google، إلى جانب iOS AutoFill ومعيار WebOTP.
- لا يُكتب النطاق يدويًا: يُشتق autofill_domain من موقع التطبيق بعد مراجعته، أي النطاق الأساسي فتُغطى النطاقات الفرعية، ويظهر للقراءة فقط في كل استجابة. ويشغّل autofill_domain_enabled سطره أو يوقفه، ويُضبط android_app_hash، وطوله 11 حرفًا، لكل تطبيق من اللوحة أو عبر واجهة الشركاء عند الإنشاء وفي تعديل إعدادات التحقق.
- يضيف سطر @domain #code نحو 25 حرفًا. والرسالة العربية تُحسب بمقاطع من 70 حرفًا، فقد يحوّلها السطر من مقطع إلى مقطعين، ولذلك تعرض معاينة اللوحة عدد المقاطع، وللسطر مفتاح تشغيل.
- يُضاف إلى الرسالة بعد نصها: سطر بصمة تطبيق أندرويد إن كانت مضبوطة والهدف أندرويد، ثم @النطاق #الرمز آخر سطر إن كان النطاق مضبوطًا والهدف الويب.
- يقرأ iOS AutoFill وWebOTP آخر سطر في الرسالة فقط، ولهذا يأتي سطر النطاق دائمًا أخيرًا بعد سطر بصمة التطبيق.
- تحتاج خدمة SMS Retriever من Google إلى وجود البصمة في أي مكان من الرسالة، وأن يبقى حجمها كله أقل من 140 بايت. ونص GSM-7 بايت واحد لكل حرف، وأي حرف خارجه، ومنه أغلب العربية، بايتان.
- يحدد الحقل الاختياري autofill في start، بقيمة web أو android أو none، السطر الذي يُرسل في هذه العملية وحدها. اتركه فارغًا لإرسال كل الأسطر المفعّلة للتطبيق.
- يأتي ختم التجربة، إن وُجد، أولًا دائمًا قبل أي سطر إكمال تلقائي.
- لا ينطبق على واتساب: رسالته قالب ثابت من Meta لا يتسع لأي من السطرين.
مثال رسالة أقل من 140 بايت
Your Flower Shop verification code is: 482913 FA+9qCX9VSu @shop.example.com #482913
نقاط النهاية
/v1/verify/startبدء عملية تحقق
يرسل رمزًا لمرة واحدة إلى وجهة، ويعيد id تتحقق به منه.
المعاملات
tostringمطلوبالوجهة. أي صيغة من الصيغ السعودية المقبولة أدناه.
phonestringاختيارياسم بديل قديم للحقل to، أُبقي للتكاملات السابقة. يُستخدم فقط إن غاب to أو كان فارغًا، والأولوية للحقل to إن وُجد الاثنان. والتكاملات الجديدة تستخدم to.
channelstringاختياريقناة التسليم، وقيمتها sms إن غابت أو كانت فارغة. أما whatsapp فتُرفض بالخطأ unsupported_channel حتى يفتح توكيد واتساب للرموز لكل الحسابات.
langstringاختياريلغة الرسالة. القيمة en وحدها تختار الإنجليزية، وأي قيمة أخرى أو غيابها يعني العربية.
applicationstringمفتاح الشريكلمفاتيح الشركاء فقط: التطبيق المرسِل من تطبيقاتك المزوَّدة. ويُقبل الاسم القديم service بالمعنى نفسه.
referencestringاختياريمرجعك، مثل رقم طلب أو معرّف عملية، حتى 64 حرفًا قابلًا للطباعة. يعود في رد start وفي GET /v1/verify/{id}، وتبحث به في قائمة عمليات التحقق في اللوحة.
client_ipstringاختياريعنوان IP للمستخدم النهائي. يفعّل حارس الحماية لكل IP لهذا التطبيق إن كان مضبوطًا، ولا يُستنتج من الطلب أبدًا، بل يُمرَّر صراحةً.
autofillstringاختياريالقيمة web أو android أو none، وتحدد سطر الإكمال التلقائي في هذا الإرسال: يرسل web سطر @النطاق #الرمز وحده، ويرسل android سطر بصمة التطبيق وحده، ولا يرسل none أيًا منهما. اتركه فارغًا لإرسال كل الأسطر المفعّلة للتطبيق.
الترويسات
Idempotency-Keystringاختياريمفتاح تولّده أنت، من 1 إلى 128 حرف ASCII قابلًا للطباعة، مرتبط بمفتاح API لديك، وبالتطبيق المحدد أيضًا لمفاتيح الشركاء. تكرار المفتاح نفسه يعيد استجابة 201 الأصلية كما هي، مع ترويسة الاستجابة Idempotent-Replayed: true، بلا إرسال أو خصم جديد. والإرسال الذي يفشل يحرّر المفتاح لتعيد المحاولة.
الاستجابة
{
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "pending",
"expires_at": "2026-09-01T12:34:56.789Z"
}مثال الطلب
curl -X POST https://tawked.com/v1/verify/start \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "0551234567",
"channel": "sms",
"lang": "ar"
}'/v1/verify/checkالتحقق من رمز
يتحقق من الرمز الذي كتبه المستخدم مقابل id الذي أعاده verify/start.
المعاملات
idstringمطلوبالمعرّف id الذي أعاده verify/start.
codestringمطلوبالرمز الذي كتبه المستخدم، ويُقارَن كما وصل تمامًا بلا قص للمسافات، فالمسافة الزائدة تمنع التطابق.
applicationstringمفتاح الشريكلمفاتيح الشركاء فقط، بمعنى verify/start نفسه. ولا يتحقق المفتاح إلا من رمز بدأ تحت التطبيق نفسه.
الاستجابة
{
"verified": true,
"status": "verified"
}{
"verified": false,
"status": "invalid_code",
"attempts_remaining": 2
}{
"verified": false,
"status": "too_many_attempts",
"attempts_remaining": 0
}{
"verified": false,
"status": "failed"
}{
"verified": false,
"status": "expired"
}{
"verified": false,
"status": "canceled"
}{
"error": "not_found"
}مثال الطلب
curl -X POST https://tawked.com/v1/verify/check \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"code": "482913"
}'/v1/verify/{id}قراءة عملية تحقق
يعيد الحالة الحالية لعملية تحقق، أي الحالة والقناة والوجهة وعدد المحاولات والإعادات المتبقية، دون استهلاك أي محاولة.
المعاملات
applicationstringمفتاح الشريكلمفاتيح الشركاء فقط: يُمرَّر معاملًا في الرابط ?application=… لأن طلب GET بلا جسم، بمعنى start نفسه، ويُقبل الاسم القديم service.
الاستجابة
{
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "pending",
"channel": "sms",
"to": "+966551234567",
"reference": "order-42",
"attempts_remaining": 3,
"resends_remaining": 3,
"expires_at": "2026-09-01T12:34:56.789Z",
"verified_at": null,
"created_at": "2026-09-01T12:29:56.789Z"
}{
"error": "not_found"
}مثال الطلب
curl https://tawked.com/v1/verify/b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44 \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"/v1/verify/{id}/resendإعادة إرسال رمز
يرسل رمزًا جديدًا على المعرّف نفسه: يتوقف الرمز السابق، وتُصفَّر المحاولات وتتجدد الصلاحية، ويُخصم الإرسال ويخضع لحدود المعدل كأي إرسال آخر، بحد أقصى 3 إعادات لكل عملية تحقق.
المعاملات
applicationstringمفتاح الشريكلمفاتيح الشركاء فقط، بمعنى start نفسه.
الاستجابة
{
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "pending",
"expires_at": "2026-09-01T12:39:56.789Z",
"resends_remaining": 2
}{
"error": "not_resendable",
"status": "verified"
}{
"error": "resend_limit_reached"
}مثال الطلب
curl -X POST https://tawked.com/v1/verify/b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44/resend \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"/v1/verify/{id}/cancelإلغاء عملية تحقق
يلغي عملية تحقق قيد الانتظار، ويعيد أي check لاحق عليها { "verified": false, "status": "canceled" }.
المعاملات
applicationstringمفتاح الشريكلمفاتيح الشركاء فقط، بمعنى start نفسه.
الاستجابة
{
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "canceled"
}{
"error": "not_cancelable",
"status": "verified"
}مثال الطلب
curl -X POST https://tawked.com/v1/verify/b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44/cancel \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"رسائل واتساب
أرسل قالب واتساب معتمدًا من رقمك المربوط بتطبيقك، بالمفتاح الفعلي للتطبيق. يتحقق توكيد من القالب مقابل قائمة قوالب الرقم الحالية، ويخصم الرسوم، ويرسل عبر Meta نيابة عنك، ويسجّل الرسالة، ويعرضها في محادثة توكيد شات، ويتابع التسليم والقراءة، ولا يحمل نظامك أي رمز وصول من Meta. ويستطيع أي تطبيق قيد المراجعة أو معتمد ربط حسابه على واتساب للأعمال من اللوحة.
خطوات البدء
أربع خطوات من الصفر إلى أول رسالة، ثلاث منها في اللوحة.
- 01
اربط رقمك
من اللوحة: التطبيقات، ثم تطبيقك، قيد المراجعة أو معتمدًا، ثم الإشعارات، ثم «ربط واتساب»، ويربطه المالك أو أحد المديرين. تفتح Meta نافذة تختار فيها النشاط والرقم أو تنشئهما، ويسجّل توكيد الرقم ويجهّز صندوق الوارد هنا. وتحتفظ بصلاحيتك الكاملة في WhatsApp Manager وتدفع إلى Meta مباشرة مقابل الرسائل.
- 02
أنشئ قالبًا
من صفحة القوالب في التطبيق، أو من مكتبة قوالب Meta، أو من WhatsApp Manager. تراجعه Meta في 24 ساعة على الأكثر، والقالب المعتمد وحده يُرسل. وتعمل هنا قوالب الخدمة والتسويق والمصادقة، وقالب المصادقة يرسل رمز تحقق من رقمك.
- 03
استخدم المفتاح الفعلي للتطبيق
من اللوحة: التطبيقات، ثم تطبيقك، ثم المفاتيح. يحتاج إرسال واتساب مفتاح tk_live_ للتطبيق المربوط بالرقم، بصلاحية كاملة أو بمستوى «إرسال» في الإشعارات، ويُرفض مفتاح tk_test_، فلا بيئة تجربة لواتساب.
- 04
اعرض القوالب ثم أرسل
يعرض GET /v1/whatsapp/templates كل قالب مع متغيراته. ويرسل POST /v1/whatsapp/messages رسالة بالحقول to وtemplate وparams، والرد 202 مع id. اقرأ الحالة عبر GET /v1/whatsapp/messages/{id}، أو استقبل ويبهوك message.*.
/v1/whatsapp/messagesإرسال رسالة قالب
يرسل قالبًا معتمدًا إلى جوال سعودي من الرقم المربوط بالتطبيق، ويرد 202 مع id تتابع به الرسالة. والرسوم، إن وُجدت، مقابل الإرسال، ويُعاد الخصم عن الإرسال الفاشل.
المعاملات
tostringمطلوبالوجهة: جوال سعودي بأي صيغة من الصيغ المقبولة، ويُحفظ بالصيغة الدولية.
templatestringمطلوباسم القالب كما يظهر في WhatsApp Manager، من 1 إلى 512 حرفًا. ويجب أن يكون معتمدًا في حساب واتساب للأعمال للرقم.
langstringاختياريلغة القالب كما تسجّلها Meta، مثل ar أو en أو en_US. مطلوبة إن كان القالب بأكثر من لغة.
paramsobjectاختياريقيم متغيرات نص الرسالة: المفاتيح أسماء المتغيرات في القالب المسمّى مثل {{name}}، أو "1" و"2" في القالب المرقّم مثل {{1}}. كل متغير مطلوب، وتُرفض المفاتيح الزائدة، والقيم نصوص من 1 إلى 1024 حرفًا. ويأخذ قالب المصادقة { "code": "…" } وحده، من 4 إلى 15 حرفًا أو رقمًا، فيملأ نصه وزره. ويعرض GET /v1/whatsapp/templates متغيرات كل قالب.
headerobjectاختياري{ "text": "…" }: قيمة متغير الترويسة النصية، مطلوبة إن كان في القالب متغير ترويسة ومرفوضة إن لم يكن، وبلا أسطر جديدة. وللقالب الذي يبدأ بصورة: { "image": { "link": "https://…" } }، رابط الصورة العام بـ https، حتى 2048 حرفًا، لصورة JPG أو PNG حتى 5 ميجابايت تجلبها Meta عند الإرسال؛ مطلوب لمثل هذا القالب ومرفوض لغيره. وترويسات الفيديو والمستندات والمواقع غير مدعومة بعد.
buttonsarrayاختياري[{ "index": 0, "parameter": "…" }]: اللاحقة المتغيرة لكل زر رابط، عنصر واحد لكل زر فيه متغير، وindex ترتيب الزر بين أزرار القالب. وتُرفض مع قالب المصادقة، فالقيمة params.code تملأ زره.
referencestringاختياريمرجعك، مثل رقم طلب أو معرّف حدث، من 1 إلى 64 حرفًا قابلًا للطباعة. يعود إليك في الرد، وتبحث به في سجل الرسائل في اللوحة.
الترويسات
Idempotency-Keystringاختياريمفتاح تولّده أنت، من 1 إلى 128 حرف ASCII قابلًا للطباعة، مرتبط بمفتاح API لديك. تكرار المفتاح نفسه يعيد استجابة 202 الأصلية كما هي، مع ترويسة الاستجابة Idempotent-Replayed: true، بلا إرسال أو خصم جديد. والإرسال الذي يفشل بخطأ 502 يحرّر المفتاح. استخدم مفتاحًا لكل حدث تجاري، مثل order-1042-received، وأعد المحاولة بالمفتاح نفسه عند 502 أو خطأ في الشبكة.
الاستجابة
{
"id": "0f4c9c0e-6d2b-4b8a-9c3e-7a1d2e3f4a5b",
"status": "accepted",
"to": "+966550000000",
"template": "order_received",
"lang": "ar",
"reference": "order-30517",
"price_halalas": 0,
"created_at": "2026-09-06T12:00:00+03:00"
}{
"error": "unknown_template"
}{
"error": "insufficient_credits",
"message": "Insufficient credits",
"balance_halalas": 0,
"price_halalas": 9
}مثال الطلب
curl -X POST https://tawked.com/v1/whatsapp/messages \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-30517-received" \
-d '{
"to": "0550000000",
"template": "order_received",
"lang": "ar",
"params": {
"customer_name": "سارة",
"order_number": "30517"
},
"reference": "order-30517"
}'/v1/whatsapp/messages/{id}قراءة رسالة
يعيد الحالة الحالية للرسالة وأوقاتها. تُتابَع حالات Meta 48 ساعة بعد الإرسال، ويُضبط error إن فشلت الرسالة. والرسالة تخص تطبيق المفتاح، وأي id آخر يعيد 404.
المعاملات
الاستجابة
{
"id": "0f4c9c0e-6d2b-4b8a-9c3e-7a1d2e3f4a5b",
"status": "delivered",
"to": "+966550000000",
"template": "order_received_v1",
"lang": "ar",
"reference": "order-1042",
"price_halalas": 0,
"error": null,
"created_at": "2026-09-06T12:00:00+03:00",
"sent_at": "2026-09-06T12:00:01+03:00",
"delivered_at": "2026-09-06T12:00:04+03:00",
"read_at": null,
"failed_at": null
}{
"id": "0f4c9c0e-6d2b-4b8a-9c3e-7a1d2e3f4a5b",
"status": "failed",
"to": "+966550000000",
"template": "order_received_v1",
"lang": "ar",
"reference": "order-1042",
"price_halalas": 0,
"error": {
"code": "131026",
"message": "Message undeliverable"
},
"created_at": "2026-09-06T12:00:00+03:00",
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": "2026-09-06T12:00:03+03:00"
}{
"error": "not_found"
}مثال الطلب
curl https://tawked.com/v1/whatsapp/messages/0f4c9c0e-6d2b-4b8a-9c3e-7a1d2e3f4a5b \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"/v1/whatsapp/templatesقائمة القوالب
يعرض قوالب حساب واتساب للأعمال للرقم كما تحفظها Meta، مع متغيرات كل قالب، فيعرف نظامك ما يرسله دون WhatsApp Manager. ويحمل كل صف id القالب لدى Meta، وهو ما تأخذه عمليات القوالب، والحقل managed، وقيمته true حين يكون المفتاح مفتاح تطبيق مربوط أنشأ هذا القالب عبر هذا التطبيق نفسه. ويُخزَّن مؤقتًا 5 دقائق.
المعاملات
الاستجابة
{
"data": [
{
"id": "7000",
"name": "order_received_v1",
"language": "ar",
"category": "UTILITY",
"status": "APPROVED",
"placeholders": {
"kind": "named",
"header": [],
"body": [
"name",
"order"
],
"buttons": [
{
"index": 0,
"type": "url"
}
]
},
"managed": false
}
]
}مثال الطلب
curl https://tawked.com/v1/whatsapp/templates \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"/v1/whatsapp/templates/{template_id}قراءة قالب
يقرأ قالبًا واحدًا كاملًا بمعرّفه لدى Meta: حالته وجودته وسبب رفضه، ومكوّناته كما تحفظها Meta، وقيم الأمثلة، والمتغيرات التي يملؤها الإرسال، والحقل managed. والمعرّف غير الموجود في حساب واتساب للأعمال للرقم يعيد 404.
المعاملات
الاستجابة
{
"id": "7000",
"name": "order_received_v1",
"language": "ar",
"category": "UTILITY",
"status": "APPROVED",
"quality": "GREEN",
"rejected_reason": null,
"components": [
{
"type": "HEADER",
"format": "TEXT",
"text": "طلبك {{1}}",
"buttons": []
},
{
"type": "BODY",
"format": null,
"text": "استلمنا طلبك رقم {{1}} بقيمة {{2}} ريال.",
"buttons": []
},
{
"type": "BUTTONS",
"format": null,
"text": null,
"buttons": [
{
"type": "URL",
"text": "تتبع الطلب",
"url": "https://flowers.example/orders/{{1}}",
"phone_number": null
}
]
}
],
"examples": {
"header:1": "1042",
"body:1": "1042",
"body:2": "250",
"button:0": "1042"
},
"placeholders": {
"kind": "positional",
"header": [
"1"
],
"body": [
"1",
"2"
],
"buttons": [
{
"index": 0,
"type": "url"
}
]
},
"managed": false
}{
"error": "not_found"
}مثال الطلب
curl https://tawked.com/v1/whatsapp/templates/7000 \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"/v1/whatsapp/templatesإنشاء قالب
يتطلب مفتاح تطبيق مربوط (خارجي). مفتاح نشاطك التجاري، حتى بصلاحية كاملة، يعيد 403 insufficient_scope، وتكتب قوالبك من اللوحة. يرسل قالبًا نصيًّا إلى مراجعة Meta بقواعد محرر اللوحة نفسها، ويعيد id القالب لدى Meta، والفئة كما سجّلتها Meta، والحالة status، وهي PENDING في البداية غالبًا. للنص فقط: يُهمل أي حقل غير الحقول أدناه، فالقالب الذي يبدأ بصورة يُنشأ من اللوحة. والحقل المرفوض يعيد 400 invalid_request، وفيه fields بأسماء الحقول وerrors بأسباب كل حقل، وما ترفضه Meta بعد ذلك يعيد 422 template_refused بعبارة Meta نفسها.
المعاملات
namestringمطلوبحروف إنجليزية صغيرة وأرقام وشرطات سفلية، حتى 512 حرفًا. وتثبّته Meta عند الإنشاء. ولا يأخذ مفتاح تطبيق مربوط اسمًا يبدأ بـ salla_ أو zid_ أو wf_، ولا اسمًا من أسماء قوالب توكيد نفسها، ويحمل errors.name عندها القيمة nameReserved.
languagestringمطلوبإحدى القيم ar أو en أو en_US أو en_GB أو ur أو hi أو bn أو tl أو id أو fr. وتثبت عند الإنشاء.
categorystringمطلوبالقيمة UTILITY. يكتب مفتاح التطبيق المربوط قوالب الخدمة وحدها، وتُرفض MARKETING بالخطأ 422 template_category_not_allowed. وقالب المصادقة يُنشأ من اللوحة.
headerstringاختياريترويسة نصية: سطر واحد، حتى 60 حرفًا، بلا رموز تعبيرية ولا علامة النجمة، وبمتغير واحد على الأكثر.
bodystringمطلوبحتى 1024 حرفًا. والمتغيرات كلها مسمّاة مثل {{name}} بحروف صغيرة، أو كلها مرقّمة مثل {{1}} ثم {{2}} بالترتيب، ولا تقع في أول النص ولا في آخره.
footerstringاختياريسطر واحد، حتى 60 حرفًا، بلا متغيرات.
buttonsarrayاختياريحتى 10 عناصر، في كل منها text حتى 25 حرفًا: { "type": "QUICK_REPLY", "text" }، أو { "type": "URL", "text", "url" } برابط https قد ينتهي بالمتغير {{1}} (زرّان على الأكثر)، أو { "type": "PHONE_NUMBER", "text", "phone_number" } برقم بالصيغة الدولية (زر واحد على الأكثر). وتتجاور أزرار الرد السريع، قبل الأزرار الأخرى أو بعدها.
examplesobjectاختياريقيمة مثال لكل متغير، بالمفاتيح header:<key> وbody:<key> وbutton:<index>. مطلوبة كلما كان في القالب متغيرات، فبها تراجعه Meta.
الترويسات
Idempotency-Keystringاختياريمفتاح تولّده أنت، من 1 إلى 128 حرف ASCII قابلًا للطباعة، مرتبط بمفتاح API لديك. تكراره مع الطلب نفسه يعيد استجابة 2xx الأصلية كما هي، مع ترويسة الاستجابة Idempotent-Replayed: true، دون تنفيذ جديد. والمفتاح نفسه مع طلب آخر يعيد 409 idempotency_key_reused، ومع طلب ما زال قيد التنفيذ 409 idempotency_in_progress. والطلب المرفوض لا يُحفظ، فتعمل إعادة المحاولة المصحّحة بالمفتاح نفسه. وتنتهي المفاتيح بعد 24 ساعة.
الاستجابة
{
"id": "7100",
"name": "order_shipped_v1",
"language": "ar",
"category": "UTILITY",
"status": "PENDING"
}{
"error": "invalid_request",
"fields": [
"body",
"examples.header:order"
],
"errors": {
"body": [
"placeholderEdges"
],
"examples.header:order": [
"exampleRequired"
]
}
}{
"error": "template_refused",
"message": "Meta error 100: Template name already exists"
}مثال الطلب
curl -X POST https://tawked.com/v1/whatsapp/templates \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_shipped_v1-ar" \
-d '{
"name": "order_shipped_v1",
"language": "ar",
"category": "UTILITY",
"header": "طلبك {{order}}",
"body": "طلبك {{order}} في الطريق، ويصلك خلال {{days}} أيام.",
"footer": "متجر الورد",
"buttons": [
{
"type": "URL",
"text": "تتبع الشحنة",
"url": "https://flowers.example/track/{{1}}"
}
],
"examples": {
"header:order": "1042",
"body:order": "1042",
"body:days": "3",
"button:0": "1042"
}
}'/v1/whatsapp/templates/{template_id}تعديل قالب
يتطلب مفتاح تطبيق مربوط (خارجي). مفتاح نشاطك التجاري، حتى بصلاحية كاملة، يعيد 403 insufficient_scope، وتكتب قوالبك من اللوحة. يستبدل محتوى قالب نصي لدى Meta. أرسل المحتوى الجديد كاملًا: جسم الإنشاء دون name وlanguage، فقد ثبّتتهما Meta عند الإنشاء ويُهملان هنا. وتراجع Meta التعديل من جديد. ولا يُعدَّل إلا قالب حالته APPROVED أو REJECTED أو PAUSED، وما عداه يعيد 409 template_not_editable مع status: حالة القالب نفسها، أو META_SAMPLE لقالب من نماذج Meta، أو MEDIA_HEADER لقالب يبدأ بصورة أو وسائط أخرى، وهذا يُعدَّل من اللوحة. وقالب المصادقة يعيد 422 template_category_not_allowed. ويعيد الرد القالب كما صار بعد التعديل.
المعاملات
categorystringمطلوبالقيمة UTILITY. يكتب مفتاح التطبيق المربوط قوالب الخدمة وحدها، وتُرفض MARKETING بالخطأ 422 template_category_not_allowed. وقالب المصادقة يُنشأ من اللوحة.
headerstringاختياريترويسة نصية: سطر واحد، حتى 60 حرفًا، بلا رموز تعبيرية ولا علامة النجمة، وبمتغير واحد على الأكثر.
bodystringمطلوبحتى 1024 حرفًا. والمتغيرات كلها مسمّاة مثل {{name}} بحروف صغيرة، أو كلها مرقّمة مثل {{1}} ثم {{2}} بالترتيب، ولا تقع في أول النص ولا في آخره.
footerstringاختياريسطر واحد، حتى 60 حرفًا، بلا متغيرات.
buttonsarrayاختياريحتى 10 عناصر، في كل منها text حتى 25 حرفًا: { "type": "QUICK_REPLY", "text" }، أو { "type": "URL", "text", "url" } برابط https قد ينتهي بالمتغير {{1}} (زرّان على الأكثر)، أو { "type": "PHONE_NUMBER", "text", "phone_number" } برقم بالصيغة الدولية (زر واحد على الأكثر). وتتجاور أزرار الرد السريع، قبل الأزرار الأخرى أو بعدها.
examplesobjectاختياريقيمة مثال لكل متغير، بالمفاتيح header:<key> وbody:<key> وbutton:<index>. مطلوبة كلما كان في القالب متغيرات، فبها تراجعه Meta.
الترويسات
Idempotency-Keystringاختياريمفتاح تولّده أنت، من 1 إلى 128 حرف ASCII قابلًا للطباعة، مرتبط بمفتاح API لديك. تكراره مع الطلب نفسه يعيد استجابة 2xx الأصلية كما هي، مع ترويسة الاستجابة Idempotent-Replayed: true، دون تنفيذ جديد. والمفتاح نفسه مع طلب آخر يعيد 409 idempotency_key_reused، ومع طلب ما زال قيد التنفيذ 409 idempotency_in_progress. والطلب المرفوض لا يُحفظ، فتعمل إعادة المحاولة المصحّحة بالمفتاح نفسه. وتنتهي المفاتيح بعد 24 ساعة.
الاستجابة
{
"id": "7000",
"name": "order_received_v1",
"language": "ar",
"category": "UTILITY",
"status": "PENDING",
"quality": null,
"rejected_reason": null,
"components": [
{
"type": "HEADER",
"format": "TEXT",
"text": "طلبك {{1}}",
"buttons": []
},
{
"type": "BODY",
"format": null,
"text": "استلمنا طلبك رقم {{1}} بقيمة {{2}} ريال، ونبلغك عند شحنه.",
"buttons": []
},
{
"type": "BUTTONS",
"format": null,
"text": null,
"buttons": [
{
"type": "URL",
"text": "تتبع الطلب",
"url": "https://flowers.example/orders/{{1}}",
"phone_number": null
}
]
}
],
"examples": {
"header:1": "1042",
"body:1": "1042",
"body:2": "250",
"button:0": "1042"
},
"placeholders": {
"kind": "positional",
"header": [
"1"
],
"body": [
"1",
"2"
],
"buttons": [
{
"index": 0,
"type": "url"
}
]
},
"managed": false
}{
"error": "template_not_editable",
"status": "PENDING"
}{
"error": "not_found"
}مثال الطلب
curl -X PATCH https://tawked.com/v1/whatsapp/templates/7000 \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_received_v1-ar-2" \
-d '{
"category": "UTILITY",
"header": "طلبك {{1}}",
"body": "استلمنا طلبك رقم {{1}} بقيمة {{2}} ريال، ونبلغك عند شحنه.",
"buttons": [
{
"type": "URL",
"text": "تتبع الطلب",
"url": "https://flowers.example/orders/{{1}}"
}
],
"examples": {
"header:1": "1042",
"body:1": "1042",
"body:2": "250",
"button:0": "1042"
}
}'/v1/whatsapp/templates/{template_id}حذف قالب
يتطلب مفتاح تطبيق مربوط (خارجي). مفتاح نشاطك التجاري، حتى بصلاحية كاملة، يعيد 403 insufficient_scope، وتكتب قوالبك من اللوحة. يحذف هذه اللغة وحدها من القالب لدى Meta. ويُرفض الحذف ما دام شيء يرسل القالب: 409 template_in_use، ويبيّن used_by ما هو. ونماذج Meta نفسها لا تُحذف: 409 template_not_editable مع status بالقيمة META_SAMPLE.
المعاملات
الترويسات
Idempotency-Keystringاختياريمفتاح تولّده أنت، من 1 إلى 128 حرف ASCII قابلًا للطباعة، مرتبط بمفتاح API لديك. تكراره مع الطلب نفسه يعيد استجابة 2xx الأصلية كما هي، مع ترويسة الاستجابة Idempotent-Replayed: true، دون تنفيذ جديد. والمفتاح نفسه مع طلب آخر يعيد 409 idempotency_key_reused، ومع طلب ما زال قيد التنفيذ 409 idempotency_in_progress. والطلب المرفوض لا يُحفظ، فتعمل إعادة المحاولة المصحّحة بالمفتاح نفسه. وتنتهي المفاتيح بعد 24 ساعة.
الاستجابة
{
"id": "7002",
"name": "promo_v1",
"language": "en",
"deleted": true
}{
"error": "template_in_use",
"used_by": [
"campaign",
"automation"
]
}{
"error": "not_found"
}مثال الطلب
curl -X DELETE https://tawked.com/v1/whatsapp/templates/7002 \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"حالات الرسالة
acceptedsentdeliveredreadfailedوقد تأتي الحالة failed بعد أي من الحالات الثلاث الأولى، فتُعاد الرسوم.
- accepted: سجّل توكيد الرسالة واستلمتها Meta، وهي استجابة 202.
- sent وdelivered وread: حالات Meta، تُطبَّق بهذا الترتيب ولا تعود إلى الخلف. تصل إلى توكيد عبر مزامنة الحالات، التي تتابع كل رسالة 48 ساعة بعد إرسالها.
- failed: ممكنة بعد أي من الحالات الثلاث الأولى، مثل رقم لا يمكن الوصول إليه، أو قالب موقوف، أو نافذة مراسلة مغلقة. ويحمل error رمز Meta ورسالتها.
- الرسوم مقابل الإرسال لا التسليم: لا تكلّف read شيئًا إضافيًا، وتعيد failed الرسوم مرة واحدة. وتتوقف متابعة الرسالة بعد 48 ساعة من الإرسال، وتبقى على آخر حالة.
ويبهوك واتساب
message.sentmessage.deliveredmessage.readmessage.failed- حدث واحد لكل تغيير في الحالة إلى رابط ويبهوك التطبيق، موقّع ومُعاد الإرسال مثل verification.* تمامًا: الترويسات tawked-timestamp وtawked-signature وtawked-event نفسها، وHMAC نفسه على "{timestamp}.{raw body}"، وجدول إعادة المحاولة نفسه، وسجل التسليم نفسه في اللوحة.
- غلاف verification.* نفسه: event وdata وsent_at. وحقول الرسالة تحت data، وoccurred_at وقت الحالة التي يعلنها الحدث، وerror قيمته null إلا في message.failed، فيكون عندها { "code", "message" }. وحدث التجربة المرسل من اللوحة هو دائمًا verification.verified، فلا يحمل أي حدث message.* الحقل test.
- يُسلَّم عبر مزامنة الحالات، التي تتابع كل رسالة 48 ساعة بعد إرسالها. ولا يُعلن إلا عن الحالة التي بلغتها الرسالة: الرسالة التي تنتقل مباشرة إلى read تنال حدث message.read واحدًا، بلا الحالات التي بينهما.
- يُعرض to مقنّعًا كما في اللوحة. احتفظ بنسختك من الوجهة بجانب id المعاد أو reference.
مثال المحتوى
{
"event": "message.delivered",
"data": {
"id": "0f4c9c0e-6d2b-4b8a-9c3e-7a1d2e3f4a5b",
"status": "delivered",
"application_id": "c2a10f3e-8b7a-4d2e-9c1a-1a2b3c4d5e6f",
"to": "+9665•• ••• 000",
"template": "order_received_v1",
"lang": "ar",
"reference": "order-1042",
"price_halalas": 0,
"error": null,
"occurred_at": "2026-09-06T09:00:04.512Z",
"created_at": "2026-09-06T09:00:01.087Z"
},
"sent_at": "1788685205201"
}أخطاء واتساب
بعد الفحوص المشتركة بين كل النقاط، أي حد المعدل والمصادقة وحالة الحساب وشكل الطلب، بهذا الترتيب.
| الحالة | error | المعنى |
|---|---|---|
| 403 | live_key_required | مفتاح تجربة tk_test_، ولا بيئة تجربة لواتساب بعد. استخدم المفتاح الفعلي للتطبيق. |
| 403 | whatsapp_not_enabled | واتساب موقوف لهذا التطبيق. تواصل مع الدعم إن كنت تعتقد أن هذا خطأ. |
| 409 | no_whatsapp_number | لا رقم واتساب مربوطًا بهذا التطبيق بعد. اربط رقمًا من قسم الرقم في تبويب الإشعارات في صفحة التطبيق باللوحة، وهي الخطوة الأولى في «خطوات البدء». |
| 409 | number_disconnected | الرقم مربوط لكنه غير متصل من جهة Meta الآن، فالويبهوك غير مثبّت أو تبلّغ Meta عن حالة غير CONNECTED. وتعرض صفحة الإشعارات في اللوحة صحة الرقم. |
| 422 | invalid_destination | الوجهة لا تطابق أي صيغة جوال سعودي مقبولة، ورسائل واتساب للجوالات السعودية فقط. |
| 422 | unknown_template | لا قالب بهذا الاسم، وبهذه اللغة إن حُددت، في حساب واتساب للأعمال للرقم. ويعرض GET /v1/whatsapp/templates القوالب الموجودة. |
| 422 | template_not_approved | القالب موجود لكن Meta لم تعتمده، ويحمل message حالة Meta، مثل PENDING أو REJECTED أو PAUSED. |
| 422 | template_category_not_allowed | قالب من فئة AUTHENTICATION أُرسل بمفتاح شريك. ترسل مفاتيح الشركاء قوالب الخدمة والتسويق، ويرسل المفتاح الفعلي للتطبيق قوالب المصادقة. ويعيده كذلك تعديل قالب مصادقة عبر PATCH /v1/whatsapp/templates/{template_id}، فنصّه نص Meta، ومفتاح تطبيق مربوط مع أي فئة غير UTILITY، في الإرسال أو في قالب ينشئه أو يعدّله. |
| 422 | consent_opted_out | قالب تسويقي إلى مستلم طلب من هذا التطبيق إيقاف رسائله التسويقية، بكتابة «إيقاف» إلى الرقم أو بإيقاف عروضه من واتساب. لم يُرسل شيء ولم يُسجَّل ولم يُخصم. وتبقى قوالب الخدمة والمصادقة تصله. |
| 422 | unsupported_template | يحتاج القالب شيئًا لا تحمله هذه النقطة بعد: ترويسة فيديو أو ملف أو موقع (أما ترويسة الصورة فتُرسل بـ header.image.link)، أو زرًا أو مكوّنًا يأخذ معاملًا غير نصي، مثل زر نسخ رمز الخصم في قالب تسويقي أو flow أو كتالوج أو carousel أو عرض محدود، أو متغيرات مسمّاة ومرقّمة معًا في النص. ويبيّن message أيها. |
| 422 | invalid_params | قيمة متغير ناقصة أو فارغة أو غير متوقعة، أو أطول من 1024 حرفًا، أو فيها سطر جديد أو تاب أو رمز تحكم ترفضه Meta، أو القالب بعدة لغات ولم يُحدد lang، أو وصل قالبَ المصادقة buttons أو code ليس من 4 إلى 15 حرفًا أو رقمًا، أو قالب يبدأ بصورة بلا header.image.link، أو برابط لا يبدأ بـ https، أو وصلت صورة قالبًا لا يبدأ بها. ويسمّي message المتغير. |
| 402 | insufficient_credits | الرصيد المسبق للحساب أقل من رسوم رسالة واتساب. ويضيف الرد balance_halalas وprice_halalas، ولم يُرسل شيء ولم يُسجَّل شيء. |
| 502 | send_failed | رفضت Meta الإرسال أو تعذّر الوصول إليها. ويضيف الرد provider_code، وهو رمز خطأ Meta، وmessage، وتُعاد الرسوم وتُسجَّل الرسالة فاشلة. |
| 403 | template_not_managed | مفتاح تطبيق مربوط مع قالب لم ينشئه ذلك التطبيق لهذا التطبيق. يعدّل هذا المفتاح ويحذف القوالب التي أنشأها وحدها، وهي التي قيمة managed فيها true. |
| 409 | template_not_editable | لا يتغيّر القالب عبر API وهو على حاله، ويبيّن status السبب. في التعديل: حالة القالب إن لم تكن APPROVED أو REJECTED أو PAUSED، أو MEDIA_HEADER لقالب يبدأ بصورة أو وسائط أخرى، وهذا يُعدَّل من اللوحة. وفي التعديل والحذف: META_SAMPLE لقالب من نماذج Meta. |
| 409 | template_in_use | ما زال شيء يرسل القالب، فلا يقبل التعديل أو الحذف. ويعدّد used_by ما هو، من campaign لحملة لم تنتهِ، وautomation لأتمتة مفعّلة، وstore_notice لإشعار متجر مفعّل، بهذا الترتيب. يوقفه صاحب الحساب أو يغيّر قالبه من اللوحة أولًا. |
| 409 | idempotency_in_progress | طلب بمفتاح Idempotency-Key نفسه ما زال قيد التنفيذ. انتظر رده، أو أعد المحاولة بعد لحظة. |
| 409 | idempotency_key_reused | استُخدم مفتاح Idempotency-Key هذا من قبل لطلب مختلف. استخدم مفتاحًا لكل تغيير. |
| 422 | template_refused | رفضت Meta القالب بعد أن اجتاز فحوص توكيد، ويحمل message عبارة Meta نفسها، مثل اسم مستخدم من قبل أو نص لا تراجعه. ويعيده كذلك مفتاح تطبيق مربوط بلغ أقصى ما يُسمح له به من القوالب، ويبيّن message ذلك. |
| 503 | templates_unavailable | لم ترد Meta على قراءة قائمة قوالب الرقم، وهي ما تحتاجه نقاط القوالب والإرسال قبل أي شيء، أو لم ترد على تعديل في قالب. لم يُرسل شيء ولم يُخصم شيء، وبقي القالب كما هو، فأعد المحاولة بعد قليل. |
كل الأخطاء الممكنة
| الحالة | error | المعنى |
|---|---|---|
| 429 | too_many_requests | تجاوزت حد الطلبات لكل مفتاح، وهو افتراضيًا 120 طلبًا في الدقيقة في نافذة ثابتة من 60 ثانية. ويُفحص قبل المصادقة. |
| 401 | unauthorized | مفتاح غائب أو غير معروف أو ملغى أو من غير نوع النقطة، أو شريك غير معروف أو موقوف. |
| 400 | service_required | مفتاح شريك بلا application أو service في جسم الطلب. |
| 404 | service_not_found | مفتاح شريك، لكن application/service لا يطابق أي تطبيق من تطبيقات هذا الشريك. |
| 403 | account_not_active | التطبيق لم يُعتمد بعد، أو الحساب موقوف، أو عطّل الشريك هذا التطبيق. وكل هذه الأسباب تعيد الاستجابة نفسها. |
| 400 | invalid_json | جسم الطلب ليس JSON صالحًا. |
| 400 | invalid_request | في start: الحقلان to وphone غائبان أو فارغان. وفي check: الحقل id أو code غائب. |
| 422 | unsupported_channel | اسم قناة غير معروف، أو قناة معروفة غير مفعّلة: واتساب حتى يفتحه توكيد لكل الحسابات، أو البريد: لا تُرسل الرموز بالبريد (توكيد للبريد الإلكتروني يرسل بريد النشاط نفسه، https://tawked.com/ar/email). |
| 422 | sandbox_unsupported_channel | مفتاح تجربة tk_test_ على قناة لا تتسع لختم [تجريبي]، فقالب واتساب الثابت من Meta لا مكان فيه له. |
| 422 | invalid_destination | الوجهة لا تطابق أي صيغة جوال سعودي مقبولة. |
| 422 | sandbox_unverified_destination | مفتاح تجربة، والوجهة ليست رقم الجوال الذي وثّقه مالك الحساب عند التسجيل. |
| 429 | sandbox_quota_exceeded | بلغ التطبيق سقف إرسال التجربة مدى الحياة، وهو 10 رسائل. |
| 429 | rate_limited | بلغت الوجهة حدها في الساعة. ويختلف عن too_many_requests أعلاه: حالة HTTP نفسها وقيمة error مختلفة. |
| 402 | insufficient_credits | الرصيد المسبق للحساب أقل من سعر القناة. |
| 502 | send_failed | فشل استدعاء مزوّد التسليم، ويُعاد الخصم إلى رصيدك تلقائيًا. |
| 404 | not_found | معرّف غير معروف، أو معرّف يخص حسابًا أو تطبيقًا غير حساب المفتاح المستدعي وتطبيقه. |
| 500 | internal_error | خطأ غير متوقع في الخادم. اذكر ترويسة X-Request-Id عند الإبلاغ عنه. |
| 401 | key_expired | انقضى تاريخ انتهاء المفتاح expires_at. ويُفحص فور التعرف على المفتاح، قبل القائمة المسموحة ونطاق الصلاحية. |
| 403 | ip_not_allowed | عنوان IP للمستدعي خارج القائمة المسموحة للمفتاح ip_allowlist، وهي عناوين محددة أو نطاقات CIDR، بصيغتي IPv4 وIPv6. |
| 403 | insufficient_scope | لم يُمنح المفتاح هذا الاستدعاء: مفتاح بصلاحية مخصّصة لا تشمل هذا المنتج، أو بمستوى أدنى مما يحتاج إليه الاستدعاء، كمفتاح يتحقق والاستدعاء يرسل. وتذكر ترويسة الاستجابة WWW-Authenticate الصلاحية التي يحتاج إليها الاستدعاء. ويُفحص ذلك فور التعرف على المفتاح، قبل account_not_active وشكل الطلب. |
| 403 | application_paused | أوقف حارس الحماية من الضخ التطبيق تلقائيًا بعد قفزة في الوجهات الجديدة خلال ساعة، ويستأنفه المالك أو أحد المشرفين. |
| 429 | ip_rate_limited | مرّر المستدعي client_ip، وأرسل هذا العنوان في الساعة الأخيرة أكثر مما يسمح به max_per_ip_per_hour للتطبيق. |
| 429 | spend_cap_reached | إنفاق اليوم بتوقيت الرياض مع هذا الإرسال يتجاوز daily_spend_cap_halalas للتطبيق. |
| 409 | not_resendable | عملية التحقق في حالة نهائية: تحققت أو فشلت أو انتهت أو أُلغيت. ويتضمن الرد status الحالية. |
| 409 | not_cancelable | عملية التحقق في حالة نهائية، ويتضمن الرد status الحالية. |
| 429 | resend_limit_reached | استخدمت عملية التحقق هذه إعاداتها الثلاث. |
| 403 | live_key_required | مفتاح تجربة tk_test_، ولا بيئة تجربة لواتساب بعد. استخدم المفتاح الفعلي للتطبيق. |
| 403 | whatsapp_not_enabled | واتساب موقوف لهذا التطبيق. تواصل مع الدعم إن كنت تعتقد أن هذا خطأ. |
| 409 | no_whatsapp_number | لا رقم واتساب مربوطًا بهذا التطبيق بعد. اربط رقمًا من قسم الرقم في تبويب الإشعارات في صفحة التطبيق باللوحة، وهي الخطوة الأولى في «خطوات البدء». |
| 409 | number_disconnected | الرقم مربوط لكنه غير متصل من جهة Meta الآن، فالويبهوك غير مثبّت أو تبلّغ Meta عن حالة غير CONNECTED. وتعرض صفحة الإشعارات في اللوحة صحة الرقم. |
| 422 | unknown_template | لا قالب بهذا الاسم، وبهذه اللغة إن حُددت، في حساب واتساب للأعمال للرقم. ويعرض GET /v1/whatsapp/templates القوالب الموجودة. |
| 422 | template_not_approved | القالب موجود لكن Meta لم تعتمده، ويحمل message حالة Meta، مثل PENDING أو REJECTED أو PAUSED. |
| 422 | template_category_not_allowed | قالب من فئة AUTHENTICATION أُرسل بمفتاح شريك. ترسل مفاتيح الشركاء قوالب الخدمة والتسويق، ويرسل المفتاح الفعلي للتطبيق قوالب المصادقة. ويعيده كذلك تعديل قالب مصادقة عبر PATCH /v1/whatsapp/templates/{template_id}، فنصّه نص Meta، ومفتاح تطبيق مربوط مع أي فئة غير UTILITY، في الإرسال أو في قالب ينشئه أو يعدّله. |
| 422 | consent_opted_out | قالب تسويقي إلى مستلم طلب من هذا التطبيق إيقاف رسائله التسويقية، بكتابة «إيقاف» إلى الرقم أو بإيقاف عروضه من واتساب. لم يُرسل شيء ولم يُسجَّل ولم يُخصم. وتبقى قوالب الخدمة والمصادقة تصله. |
| 422 | unsupported_template | يحتاج القالب شيئًا لا تحمله هذه النقطة بعد: ترويسة فيديو أو ملف أو موقع (أما ترويسة الصورة فتُرسل بـ header.image.link)، أو زرًا أو مكوّنًا يأخذ معاملًا غير نصي، مثل زر نسخ رمز الخصم في قالب تسويقي أو flow أو كتالوج أو carousel أو عرض محدود، أو متغيرات مسمّاة ومرقّمة معًا في النص. ويبيّن message أيها. |
| 422 | invalid_params | قيمة متغير ناقصة أو فارغة أو غير متوقعة، أو أطول من 1024 حرفًا، أو فيها سطر جديد أو تاب أو رمز تحكم ترفضه Meta، أو القالب بعدة لغات ولم يُحدد lang، أو وصل قالبَ المصادقة buttons أو code ليس من 4 إلى 15 حرفًا أو رقمًا، أو قالب يبدأ بصورة بلا header.image.link، أو برابط لا يبدأ بـ https، أو وصلت صورة قالبًا لا يبدأ بها. ويسمّي message المتغير. |
| 403 | template_not_managed | مفتاح تطبيق مربوط مع قالب لم ينشئه ذلك التطبيق لهذا التطبيق. يعدّل هذا المفتاح ويحذف القوالب التي أنشأها وحدها، وهي التي قيمة managed فيها true. |
| 409 | template_not_editable | لا يتغيّر القالب عبر API وهو على حاله، ويبيّن status السبب. في التعديل: حالة القالب إن لم تكن APPROVED أو REJECTED أو PAUSED، أو MEDIA_HEADER لقالب يبدأ بصورة أو وسائط أخرى، وهذا يُعدَّل من اللوحة. وفي التعديل والحذف: META_SAMPLE لقالب من نماذج Meta. |
| 409 | template_in_use | ما زال شيء يرسل القالب، فلا يقبل التعديل أو الحذف. ويعدّد used_by ما هو، من campaign لحملة لم تنتهِ، وautomation لأتمتة مفعّلة، وstore_notice لإشعار متجر مفعّل، بهذا الترتيب. يوقفه صاحب الحساب أو يغيّر قالبه من اللوحة أولًا. |
| 409 | idempotency_in_progress | طلب بمفتاح Idempotency-Key نفسه ما زال قيد التنفيذ. انتظر رده، أو أعد المحاولة بعد لحظة. |
| 409 | idempotency_key_reused | استُخدم مفتاح Idempotency-Key هذا من قبل لطلب مختلف. استخدم مفتاحًا لكل تغيير. |
| 422 | template_refused | رفضت Meta القالب بعد أن اجتاز فحوص توكيد، ويحمل message عبارة Meta نفسها، مثل اسم مستخدم من قبل أو نص لا تراجعه. ويعيده كذلك مفتاح تطبيق مربوط بلغ أقصى ما يُسمح له به من القوالب، ويبيّن message ذلك. |
| 503 | templates_unavailable | لم ترد Meta على قراءة قائمة قوالب الرقم، وهي ما تحتاجه نقاط القوالب والإرسال قبل أي شيء، أو لم ترد على تعديل في قالب. لم يُرسل شيء ولم يُخصم شيء، وبقي القالب كما هو، فأعد المحاولة بعد قليل. |
حدود المعدل
الحد الافتراضي 120 طلبًا في الدقيقة لكل مفتاح، في نافذة ثابتة من 60 ثانية. ويسمح بالمرور عند أي خلل في التخزين المؤقت، فهو دفاع إضافي فوق سقف الرصيد وسقف الوجهة، لا الضابط الأساسي.
معرّف الطلب
تحمل كل استجابة ترويسة X-Request-Id، فاذكرها إن راسلت الدعم عن طلب بعينه.
ويبهوك العميل
اضبط رابطًا وسر توقيع لكل تطبيق، فتصلك رسالة موقّعة بكل نتيجة، بلا استعلام متكرر.
verification.verifiedverification.failedverification.expired- تُضبط لكل تطبيق في صفحة «الويبهوك» الخاصة به: رابط وسر توقيع، يُكشف عند الطلب ويمكن تدويره. والتطبيق الذي يزوّده شريك ليس له ويبهوك خاص: تذهب نتائج التحقق فيه إلى سجل أحداث الشريك، وإلى ويبهوك الشريك إن اشترك فيها، مع external_id الخاص بالشريك.
- يُطلق verification.verified وverification.failed من check، ويُطلق verification.expired من مسح انتهاء الصلاحية الدوري، ومن أي check أو GET يكتشف الانتهاء.
- يحمل كل تسليم الترويسات tawked-timestamp وtawked-signature وtawked-event، والتوقيع HMAC-SHA256 بصيغة hex للنص "{timestamp}.{raw body}" بسر التوقيع لديك. تحقق من التوقيع مقابل جسم الطلب الخام قبل الوثوق بأي محتوى.
- يُعاد التسليم تلقائيًا بفواصل متزايدة لأي رد غير 2xx، بالمهمة والجدول المستخدمين لويبهوك الشركاء، وعدد المحاولات أدناه. ويعرض سجل التسليم في اللوحة كل محاولة.
- يجب أن يكون الرابط https على عنوان عام، وأن يرد عليه خادمك مباشرة: إعادة التوجيه لا تُتبع وتُحسب محاولة فاشلة.
- حدث التجربة المرسل من صفحة الويبهوك في اللوحة هو عيّنة verification.verified واحدة يحمل غلافها أيضًا "test": true، وقيم data فيها مصطنعة: المعرّف أصفار، والمرجع test-event، والنمط test. لا يحمل أي حدث حقيقي الحقل test، فتجاوز آثارك الجانبية عند وجوده.
- ويستقبل التطبيق المربوط بواتساب أيضًا الأحداث message.sent وmessage.delivered وmessage.read وmessage.failed على الرابط نفسه وبالغلاف نفسه، كما في رسائل واتساب.
مثال المحتوى
{
"event": "verification.verified",
"data": {
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "verified",
"application_id": "c2a10f3e-8b7a-4d2e-9c1a-1a2b3c4d5e6f",
"reference": "order-42",
"channel": "sms",
"to": "+966551234567",
"mode": "live",
"attempts": 1,
"expires_at": "2026-09-01T12:34:56.789Z",
"verified_at": "2026-09-01T12:31:02.145Z",
"created_at": "2026-09-01T12:29:56.789Z"
},
"sent_at": "1788265862201"
}التحقق من التوقيع في Node.js
const [timestamp, signature] = [
req.headers["tawked-timestamp"],
req.headers["tawked-signature"],
];
const expected = crypto
.createHmac("sha256", webhookSecret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) throw new Error("bad signature");يُعاد الإرسال لأي رد غير 2xx، والحد الأقصى للمحاولات 5، بفواصل متزايدة بالدقائق: 1, 5, 30, 120, 360.
واجهة الشركاء
تستخدم منصات إعادة البيع، مثل تطبيقات سلة وزد، مفتاح tk_partner_ واحدًا لتزويد متاجر كثيرة عبر /v1/partner/applications، مع ويبهوك لأحداث المراجعة والرصيد.
دليل الشركاءهذا المرجع متاح للآلات أيضًا بصيغة Markdown خام: /llms.txt · /llms-full.txt