هدهد العراق التوثيق
لوحة التحكم

توثيق هدهد

أرسل رسائل واتساب من موقعك الإلكتروني أو نظام إدارة العملاء (CRM) أو متجرك أو خادمك — تحديثات الطلبات، وتذكيرات المواعيد، وإشعارات التوصيل — بطلب HTTP واحد. كل ما تستطيع فعله في لوحة التحكم تستطيع فعله من خلال الكود.

ما الذي تحصل عليه

  • نقطة وصول واحدة للإرسال — نص عادي أو قالب واتساب معتمد.
  • تتبّع التسليم — تحصل كل رسالة على معرّف تستعلم به عن حالتها: sent أو delivered أو read أو failed.
  • إرسال جماعي في طلب واحد — حتى 25,000 مستلم، لكلٍّ منهم متغيراته الخاصة.
  • فوترة شفافة — الرسالة التي ترفضها ميتا تُعاد قيمتها إلى رصيدك تلقائيًا. والردود النصية الحرة داخل نافذة المحادثة (24 ساعة) تُحتسب حاليًا بسعر 0 د.ع.

إلى أين بعد ذلك؟

تدير رسائلك يدويًا؟ ابدأ بقسم كيف يعمل هدهد ثم إعداد حسابك — دون أي برمجة. تريد ربط نظامك الخاص؟ انتقل مباشرةً إلى البدء السريع للمطورين.

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

جميع نقاط وصول API تتفرع من هذا العنوان. كل الطلبات عبر HTTPS وكل أجسام الطلبات بصيغة JSON.

رقم إصدار API جزء من المسار. الإصدار v1 مستقر — قد نضيف حقولًا جديدة، لكننا لا نحذف الحقول ولا نغيّر أسماءها.
عنوان URL الأساسي
https://hudhudiraq.com/api.php/v1
cURL
# أبسط طلب إرسال ممكن
curl -X POST https://hudhudiraq.com/api.php/v1/messages \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to":"+9647500000000","body":"Your order is on its way."}'

كيف يعمل هدهد #

يقف هدهد بين نشاطك التجاري وواتساب. لن تتعامل مع ميتا مباشرةً أبدًا — نحن نتولى الاتصال بواتساب، وأنت تملك حسابًا برصيد.

  1. تحصل على رقم للإرسال. استأجر رقمًا من قائمة الأرقام المتاحة في لوحة التحكم. كل رسالة ترسلها تخرج منه.
  2. تكتب القوالب. يشترط واتساب صياغة معتمدة مسبقًا لبدء أي محادثة. تقدّم القوالب هنا، وتراجعها ميتا.
  3. ترسل — يدويًا من لوحة التحكم، أو كحملة جماعية، أو وفق جدول زمني، أو من الكود الخاص بك عبر API.
  4. يُبلغك واتساب بالنتيجة. تنتقل كل رسالة عبر الحالات sent ← delivered ← read، ويُخصم من رصيدك عن كل رسالة.

قاعدتان من المفيد معرفتهما مسبقًا

نافذة المحادثة (24 ساعة). بمجرد أن يراسلك العميل، يمكنك الرد عليه بأي نص حر لمدة 24 ساعة، وتُحتسب هذه الردود حاليًا بسعر 0 د.ع. خارج هذه النافذة لا يقبل واتساب إلا قالبًا معتمدًا.

القوالب تتبع حساب واتساب واحدًا. إذا كانت لديك أرقام على حسابين، فلكل حساب قائمة قوالبه الخاصة — ولوحة التحكم لا تعرض إلا القوالب التي يستطيع المرسِل المختار استخدامها فعلًا.

لا تدفع إلا عن الرسائل التي يقبلها واتساب. أي رسالة يرفضها — رقم خاطئ أو قالب محظور — تُعاد قيمتها إلى رصيدك تلقائيًا، وتظهر كعملية استرداد في سجل الاستخدام.
لا شيء هنا يحتاج إلى مطوّر. لوحة التحكم تقوم بكل شيء، أما واجهة API فهي لمن يريد أن يرسل نظامه الخاص الرسائل تلقائيًا.

إعداد حسابك #

ست خطوات بالترتيب. كل خطوة منها صفحة في القائمة الجانبية للوحة التحكم.

1. تسجيل الدخول

استخدم البريد الإلكتروني أو اسم المستخدم أو معرّف المستخدم الذي حصلت عليه، أو تابع عبر Google أو Facebook. معرّف المستخدم يكفي وحده لتسجيل الدخول — تجده في صفحة الملف الشخصي وAPI.

2. استئجار رقم هاتف

تعرض صفحة أرقام الهاتف الأرقام المتاحة مع سعر كل 30 يومًا. يُخصم الاستئجار من رصيدك ويعمل الرقم فورًا. وبدون رقم لا يمكنك الإرسال إطلاقًا.

3. إضافة قالب

القوالب ← اكتب قالبًا، أو انسخ قالبًا جاهزًا من مكتبة القوالب. تراجع ميتا القوالب عادةً خلال دقائق إلى بضع ساعات.

4. شحن الرصيد

الرصيد ← اشحن عبر FIB أو أي طريقة أخرى متاحة في لوحة التحكم. يُضاف المبلغ الذي تدفعه كاملًا، ولا نفرض أي رسوم على الشحن.

5. أرسل رسالة تجريبية إلى نفسك

إرسال رسالة ← رقمك الشخصي ← اختر القالب ← أرسل. ثم افتح السجلات لتراها تتحول إلى delivered.

6. اختياري: اربط أنظمتك

الملف الشخصي وAPI ← أنشئ مفتاح API واتبع خطوات البدء السريع للمطورين.

قائمة التحقق
□  تم تسجيل الدخول
□  رقم هاتف مستأجر وحالته «جاهز للإرسال»
□  قالب واحد معتمد على الأقل
□  تم شحن الرصيد
□  وصلت رسالة تجريبية إلى هاتفي
□  (اختياري) أنشأت مفتاح API وحفظته على خادمي
يفشل الإرسال برسالة «لا يوجد رقم هاتف في هذا الحساب» إلى أن تُنجز الخطوة 2. وهذا أكثر سؤال يتكرر في اليوم الأول.

أرقام الهاتف #

تتكون صفحة أرقام الهاتف في لوحة التحكم من جزأين: الأرقام التي تملكها، والأرقام المتاحة للاستئجار.

الاستئجار

يظهر لكل رقم متاح عنوان ووصف قصير وسعر لكل 30 يومًا. يُخصم الاستئجار من رصيدك فورًا ويصبح الرقم مرسِلًا يمكنك اختياره في صفحة الإرسال. بعض الأرقام مشتركة — وتُظهر بطاقتها عدد الأماكن المتبقية؛ وبعضها مخصص لأنشطة تجارية معيّنة فقط، أو للحسابات الجديدة فقط كرقم ترحيبي مجاني.

التجديد

يتجدد الرقم المستأجر كل 30 يومًا من رصيدك في تاريخ تجديده. أوقف التجديد التلقائي لإنهائه في نهاية المدة الحالية — ويبقى معك حتى ذلك الحين. وإذا لم يكفِ رصيدك في تاريخ التجديد، يُحرَّر الرقم.

تحرير الرقم

زر تحرير يعيد الرقم فورًا. لا تُسترد قيمة الأيام المدفوعة مسبقًا، ويعود الرقم إلى قائمة الأرقام المتاحة.

أرقام مُنحت لك

يمكن للمنصة أيضًا أن تمنحك رقمًا مباشرةً — ويظهر بعلامة مجاني، مع تاريخ انتهاء إن حُدِّد. لا يُخصم أي مبلغ مقابل هذه الأرقام.

المرسِل الافتراضي

إذا كان لديك أكثر من رقم، يظهر حقل الإرسال من في صفحتي الإرسال والإرسال الجماعي. الرقم المعلَّم بـالمرسِل الافتراضي هو الذي تستخدمه API، ويُستخدم أيضًا كلما لم تختر رقمًا.

تغيير المرسِل يغيّر القوالب المتاحة لك، لأن القوالب تتبع حساب واتساب الذي يقف خلف الرقم. وتتحدث القائمة تلقائيًا عند التبديل.
العملاء الذين لم يحفظوا رقمك يرون الرقم نفسه، لا اسم نشاطك التجاري، في أعلى المحادثة. هذه قاعدة لدى واتساب للحسابات التي لا تحمل شارة الحساب التجاري الرسمي (Official Business Account) — ويبقى اسمك ظاهرًا في ملفك الشخصي.

القوالب والاعتماد #

القالب رسالة اعتمدتها ميتا مسبقًا، وهو الطريقة الوحيدة لمراسلة شخص لم يكتب إليك خلال آخر 24 ساعة.

كتابة قالب

القوالب ← جديد. ثم تختار:

  • الاسم — أحرف إنجليزية صغيرة وأرقام وشرطات سفلية، مثل order_shipped.
  • الفئة — خدمية (تحديثات الطلبات والحساب)، أو تسويقية (عروض وإعادة تفاعل)، أو مصادقة (رموز تُستخدم مرة واحدة). والفئة هي التي تحدد السعر.
  • اللغة — قالب واحد لكل لغة، ويمكن أن يتكرر الاسم نفسه بعدة لغات.
  • النص — نص رسالتك مع {{1}} و{{2}} في مواضع القيم المتغيرة.
  • التذييل وزر الرابط — اختياريان. يمكن أن ينتهي رابط الزر بـ{{1}} لتشير كل رسالة إلى طلب مختلف.

الحالات

الحالةالمعنى
مسودةبانتظار موافقة المنصة قبل أن يصل إلى ميتا.
قيد المراجعةلدى ميتا للمراجعة.
معتمدجاهز للإرسال.
مرفوضرفضته ميتا — عدّل الصياغة وقدّمه من جديد.

كيف يُعتمد قالبك من المحاولة الأولى

  • اكتبه كرسالة حقيقية إلى عميل حقيقي، لا كشعار دعائي.
  • اختر الفئة الصحيحة بأمانة. الصياغة التسويقية في قالب خدمي هي أكثر أسباب الرفض شيوعًا.
  • لا قوالب من المتغيرات وحدها: القالب الذي نصه {{1}} فقط يُرفض.
  • لا تعِد بما لا تستطيع تنفيذه، ولا توحِ بأن واتساب يزكّيك.

مكتبة القوالب

قوالب جاهزة للحالات الشائعة — تأكيد الطلبات، وتحديثات التوصيل، وتذكيرات المواعيد. استورد أيًّا منها وسيمرّ بالمراجعة نفسها.

مثال على نص قالب
مرحبًا {{1}}، طلبك {{2}} في الطريق إليك
ومن المتوقع أن يصل بحلول {{3}}.

شكرًا لتسوّقك معنا.
اجعل لكل غرض قالبًا واحدًا وأعد استخدامه. مكتبة قصيرة من القوالب المعتمدة أفضل من قوالب كثيرة متشابهة، وتقيّم ميتا حسابك بناءً على تفاعل الناس مع ما ترسله.

الإرسال من لوحة التحكم #

رسالة واحدة

إرسال رسالة ← اكتب المستلم أو اختره، واختر المرسِل إن كان لديك أكثر من رقم، ثم اختر قالبًا واملأ قيمه. تعرض المعاينة المجاورة للنموذج ما سيراه العميل تمامًا. والأرقام المحلية مثل 07XXXXXXXXX تُحوَّل تلقائيًا إلى الصيغة الدولية.

الحملات الجماعية

يرسل الإرسال الجماعي قالبًا واحدًا إلى أشخاص كثيرين، مع تخصيصه لكل مستلم. يأتي المستلمون من جهات اتصالك المحفوظة، أو من قائمة تلصقها، أو من ملف CSV ترفعه. ومع ملف CSV تربط كل {{1}} بعمود، فتحمل كل رسالة قيم صفّها. أعطِ الحملة اسمًا لتُجمَّع تحته في السجلات والتقارير.

الجدولة

في كلتا الصفحتين زر جدولة — اختر تاريخًا ووقتًا فتُوضع الرسالة في الانتظار. وتعرض صفحة المجدولة كل ما ينتظر الإرسال وتتيح لك إلغاءه. تُنفَّذ عمليات الإرسال المجدولة حتى لو كان متصفحك مغلقًا، ولا تُحتسب إلا عند إرسالها فعلًا.

جهات الاتصال

تحفظ صفحة جهات الاتصال الأسماء والأرقام والوسوم والحقول المخصصة. تتيح لك الوسوم الإرسال إلى مجموعة، وتملأ الحقول المخصصة قيم القوالب تلقائيًا. ويمكنك استيراد ملف CSV والتصدير في أي وقت.

ملف CSV للإرسال الجماعي
phone,name,order,eta
+9647500000001,Ahmed,ORD-1024,17:30
+9647500000002,Sara,ORD-1025,18:00

# ثم اربط كل متغير بعمود
# {{1}} → name   {{2}} → order   {{3}} → eta
إذا أظهر جدول البيانات رقمًا بالشكل 9.64751E+12، فنسّق ذلك العمود كنص قبل التصدير، وإلا ضاعت الأرقام.

السجلات والتقارير والرصيد #

السجلات

كل رسالة مع حالتها وتكلفتها وقالبها ومن أرسلها. صفِّ حسب الحالة أو عضو الفريق أو التاريخ، واحفظ عوامل التصفية التي تستخدمها كثيرًا، وصدّر إلى CSV أو Excel. وتعرض الرسالة الفاشلة السبب الذي أرسله واتساب نفسه.

التقارير

إجماليات حسب اليوم والقالب وعضو الفريق — ما تم تسليمه وما تمت قراءته وما فشل، وما أنفقته. وهي مفيدة لمعرفة أي القوالب تُقرأ فعلًا.

الرصيد

الشارة في أعلى الصفحة تعرض رصيدك. يتيح شحن الرصيد الدفع ويضيف المبلغ كاملًا — لا نفرض أي رسوم على الشحن. ويعرض سجل الاستخدام كل عملية خصم وشحن واسترداد مع الرصيد بعد كل عملية، لتتمكن من تتبّع أي مبلغ.

التكاليف

البندالسعر
قالب خدمي أو قالب مصادقة40 29 د.ع للرسالة
قالب تسويقي80 59 د.ع للرسالة
نص حر داخل نافذة المحادثة (24 ساعة)0 د.ع حاليًا
رقم مستأجرسعره المعروض، كل 30 يومًا

الفريق والصلاحيات

تتيح صفحة الفريق والصلاحيات دعوة زملائك والتحكم فيما يستطيع كلٌّ منهم فعله — الإرسال، والإرسال الجماعي، والقوالب، وجهات الاتصال، والسجلات، واستئجار الأرقام، والاطلاع على الرصيد. لا يرى الموظفون إلا الرسائل التي أرسلوها بأنفسهم. ولا يمكنك أبدًا منح صلاحية لا تملكها.

الرسائل العالقة عند sent التي لا تصل أبدًا إلى delivered تعني عادةً أن هاتف المستلم غير متصل — ويواصل واتساب المحاولة لمدة تصل إلى 30 يومًا.
احتفظ بقليل من الرصيد الاحتياطي. يُفحص الرصيد مقابل الدفعة كاملة قبل بدء أي حملة جماعية، ويُحرَّر الرقم المستأجر إذا تعذّر دفع تجديده.

الحفاظ على سمعة جيدة #

يقيّم واتساب كل نشاط تجاري بناءً على تفاعل الناس مع رسائله. التقييم الجيد يرفع عدد الأشخاص الذين يمكنك مراسلتهم يوميًا، والتقييم السيئ يؤدي إلى تقييد الرقم. وكل ما يلي يحمي هذا التقييم.

  • راسل من يتوقع رسائلك. اطلب الإذن عندما تأخذ الرقم، ووضّح ما الذي سترسله.
  • أرسل ما هو مفيد. تحديثات الطلبات والتذكيرات تُقرأ، أما العروض الترويجية المتكررة فتُحظر.
  • احترم طلبات إلغاء الاشتراك فورًا. إذا طلب أحدهم التوقف، فاحذفه من جهات اتصالك ولا تراسله مجددًا.
  • لا تشترِ قوائم أرقام. إنها أسرع طريقة لخسارة رقمك.
  • اجعل لكل غرض رسالة واحدة ولا ترسل الشيء نفسه مرتين.
  • راقب الجودة في صفحة أرقام الهاتف — انخفاض التقييم إلى الأصفر أو الأحمر إنذار يسبق فرض القيود.
تكرار محاولة الإرسال بقالب محظور أو غير معتمد قد يؤدي إلى إيقاف حسابك تلقائيًا. إذا رُفض قالب، فأصلحه بدلًا من إعادة المحاولة.
طلب الإذن
عند إتمام الطلب، بجانب حقل رقم الهاتف:

  «أرسلوا لي تحديثات طلبي عبر واتساب»   [x]

احتفظ بسجل هذه الموافقة، فهو ردّك
إذا اشتكى أي عميل يومًا.

البدء السريع للمطورين #

أربع خطوات من الصفر حتى رسالة تم تسليمها.

1. احصل على مفتاح API

افتح لوحة التحكم ← الملف الشخصي وAPI ← واجهة API للمطورين ← إنشاء مفتاح API. تبدأ المفاتيح بـhd_ ويليها 36 حرفًا ست عشريًا (hex). وإعادة إنشاء المفتاح تعطّل المفتاح القديم فورًا.

2. تأكد من امتلاكك رقمًا

تخرج الرسائل من رقم واتساب يملكه نشاطك التجاري. استأجر رقمًا من صفحة أرقام الهاتف في لوحة التحكم — راجع قبل أن تبدأ الإرسال.

3. أرسل

اختر لغة البرمجة من شريط اللغات فوق أمثلة الكود. أي شخص راسلك خلال آخر 24 ساعة يمكنه استلام نص عادي، أما الباقون فيحتاجون إلى قالب معتمد.

4. تتبّع الرسالة

احتفظ بقيمة message_id من الاستجابة واستعلم عن حالة التسليم عبر GET /v1/messages/{id}.

cURL
curl -X POST https://hudhudiraq.com/api.php/v1/messages \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "to": "+9647500000000",
        "template": "order_shipped",
        "language": "ar",
        "variables": ["Ahmed", "ORD-1024"]
      }'
PHP
<?php
$ch = curl_init('https://hudhudiraq.com/api.php/v1/messages');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer hd_your_key_here',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'to'        => '+9647500000000',
        'template'  => 'order_shipped',
        'language'  => 'ar',
        'variables' => ['Ahmed', 'ORD-1024'],
    ]),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Node.js
// Node 18+ (built-in fetch)
const res = await fetch('https://hudhudiraq.com/api.php/v1/messages', {
    method: 'POST',
    headers: {
        Authorization: 'Bearer hd_your_key_here',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        to: '+9647500000000',
        template: 'order_shipped',
        language: 'ar',
        variables: ['Ahmed', 'ORD-1024'],
    }),
});
console.log(await res.json());
Python
import requests

res = requests.post(
    "https://hudhudiraq.com/api.php/v1/messages",
    headers={
        "Authorization": "Bearer hd_your_key_here",
        "Content-Type": "application/json",
    },
    json={
        "to": "+9647500000000",
        "template": "order_shipped",
        "language": "ar",
        "variables": ["Ahmed", "ORD-1024"],
    },
)
print(res.json())
Java
// Java 11+ (java.net.http)
HttpClient client = HttpClient.newHttpClient();

String json = "{\"to\":\"+9647500000000\",\"template\":\"order_shipped\","
            + "\"language\":\"ar\",\"variables\":[\"Ahmed\",\"ORD-1024\"]}";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://hudhudiraq.com/api.php/v1/messages"))
    .header("Authorization", "Bearer hd_your_key_here")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();

HttpResponse<String> response =
    client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
C#
// .NET 6+
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer hd_your_key_here");

var json = "{\"to\":\"+9647500000000\",\"template\":\"order_shipped\","
         + "\"language\":\"ar\",\"variables\":[\"Ahmed\",\"ORD-1024\"]}";
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync(
    "https://hudhudiraq.com/api.php/v1/messages", content);
Console.WriteLine(await response.Content.ReadAsStringAsync());
الاستجابة
{
  "ok": true,
  "message_id": 4821,
  "status": "queued",
  "to": "+9647500000000",
  "error": null
}

المصادقة #

أرسل مفتاحك كرمز Bearer في كل طلب:

الترويسةالقيمة
AuthorizationBearer hd_your_key_here
Content-Typeapplication/json (في طلبات POST)

المفتاح يحدد نشاطك التجاري، لذا فهو يحدد أيضًا الأرقام والقوالب والرصيد التي يستخدمها الطلب. لا يوجد أي إعداد آخر.

احفظ المفتاح على خادمك. أي شخص يملكه يستطيع إرسال الرسائل وإنفاق رصيدك. لا تضعه أبدًا في تطبيق جوال أو في JavaScript يعمل داخل المتصفح. وإذا تسرّب، فاضغط إعادة الإنشاء في لوحة التحكم — ويتوقف المفتاح القديم فورًا.
مفتاح مفقود أو غير صالح
HTTP 401
{ "error": "مفتاح API مفقود. أرسل الترويسة: Authorization: Bearer <key>" }

HTTP 401
{ "error": "مفتاح API غير صالح" }

HTTP 403
{ "error": "هذا الحساب موقوف" }

قبل أن تبدأ الإرسال #

تخرج الرسائل من رقم واتساب يملكه نشاطك التجاري. تحصل على رقم باستئجاره من صفحة أرقام الهاتف في لوحة التحكم، أو بأن يخصص لك مالك المنصة رقمًا. وإلى ذلك الحين تجيب API بالخطأ المعروض في المثال.

تستخدم الطلبات المرسِل الافتراضي — وهو الرقم المعلَّم بـdefault في GET /v1/numbers. ويمكنك تغييره من لوحة التحكم.

القوالب تتبع الرقم

يعيش قالب واتساب على الحساب (WABA) الذي يملك رقمك، لذا تقتصر GET /v1/templates وكل عملية إرسال على هذا الحساب. وإرسال قالب يتبع حسابًا آخر يعيد خطأ 422 واضحًا.

لا يوجد رقم
HTTP 402
{
  "error": "لا يوجد رقم هاتف في هذا الحساب —
            استأجر رقمًا من لوحة التحكم في صفحة أرقام الهاتف."
}

إرسال رسالة نصية #

POST/v1/messages

يصل النص العادي إلى أي شخص راسلك خلال آخر 24 ساعة — وهي ما يسميه واتساب نافذة المحادثة. وخارجها لا يقبل واتساب إلا القوالب.

الحقلالنوعملاحظات
to مطلوبstring المستلم بالصيغة الدولية، مثل +9647500000000. أضِف رمز الدولة دائمًا — فقد يرفض واتساب الرقم المحلي الذي لا يتضمنه.
body مطلوبstring نص الرسالة.
name اختياريstring تسمية لسجلاتك الخاصة، ولا يراها المستلم أبدًا.
الردود النصية الحرة داخل نافذة المحادثة تُحتسب حاليًا بسعر 0 د.ع.
cURL
curl -X POST https://hudhudiraq.com/api.php/v1/messages \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to":"+9647500000000","body":"Thanks! Your order ships today."}'
PHP
$payload = [
    'to'   => '+9647500000000',
    'body' => 'Thanks! Your order ships today.',
];
// ثم أرسل الطلب كما في مثال البدء السريع
Node.js
await send({ to: '+9647500000000', body: 'Thanks! Your order ships today.' });
Python
send({"to": "+9647500000000", "body": "Thanks! Your order ships today."})
الاستجابة
{
  "ok": true,
  "message_id": 4822,
  "status": "queued",
  "to": "+9647500000000",
  "error": null
}

إرسال قالب #

POST/v1/messages

القوالب رسائل معتمدة مسبقًا تحتوي على متغيرات مثل {{1}} و{{2}}. وهي الطريقة الوحيدة لبدء محادثة — دون الحاجة إلى نافذة محادثة مفتوحة. أنشئها وزامنها من صفحة القوالب في لوحة التحكم.

الحقلالنوعملاحظات
to مطلوبstringالمستلم.
template مطلوبstring اسم القالب تمامًا كما اعتُمد، مثل order_shipped.
language اختياريstring رمز لغة القالب المعتمد. القيمة الافتراضية ar. ويجب أن يتطابق تمامًا — فـen وen_US قالبان مختلفان.
variables اختياريstring[] تملأ {{1}} و{{2}}… بالترتيب. أعطِ كل متغير قيمة.
button_variables اختياريstring[] قيم أزرار الروابط الديناميكية، مثل رقم طلب يُضاف إلى رابط التتبع.
header_value مشروطstring مطلوب عندما يبدأ القالب بصورة أو فيديو أو مستند — فواتساب يحفظ القالب لا الملف. مرّر رابط https عامًا، أو معرّف وسائط مرفوعًا مسبقًا إلى ميتا. أو احذفه لاستخدام الملف الافتراضي المحفوظ لهذا القالب في لوحة التحكم. وإذا كانت الترويسة نصية وتحتوي على {{1}} فتؤخذ قيمته من هنا أيضًا.
الأرقام المحظورة. لا تُراسَل أبدًا الأرقام الموجودة في قائمة الحظر الخاصة بالحساب (لوحة التحكم ← الإرسال الجماعي ← قائمة الحظر). الإرسال الفردي إلى أحدها يعيد 422، وفي الطلب الجماعي يعود هذا المستلم مع "error": "الرقم موجود في قائمة الحظر" ولا يُحتسب. والمطابقة تتجاهل التنسيق، لذا فإن 0770… و+964770… رقم واحد.
استخدم GET /v1/templates لترى بالضبط أسماء القوالب ولغاتها وعدد متغيراتها التي يستطيع حسابك إرسالها.
cURL
curl -X POST https://hudhudiraq.com/api.php/v1/messages \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "to": "+9647500000000",
        "template": "booking_reminder",
        "language": "ar",
        "variables": ["Ahmed", "30/6", "5:30PM"],
        "button_variables": ["ORD-1024"]
      }'
PHP
$payload = [
    'to'               => '+9647500000000',
    'template'         => 'booking_reminder',
    'language'         => 'ar',
    'variables'        => ['Ahmed', '30/6', '5:30PM'],
    'button_variables' => ['ORD-1024'],
];
Node.js
await send({
    to: '+9647500000000',
    template: 'booking_reminder',
    language: 'ar',
    variables: ['Ahmed', '30/6', '5:30PM'],
    button_variables: ['ORD-1024'],
});
Python
send({
    "to": "+9647500000000",
    "template": "booking_reminder",
    "language": "ar",
    "variables": ["Ahmed", "30/6", "5:30PM"],
    "button_variables": ["ORD-1024"],
})
قالب من حساب آخر
HTTP 422
{
  "error": "القالب «autumn_promo» تابع لحساب واتساب «الخط الثاني».
            أرسله من رقم على ذلك الحساب، أو اختر قالبًا من
            الحساب الذي ينتمي إليه هذا الرقم."
}

الإرسال إلى عدة مستلمين #

POST/v1/messages/bulk

قالب واحد إلى أشخاص كثيرين في طلب واحد، حتى 1,000 مستلم. وتعرض الاستجابة نتيجة كل مستلم على حدة، فلا يُفشل رقمٌ خاطئ الدفعة كلها.

أرقام كثيرة ومجموعة قيم واحدة

الحالة المعتادة: مرّر to كقائمة أرقام وvariables مرة واحدة — فيحصل كل مستلم على القيم نفسها.

قيم مختلفة لكل شخص

مرّر recipients بدلًا من ذلك، ولكل عنصر variables الخاصة به. ويمكنك الجمع بين الطريقتين: المستلم الذي لا يحمل variables يأخذ المجموعة المشتركة.

الحقلالنوعملاحظات
to إما هذا…string[] قائمة أرقام بسيطة. وتعمل أيضًا سلسلة نصية مفصولة بفواصل.
recipients …أو هذاobject[] يأخذ كل عنصر to، واختياريًا variables وbutton_variables وheader_value وname.
variables اختياريstring[] قيم مشتركة لكل مستلم لا يحمل قيمه الخاصة.
header_value مشروطstring رابط الصورة / الفيديو / المستند لقالب يبدأ بأحدها، ويُستخدم للدفعة كلها. ويمكن لأي مستلم أن يحمل رابطه الخاص ليحل محله.
template مستحسنstring اسم القالب. بدونه يُرسل body كنص حر ولا يصل إلا إلى من هم داخل نافذة المحادثة (24 ساعة).
language اختياريstringالقيمة الافتراضية ar.
name اختياريstring اسم الحملة، ويجمع هذه الدفعة في السجلات والتقارير.
يجب أن يغطي رصيدك الدفعة كاملة قبل بدئها، وإلا يُرفض الطلب بالرمز 402 ولا يُرسل شيء.
cURL
# أرقام كثيرة ومتغير مشترك واحد
curl -X POST https://hudhudiraq.com/api.php/v1/messages/bulk \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Weekend offer",
        "template": "weekend_offer",
        "language": "ar",
        "variables": ["Ramadan Sale"],
        "to": ["+9647500000001", "+9647500000002", "+9647500000003"]
      }'

# أو مجموعة قيم مختلفة لكل شخص
curl -X POST https://hudhudiraq.com/api.php/v1/messages/bulk \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "template": "booking_reminder",
        "language": "ar",
        "recipients": [
          {"to":"+9647500000001","variables":["Ahmed","30/6","5:30PM"]},
          {"to":"+9647500000002","variables":["Sara","1/7","6:00PM"]}
        ]
      }'
PHP
$payload = [
    'name'       => 'Friday reminders',
    'template'   => 'booking_reminder',
    'language'   => 'ar',
    'recipients' => [
        ['to' => '+9647500000001', 'variables' => ['Ahmed', '30/6', '5:30PM']],
        ['to' => '+9647500000002', 'variables' => ['Sara', '1/7', '6:00PM']],
    ],
];
Node.js
await bulk({
    name: 'Friday reminders',
    template: 'booking_reminder',
    language: 'ar',
    recipients: [
        { to: '+9647500000001', variables: ['Ahmed', '30/6', '5:30PM'] },
        { to: '+9647500000002', variables: ['Sara', '1/7', '6:00PM'] },
    ],
});
Python
bulk({
    "name": "Friday reminders",
    "template": "booking_reminder",
    "language": "ar",
    "recipients": [
        {"to": "+9647500000001", "variables": ["Ahmed", "30/6", "5:30PM"]},
        {"to": "+9647500000002", "variables": ["Sara", "1/7", "6:00PM"]},
    ],
})
الاستجابة
{
  "ok": true,
  "campaign_id": 312,
  "total": 2,
  "sent": 1,
  "failed": 1,
  "results": [
    { "to": "+9647500000001", "ok": true,  "message_id": 4830, "status": "sent",   "error": null },
    { "to": "+9647500000002", "ok": false, "message_id": 4831, "status": "failed",
      "error": "Receiver is not a valid WhatsApp user" }
  ]
}

حالة الرسالة #

GET/v1/messages/{id}

يعود طلب الإرسال فورًا، لذا تُعرف حالة التسليم لاحقًا. استعلم من نقطة الوصول هذه باستخدام message_id الذي حصلت عليه.

كم مرة تستعلم؟

تصل معظم الرسائل إلى sent خلال ثانية أو ثانيتين، وإلى delivered خلال ثوانٍ إذا كان الهاتف متصلًا. والنمط المعقول: تحقّق بعد 5 ثوانٍ، ثم كل 30 ثانية لبضع دقائق، ثم توقّف واعتمد على صفحة السجلات في لوحة التحكم.

الحالات تتقدم إلى الأمام فقط — فإشعار delivered المتأخر لا يمكنه أبدًا أن يُرجع رسالة معلَّمة مسبقًا بـread.
cURL
curl https://hudhudiraq.com/api.php/v1/messages/4822 \
  -H "Authorization: Bearer hd_your_key_here"
الاستجابة
{
  "message": {
    "id": 4822,
    "recipient_phone": "+9647500000000",
    "status": "delivered",
    "msg_type": "api",
    "template_name": "order_shipped",
    "error_detail": null,
    "cost": "25.0000",
    "created_at": "2026-07-26 11:20:04"
  }
}

الحساب والرصيد والتقارير #

GET/v1/me

لمن يعود المفتاح، وهل يستطيع الإرسال الآن. استدعِها عند بدء التشغيل: فقيمة can_send: false تخبرك بالسبب قبل أن تفشل أي رسالة.

GET/v1/balance

ما تبقى من رصيد وكم تكلّف الرسالة، لتتمكن من رفض حملة في نظامك قبل أن تبدأ.

GET/v1/balance/history

عمليات الخصم والشحن والاسترداد، الأحدث أولًا، مع الرصيد بعد كل عملية. و?limit= حتى 200.

GET/v1/reports

إجماليات لفترة زمنية — حسب الحالة واليوم والقالب. ?from=YYYY-MM-DD&to=YYYY-MM-DD، والافتراضي هو الشهر الحالي.

GET/v1/campaigns

عمليات الإرسال الجماعي مع عدد ما تم تسليمه وما فشل، وتكلفة كل منها.

GET /v1/me
{
  "account": {
    "name": "Your Business",
    "status": "active",
    "balance": 53225,
    "currency": "IQD",
    "numbers": 3,
    "can_send": true,
    "blocked_reason": null,
    "default_sender": "100000000000001",
    "counts": { "contacts": 18, "templates": 13, "messages": 230 }
  }
}
GET /v1/balance
{
  "balance": 53225,
  "currency": "IQD",
  "rates": { "utility": 25, "authentication": 25, "marketing": 55, "service": 0 }
}
GET /v1/reports
{
  "from": "2026-07-01",
  "to": "2026-07-31",
  "total": 29,
  "spent": 550,
  "by_status": { "read": 20, "sent": 2, "failed": 6, "no_whatsapp": 1 },
  "daily": [ { "day": "2026-07-18", "n": 4, "cost": "100.0000" } ],
  "by_template": [ { "template_name": "order_shipped", "n": 12 } ]
}

سجل الرسائل #

GET/v1/messages

كل ما أرسلته، الأحدث أولًا — وهي البيانات نفسها التي تعرضها صفحة السجلات في لوحة التحكم.

معامل الاستعلامملاحظات
limitمن 1 إلى 200، والافتراضي 50.
statusإحدى الحالات.
sinceتاريخ أو تاريخ ووقت؛ تُعرض الرسائل الأحدث منه فقط.
before_idللتنقل بين الصفحات: مرّر قيمة next_before_id من الصفحة السابقة.
الاستعلام من نقطة الوصول هذه مع since كل بضع دقائق هو أبسط طريقة لنقل حالات التسليم إلى قاعدة بياناتك، ما دامت إشعارات Webhook غير متاحة بعد.
الاستجابة
{
  "messages": [
    {
      "id": 4830,
      "recipient_phone": "+9647500000001",
      "recipient_name": null,
      "status": "read",
      "msg_type": "api",
      "template_name": "order_shipped",
      "body": "Hi Ahmed, order ORD-1024 is on its way.",
      "error_detail": null,
      "cost": "25.0000",
      "from_pnid": "100000000000001",
      "campaign_id": null,
      "created_at": "2026-07-26 11:20:04"
    }
  ],
  "next_before_id": 4830
}

جهات الاتصال #

GET/v1/contacts

جهات اتصالك المحفوظة. صفِّ النتائج بـ?q= (الاسم أو الرقم) و?tag=، و?limit= حتى 500.

POST/v1/contacts

أضف جهة اتصال. الحقلان name وphone مطلوبان، والقيمة الافتراضية لـtag هي Lead. ويقبل fields حتى 20 زوجًا من المفاتيح والقيم الخاصة بك، ويمكن لعمليات الإرسال الجماعي استخدامها لملء متغيرات القوالب. والرقم الموجود مسبقًا يعيد 409 مع معرّف جهة الاتصال الموجودة.

PUT/v1/contacts/{id}

حدّث أيًّا مما يلي: name وphone وtag وfields.

DELETE/v1/contacts/{id}

احذف جهة الاتصال. تبقى الرسائل المرسلة سابقًا إلى هذا الشخص في سجلك.

cURL
curl -X POST https://hudhudiraq.com/api.php/v1/contacts \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Ahmed Ali",
        "phone": "+9647500000001",
        "tag": "Customer",
        "fields": { "city": "Baghdad", "order": "ORD-1024" }
      }'
Python
requests.post(
    "https://hudhudiraq.com/api.php/v1/contacts",
    headers={"Authorization": "Bearer hd_your_key_here",
             "Content-Type": "application/json"},
    json={"name": "Ahmed Ali", "phone": "+9647500000001",
          "tag": "Customer", "fields": {"city": "Baghdad"}},
)
Node.js
await fetch('https://hudhudiraq.com/api.php/v1/contacts', {
    method: 'POST',
    headers: {
        Authorization: 'Bearer hd_your_key_here',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'Ahmed Ali', phone: '+9647500000001',
        tag: 'Customer', fields: { city: 'Baghdad' },
    }),
});
الاستجابة
{
  "ok": true,
  "id": 149,
  "contact": {
    "name": "Ahmed Ali",
    "phone": "+9647500000001",
    "tag": "Customer",
    "fields": { "city": "Baghdad", "order": "ORD-1024" }
  }
}

الجدولة #

POST/v1/schedules

ضع عملية إرسال في الانتظار لوقت لاحق. قيمة payload هي تمامًا جسم الطلب الذي كنت سترسله إلى /v1/messages — أو إلى /v1/messages/bulk مع "kind": "bulk". تُنفَّذ العملية على خوادمنا، فلا يلزم أن يبقى أي شيء متصلًا من جهتك، ولا تُحتسب إلا عند إرسالها فعلًا.

الحقلملاحظات
send_at مطلوب موعد الإرسال، مثل 2026-08-01 09:30. ويجب أن يكون في المستقبل.
payload مطلوب الرسالة، تمامًا كما تقبلها نقاط وصول الإرسال.
kind اختياري send (الافتراضي) أو bulk.
label اختياري يظهر في صفحة المجدولة في لوحة التحكم.
GET/v1/schedules

كل ما هو في الانتظار أو أُرسل أو أُلغي، الأحدث أولًا.

DELETE/v1/schedules/{id}

ألغِ عملية لم تُنفَّذ بعد. أي عملية أُرسلت بالفعل تعيد 404.

جدولة إرسال
curl -X POST https://hudhudiraq.com/api.php/v1/schedules \
  -H "Authorization: Bearer hd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "send_at": "2026-08-01 09:30",
        "kind": "send",
        "label": "Monday reminder",
        "payload": {
          "to": "+9647500000001",
          "template": "booking_reminder",
          "language": "ar",
          "variables": ["Ahmed", "1/8", "09:30"]
        }
      }'
الاستجابة
{ "ok": true, "id": 12, "send_at": "2026-08-01 09:30:00", "status": "pending" }

نوافذ المحادثة المفتوحة #

GET/v1/windows

الأشخاص الذين يمكنك أن ترسل إليهم نصًا حرًا الآن، لأنهم راسلوك خلال آخر 24 ساعة — وكم تبقى من الوقت في نافذة كل منهم.

استخدمها لتقرر، لكل مستلم، هل ترسل ردًا نصيًا حرًا رخيصًا أم قالبًا مدفوعًا. وأي شخص غير موجود في هذه القائمة يحتاج إلى قالب.

الاستجابة
{
  "open": [
    { "phone": "+9647500000001",
      "last_message_at": "2026-07-26 09:12:40",
      "closes_in_minutes": 903 }
  ],
  "window_hours": 24
}

مرجع الحالات #

الحالةالمعنىالاحتساب
queuedاستلمناها، وهي في طريقها إلى واتساب.مبلغ محجوز
sentقبلها واتساب ويعمل على تسليمها.نعم
deliveredوصلت إلى هاتف المستلم.نعم
readفتحها المستلم.نعم
failedرفضها واتساب أو تعذّر تسليمها — ويوضح error_detail السبب.يُسترد المبلغ
no_whatsappلا يوجد حساب واتساب على هذا الرقم. توقّف عن إعادة المحاولة.يُسترد المبلغ

القوالب #

GET/v1/templates

كل قالب يستطيع حسابك إرساله، مع لغته وفئته ونصه — لتبني قائمة المتغيرات دون تخمين.

الحقلملاحظات
nameاستخدم هذه القيمة نفسها في template.
langمرّرها في language. وقد يوجد الاسم نفسه بعدة لغات.
categoryUtility أو Marketing أو Authentication — وهي التي تحدد السعر.
statusلا يمكن إرسال إلا القوالب ذات الحالة Approved.
bodyالنص المعتمد، مع متغيرات {{1}}.
url_buttonsعدد قيم button_variables التي يتوقعها القالب.
header_formatNONE أو TEXT أو IMAGE أو VIDEO أو DOCUMENT. وأي قيمة غير القيمتين الأوليين تعني أن الإرسال يحتاج إلى header_value.
header_textنص الترويسة عندما تكون من نوع TEXT. ويُملأ {{1}} فيها بقيمة header_value.
header_mediaالملف الافتراضي المحفوظ لهذا القالب في لوحة التحكم، ويُستخدم كلما حُذف header_value.
cURL
curl https://hudhudiraq.com/api.php/v1/templates \
  -H "Authorization: Bearer hd_your_key_here"
الاستجابة
{
  "templates": [
    {
      "name": "order_shipped",
      "lang": "en",
      "category": "Utility",
      "status": "Approved",
      "body": "Hi {{1}}, order {{2}} is on its way.",
      "url_buttons": 0
    }
  ]
}

الأرقام #

GET/v1/numbers

أرقام واتساب التي يملكها نشاطك التجاري حاليًا. والرقم المعلَّم بـdefault: true هو الذي تخرج منه رسائل API.

الحقلملاحظات
phone_number_idمعرّف الرقم لدى ميتا.
display_phoneالرقم كما يراه العملاء.
waba_idحساب واتساب الذي يتبعه الرقم — والقوالب مقتصرة على هذا الحساب.
statusconnected عندما يكون جاهزًا للإرسال.
defaulttrue للرقم الذي تستخدمه رسائل API.
الاستجابة
{
  "numbers": [
    {
      "phone_number_id": "100000000000001",
      "waba_id": "200000000000001",
      "display_phone": "+964 750 000 0000",
      "status": "connected",
      "default": true
    }
  ]
}

الأسعار والفوترة #

تُخصم كل رسالة من رصيد حسابك لحظة قبول واتساب لها. وكل ما يرفضه واتساب يُسترد تلقائيًا — فلا تدفع أبدًا عن رسالة لم تُرسل.

الرسالةالسعر
قالب خدمي40 29 د.ع
قالب مصادقة40 29 د.ع
قالب تسويقي80 59 د.ع
نص حر داخل نافذة المحادثة (24 ساعة)0 د.ع حاليًا

قد تتغير الأسعار في أي وقت. السعر المشطوب هو السعر المعتاد، وتعرض لوحة التحكم دائمًا السعر الذي ينطبق عليك.

فئة القالب نفسها هي التي تحدد السعر، لذا تحقّق من category قبل أي حملة كبيرة. اشحن رصيدك من صفحة الرصيد في لوحة التحكم، أما استئجار الرقم فيُحتسب بشكل منفصل كل 30 يومًا.

رصيد غير كافٍ
HTTP 402
{ "error": "الرصيد غير كافٍ" }
يعود المبلغ المسترد إلى رصيدك خلال ثوانٍ من إبلاغ واتساب بفشل الرسالة، ويظهر في سجل الاستخدام في لوحة التحكم.

الأخطاء #

تستخدم الأخطاء رموز حالة HTTP القياسية وتعيد دائمًا الشكل نفسه: { "error": "وصف المشكلة" }. والنص مكتوب ليُعرض على المستخدم، لذا يمكنك تسجيله أو عرضه مباشرةً.

الرمزالمعنىما العمل
401مفتاح API مفقود أو غير صالح.تحقّق من ترويسة Authorization.
402لا يوجد رصيد كافٍ، أو لا يوجد رقم في الحساب.اشحن رصيدك، أو استأجر رقمًا.
403الحساب موقوف، أو القالب محظور.تواصل مع الدعم.
404نقطة وصول أو معرّف رسالة غير معروف.تحقّق من المسار والمعرّف.
422خطأ في جسم الطلب — رقم غير صالح، أو حقل ناقص، أو قالب على حساب آخر.اقرأ error، فهو يذكر الحقل المعني.
500حدث خطأ من جهتنا.أعد المحاولة بعد قليل، ولم يُخصم أي مبلغ.
الاستجابة 200 مع "status": "failed" ليست خطأ API — بل تعني أننا قبلنا الطلب ثم رفض واتساب الرسالة. ويحمل error_detail السبب الذي أرسله واتساب نفسه.

الحدود #

الحدالقيمة
عدد المستلمين في الطلب الجماعي الواحدحتى 25,000 (تحدد المنصة الرقم الدقيق لحسابك)
عدد الرسائل يوميًايحدده واتساب لكل رقم (حسب المستوى) لا نحن — ويظهر في صفحة أرقام الهاتف في لوحة التحكم.
النص الحرخلال 24 ساعة فقط من آخر رسالة أرسلها العميل.
متغيرات القالبيجب أن يحصل كل {{n}} في النص على قيمة.

أرسل الرسائل بطلب واحد في كل مرة لكل مستلم. لا حاجة إلى فتح عشرات الاتصالات المتوازية، فالإرسال الجماعي موجود تحديدًا كي لا تضطر إلى ذلك.

الأسئلة الشائعة #

لماذا يرى المستلم رقمي بدلًا من اسم نشاطي التجاري؟

لا يعرض واتساب اسم النشاط التجاري في أعلى المحادثة إلا للحسابات الحاصلة على شارة الحساب التجاري الرسمي (Official Business Account). ويبقى الاسم المعروض ظاهرًا في ملفك الشخصي. اسألنا عن التقديم للحصول على الشارة.

هل يمكنني إرسال صور أو ملفات PDF أو أزرار؟

ليس عبر v1 حتى الآن — النصوص والقوالب (بما فيها القوالب ذات أزرار الروابط) مدعومة اليوم. أخبر الدعم بما تحتاج وسنمنحه الأولوية.

هل ترسلون تحديثات التسليم إلى خادمي؟

ليس بعد. استعلم حاليًا عبر GET /v1/messages/{id}، وإشعارات Webhook الصادرة ضمن خططنا القادمة.

هل توجد بيئة تجريبية (Sandbox)؟

أرسل إلى رقمك أولًا — يكلّف ذلك رسالة واحدة ويختبر مسار الإنتاج الفعلي نفسه.

ماذا يحدث إذا أرسلت الرسالة نفسها مرتين؟

تُسلَّم مرتين وتُحتسب مرتين، فلا توجد إزالة تلقائية للتكرار. احتفظ بسجلك الخاص لما أرسلته.

الدعم #

افتح تذكرة من صفحة الدعم في لوحة التحكم — فهي تصلنا مرفقةً ببيانات حسابك، وهذه أسرع طريقة للحصول على إجابة. وأرفق message_id عندما تسأل عن رسالة معيّنة.

افتح لوحة التحكم ←