المطورون
مرجع API
نقطة نهاية واحدة للإرسال، وأخرى لقراءة الحالة، وويب هوك موقّعة بـHMAC للإيصالات. تُصدَر المفاتيح لحظة إنشاء الحساب — لا شيء يحتاج إلى موافقة ولا أحد يُراسَل.
البدء
ثلاثة أشياء تفصل بين حساب جديد ورسالة مسلَّمة: رمز، وبعض الرصيد، ومفتاح. لا يتدخّل بشر في أيٍّ منها.
- أنشئ حسابًا — يُنشئ متصفحك الرمز (token)، وهذا الرمز هو الحساب.
- موّله. الحد الأدنى $40، بأي من العملات المذكورة في صفحة المدفوعات.
- أنشئ مفتاح API في لوحة التحكم. يُعرض مرة واحدة فقط؛ ونحتفظ بتجزئته فقط، تمامًا كما هو الحال مع الرمز.
مفتاح على رصيد فارغ لا يمكنه الإرسال
إنشاء المفاتيح مقيَّد عمدًا بحساب ممول. بيانات اعتماد غير مستخدمة تظل معلّقة عبء بلا فائدة، لذا لن تُنشئ لوحة التحكم مفتاحًا حتى يكون هناك ما يُنفَق.
المصادقة
رمز حامل (bearer token) في كل طلب. يُعرِّف المفتاح الحساب؛ لا عامل تحقق ثانٍ، لا توقيع على الطلب، ولا قائمة عناوين IP مسموح بها — المفتاح هو بيانات الاعتماد بأكملها، فتعامل معه على هذا الأساس.
Authorization: Bearer ws_live_9f2c…
| النقل | HTTPS فقط. يُرفض الطلب عبر HTTP العادي ولا تتم إعادة توجيهه — فإعادة التوجيه كانت ستُسرّب المفتاح مسبقًا. |
|---|---|
| النطاق | يخصم كل مفتاح من رصيد حساب واحد. أنشئ مفتاحًا واحدًا لكل نظام يرسل، بحيث يقتصر إلغاء أي تسريب على نطاق ضيق. |
| الإلغاء | فوري. يُعيد المفتاح الملغى 401 في الطلب التالي؛ أما الدفعات الجارية المقبولة مسبقًا فتكتمل كما هي. |
| الاستعادة | لا شيء. نحتفظ بتجزئة فقط. المفتاح المفقود يُستبدل، ولا يُسترجع أبدًا. |
إرسال الرسائل
POST/v1/messages
استدعاء واحد، مستلم واحد أو عدة مستلمين، وجهات مختلطة. يُسعَّر كل مستلم بسعر وجهته الخاصة ويُحتسب لكل مقطع. يُقبل الاستدعاء أو يُرفض ككل؛ لا يُحاسبك جزئيًا أبدًا.
نص الطلب
| حقل | النوع | ملاحظات |
|---|---|---|
to | string[] | مطلوب. بصيغة E.164، حتى 5,000 رقم في كل طلب. تُرفض الأرقام التي لا تُطابق وجهة مسعّرة قبل الاحتساب. |
text | string | إلزامي. UTF-8. يتبع عدد المقاطع معيار GSM 03.38 — انظر المقاطع. |
from | string | معرّف مرسل أبجدي رقمي، حتى 11 حرفًا. يُحمل حيث يسمح المسار بذلك؛ راجع معرّفات المرسل. |
vars | object[] | قيم دمج اختيارية، كائن واحد لكل مستلم، تُستبدَل في العناصر النائبة {{name}} قبل احتساب المقاطع. |
callback_url | string | تجاوز اختياري لكل دفعة لـwebhook الحساب. |
reference | string | اختياري. يُعاد إرساله في كل إيصال حتى تتمكن من ربطه بسجلاتك الخاصة. |
مثال
# one call, many recipients, mixed destinations
curl -X POST https://api.worldsms.io/v1/messages \
-H "Authorization: Bearer $WORLDSMS_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "ACME",
"to": ["+447700900123", "+33612345678"],
"text": "Your code is 480913"
}'
{
"batch_id": "b_7Kq2xR9wLm",
"accepted": 2,
"rejected": 0,
"segments": 1,
"cost_usd": 0.0353
}
$0.0137 إلى المملكة المتحدة إضافةً إلى $0.0216 إلى فرنسا — جدول الأسعار يُطبَّق لكل وجهة، لا كمتوسط ممزوج.
التجميع
تُقبل الدفعة فورًا وتُصرَف بمعدّل 200 رسالة في الدقيقة لكل حساب، فتستغرق 50,000 من المستلمين نحو 4 س 10 د. لا ينبغي أن تنتظر الحركة الحساسة للوقت خلف إرسال تسويقي: استخدم مفتاحًا منفصلًا لها.
حالة الرسالة
GET/v1/messages/{batch_id}
الاستطلاع الدوري مدعوم ومحدود المعدّل؛ أما الويب هوكس فهي المسار المقصود. تجمع الاستجابة الدفعة وتسرد حالة كل مستلم.
{
"batch_id": "b_7Kq2xR9wLm",
"status": "done",
"sending": 0,
"delivered": 1,
"undelivered": 1,
"refund_usd": 0.0216
}
refund_usd تُسوّى مرة واحدة فقط، عند انتهاء الدفعة. وتكون قد عادت بالفعل إلى رصيدك بحلول الوقت الذي تستطيع فيه قراءتها.
الرصيد
GET/v1/balance
تحقّق قبل أي إرسال كبير. تُحفظ الأرصدة داخليًا بوحدات ميكرودولار صحيحة — تصل الأسعار إلى أربع خانات عشرية، ولا مكان للأعداد العشرية التقريبية (float) في سجل حركات — وتُعرَض هنا مقرَّبة إلى ست خانات.
{ "balance_usd": 412.905400, "currency": "USD" }
إيصالات التسليم
يُصدَر إيصال لكل مستلم كما يبلّغ عنه المشغّل. هذه هي الحالات الأربع الوحيدة؛ لا توجد فئة «غير معروف» تعني بصمت «فقدناها».
| الحالة | المعنى | تم الفوترة |
|---|---|---|
queued | مقبولة وتنتظر دورها في الدفعة. | نعم |
sent | سُلّمت إلى المشغّل، ولم يصل تأكيد بعد. | نعم |
delivered | أكّد الهاتف استلامها. | نعم |
undelivered | معطّل، أو محظور، أو رُفض المرسل. | مُسترجَع |
الأرقام التي لا تُطابِق وجهة مُسعَّرة تُرفَض عند الإرسال ولا تدخل هذه الدورة إطلاقًا — لا تُحصَّل ثم تُرَدّ، بل ببساطة لا تُحصَّل.
Webhooks
اضبط نقطة نهاية في لوحة التحكم أو لكل دفعة عبر callback_url. نرسل JSON عبر POST ونتوقع 2xx خلال 5 ثوانٍ. تُعاد محاولة الحالات غير 2xx ست مرات بتراجع أسّي على مدى ساعة تقريبًا، ثم تُسقَط.
الحمولة
{
"event": "message.delivered",
"batch_id": "b_7Kq2xR9wLm",
"to": "+447700900123",
"destination": "gb",
"segments": 1,
"cost_usd": 0.0137,
"reference": "order-4471",
"ts": 1785312041
}
جارٍ التحقق من التوقيع
يحمل كل تسليم X-WorldSMS-Signature وX-WorldSMS-Timestamp. التوقيع هو HMAC-SHA256(timestamp + "." + body) باستخدام سرّ الويب هوك الخاص بك. قارِنه في زمن ثابت، وارفض أي طابع زمني يتجاوز عمره خمس دقائق حتى لا يُعاد تشغيل تسليم مُعتَرَض ضدّك لاحقًا.
// $secret is the webhook secret from the dashboard
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_WORLDSMS_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_WORLDSMS_SIGNATURE'] ?? '';
// A stale timestamp is a replay, however well it is signed.
if (abs(time() - (int) $ts) > 300) { http_response_code(408); exit; }
$mine = hash_hmac('sha256', $ts . '.' . $raw, $secret);
if (!hash_equals($mine, $sig)) { http_response_code(401); exit; }
http_response_code(204);
اجعل الطلب قابلاً للتكرار الآمن
تبدو إعادة المحاولة بعد انتهاء مهلة نقطة النهاية لديك مطابقة لعملية تسليم أولى. استخدم batch_id + to + event كمفتاح، وتعامل مع التكرار كعملية بلا أثر.
الأخطاء
كل فشل يعيد جسم JSON يحتوي على معرّف error ثابت. طابِق على المعرّف لا على النص أبدًا — فالنص قابل للتحسين.
| HTTP | الرابط المختصر | ما العمل |
|---|---|---|
| 400 | invalid_body | JSON غير صالح أو حقل مطلوب مفقود. |
| 401 | key_rejected | مفتاح مفقود، أو مُلغى، أو مكتوب خطأً. غير قابل لإعادة المحاولة. |
| 402 | insufficient_credit | تكلفة الدفعة أكبر من الرصيد المتاح. لم يُرسل شيء؛ اشحن رصيدك وأعد الإرسال. |
| 422 | no_valid_recipients | لم يتم التعرّف على أي رقم كوجهة مسعّرة. |
| 422 | sender_id_invalid | from أطول من 11 حرفًا أو يحتوي على سلسلة أرقام فقط ستُقرأ كرقم. |
| 429 | rate_limited | تمهّل. يحمل Retry-After عدد الثواني. |
| 503 | route_unavailable | الوجهة غير قابلة للتوجيه مؤقتًا. قابلة لإعادة المحاولة. |
{
"error": "insufficient_credit",
"message": "Batch costs $84.20, balance is $12.05.",
"required_usd": 84.20,
"balance_usd": 12.05
}
الحدود
| الطلبات | 60 في الدقيقة لكل مفتاح، بدفعة 20. 429 مع Retry-After بعد ذلك. |
|---|---|
| المستلمون لكل طلب | 5,000. قسّم القوائم الأكبر عبر عدة طلبات، أو ارفع الملف من لوحة التحكم. |
| حجم النص | 2 MB. |
| معدّل الإرسال | 200 رسالة في الدقيقة لكل حساب، بغض النظر عن عدد المفاتيح المرسِلة. |
| مفاتيح | لا حدّ. واحد لكل نظام إرسال هو النمط المقصود. |
تُطبَّق حدود المعدّل على طلبات API لا على الرسائل: الطلب الواحد الذي يحمل 5,000 مستلم يُحتسب بطلب واحد ضمن الحد.
تُصدر المفاتيح فورًا. لا توجد خطوة موافقة.
موّل حسابًا وستُنشئ لوحة التحكم واحدًا فورًا.