API v2 (تجريبي)
الرسائل
أرسل رسالة الآن أو في وقت محدد، إلى رقم هاتف أو مجموعة WhatsApp أو جهة اتصال محفوظة أو اسم مستخدم على Telegram. أرسل الرسالة نفسها إلى ما يصل إلى 1,000 مستلم في طلب واحد، واقرأ السجل، وتابع حالة الرسالة، وألغِها ما دامت تنتظر.
| العملية | نقطة النهاية | النطاق |
|---|---|---|
| إرسال رسالة | POST /api/v2/messages | messages:send |
| الإرسال إلى عدة مستلمين | POST /api/v2/messages/batch | messages:send |
| عرض الرسائل | GET /api/v2/messages | messages:read |
| جلب رسالة | GET /api/v2/messages/{id} | messages:read |
| إلغاء رسالة | DELETE /api/v2/messages/{id} | messages:send |
تعمل المفاتيح والأخطاء وIdempotency-Key والحدود كما هو موضّح في نظرة عامة على API v2. ولتعرف متى أُرسلت الرسالة أو فشلت دون استعلام متكرر، أضف نقطة استقبال webhook.
إرسال رسالة#
https://wbiztool.com/api/v2/messagesالنص (Body): JSON (application/json)
تدخل الرسالة قائمة الانتظار وتصل الاستجابة قبل إرسالها، برمز HTTP 202 ومعها Message بالحالة queued (أو scheduled إذا كان send_at في المستقبل). تابعها عبر جلب رسالة أو webhook.
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 '{
"from": 101,
"to": { "phone": "+919876543210" },
"text": "Hi Asha, your order #1042 is ready."
}'import os
import requests
response = requests.post(
"https://wbiztool.com/api/v2/messages",
headers={
"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}",
"Idempotency-Key": "order-1042-ready",
},
json={
"from": 101,
"to": {"phone": "+919876543210"},
"text": "Hi Asha, your order #1042 is ready.",
},
timeout=30,
)
body = response.json()
if response.status_code == 202:
print("Queued:", body["id"], body["status"])
else:
print("Refused:", body["error"]["code"], body["error"]["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "order-1042-ready",
},
body: JSON.stringify({
from: 101,
to: { phone: "+919876543210" },
text: "Hi Asha, your order #1042 is ready.",
}),
});
const body = await response.json();
if (response.status === 202) {
console.log("Queued:", body.id, body.status);
} else {
console.error("Refused:", body.error.code, body.error.message);
}<?php
$ch = curl_init('https://wbiztool.com/api/v2/messages');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: order-1042-ready',
],
CURLOPT_POSTFIELDS => json_encode([
'from' => 101,
'to' => ['phone' => '+919876543210'],
'text' => 'Hi Asha, your order #1042 is ready.',
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 202) {
echo 'Queued: ' . $body['id'] . ' ' . $body['status'];
} else {
echo 'Refused: ' . $body['error']['code'] . ' ' . $body['error']['message'];
}الاستجابة (202):
{
"id": 9817263,
"status": "queued",
"from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
"to": { "phone": "+919876543210", "contact_id": 991 },
"text": "Hi Asha, your order #1042 is ready.",
"media": null,
"send_at": null,
"expires_at": null,
"created_at": "2026-10-18T10:15:02.311Z",
"sent_at": null,
"error": null
}
الجسم
toobjectمطلوبمن يستلمها: حقل واحد بالضبط من
phoneأوgroupأوcontact_idأوusername. راجع المستلمون.frominteger or nullمطلوب ما لم يكن لدى مساحة العمل رقم متصل واحدقيمة
idللرقم الذي يرسلها، من عرض الأرقام. إذا حذفته، فسيرسلها الرقم المتصل الوحيد: يُستخدم رقم WhatsApp المتصل الوحيد حتى لو كان حساب Telegram متصلًا أيضًا، ولا يُستخدم حساب Telegram إلا عندما لا يكون أي رقم WhatsApp متصلًا. ويُقبل الرقم الذي سُجّل خروجه: تنتظر رسائله حتى يعود اتصاله.textstringمطلوب ما لم تُرسل وسائطنص الرسالة، حتى 3,000 حرف. مع
mediaيكون هو التعليق ويمكن حذفه. يعمل تنسيق WhatsApp: *bold*و_italic_و~strikethrough~. في JSON، اكتب الأسطر الجديدة بالشكل\n.mediaobject or nullاختياريصورة أو ملف للإرسال. راجع الوسائط.
send_atstring or nullاختياريالإرسال في هذا الوقت بدلًا من الآن: بصيغة ISO 8601 مع فرق التوقيت، مثل
2026-10-20T09:30:00+05:30. يجب أن يكون في المستقبل. راجع الجدولة وانتهاء الصلاحية.expires_atstring or nullاختياريلا تُرسَل بعد هذا الوقت: تصبح الرسالة
expiredبدلًا من ذلك. بصيغة ISO 8601 مع فرق التوقيت، في المستقبل وبعدsend_at.
الترويسات
Authorizationheaderمطلوب
Bearer wbz_live_…، مفتاح له النطاقmessages:send.Idempotency-Keyheaderاختياريأي سلسلة فريدة، حتى لا تؤدي إعادة المحاولة أبدًا إلى إرسال رسالة ثانية. راجع Idempotency-Key.
أخطاء الإرسال#
| HTTP | الرمز | متى |
|---|---|---|
400 | validation_failed | حقل مفقود أو نوعه خاطئ أو غير معروف؛ أو لا يحتوي to على أي من حقوله أو يحتوي على عدة حقول منها؛ أو يحتوي media على url وmedia_id معًا أو على أي منهما؛ أو ليس expires_at بعد send_at |
400 | text_required | لا يوجد text ولا media |
400 | text_too_long | يزيد text على 3,000 حرف |
400 | invalid_datetime | ليس send_at أو expires_at بصيغة ISO 8601 مع فرق التوقيت |
402 | no_credits | لم تتبقَّ لمساحة العمل رسائل في باقتها |
403 | number_not_allowed | المفتاح مقيّد بأرقام أخرى |
403 | account_disabled | حساب مالك مساحة العمل معطّل |
422 | invalid_phone | ليس to.phone رقم هاتف بالصيغة الدولية مع + |
422 | invalid_username | ليس to.username اسم مستخدم على Telegram أو رابطًا أو معرّف tg: |
422 | username_needs_telegram | to.username مع رقم WhatsApp في from |
422 | contact_not_found | لا توجد جهة اتصال بقيمة to.contact_id هذه |
422 | media_not_found | لا يوجد ملف بقيمة media.media_id هذه |
422 | invalid_media_url | ليس media.url رابط http(s) عامًا |
422 | time_in_past | مضى وقت send_at أو expires_at |
422 | number_not_found | ليس from رقمًا في مساحة العمل هذه |
422 | from_required | لا يوجد from، وليس لدى مساحة العمل أي رقم متصل أو لديها عدة أرقام |
422 | message_rejected | تعذّر إدخال الرسالة قائمة الانتظار؛ يوضّح message السبب |
429 | number_daily_cap_reached | أرسل الرقم 1,000 رسالة في آخر 24 ساعة |
الإرسال المرفوض لا يترك أثرًا: لا تُحفظ أي رسالة، فلا يوجد ما يُلغى. أما الأخطاء التي قد تحدث في أي طلب (المفاتيح، والنطاقات، وحدود المعدل، وIdempotency-Key) فهي في صفحة الأخطاء.
الإرسال إلى عدة مستلمين#
https://wbiztool.com/api/v2/messages/batchالنص (Body): JSON (application/json)
يرسل الرسالة نفسها إلى ما يصل إلى 1,000 مستلم. الجسم هو نفسه في إرسال رسالة، إلا أن to قائمة من المستلمين.
- الكل أو لا شيء. يُفحص كل مستلم قبل إدخال أي شيء قائمة الانتظار، ويجب أن تتسع القائمة كلها للرسائل المتبقية في الباقة ولما يتسع له الرقم المرسِل خلال الساعات الـ24 القادمة. إذا كان أحد المستلمين خاطئًا، فلا يدخل شيء قائمة الانتظار، ويحدّده
field، مثلto[3].phone. - المستلم المكرر يتلقى رسالة واحدة.
- تكون الاستجابة
202معdata: Message واحد لكل مستلم، بترتيبto.
curl -X POST https://wbiztool.com/api/v2/messages/batch \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: opening-hours-2026-10-20" \
-d '{
"from": 101,
"to": [
{ "phone": "+919876543210" },
{ "phone": "+447700900123" },
{ "group": "Bakery staff" }
],
"text": "We open at 10 tomorrow."
}'import os
import requests
recipients = ["+919876543210", "+447700900123"]
response = requests.post(
"https://wbiztool.com/api/v2/messages/batch",
headers={
"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}",
"Idempotency-Key": "opening-hours-2026-10-20",
},
json={
"from": 101,
"to": [{"phone": p} for p in recipients] + [{"group": "Bakery staff"}],
"text": "We open at 10 tomorrow.",
},
timeout=60,
)
body = response.json()
if response.status_code == 202:
for message in body["data"]:
print(message["id"], message["to"], message["status"])
else:
print("Refused:", body["error"]["code"], body["error"]["field"], body["error"]["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const recipients = ["+919876543210", "+447700900123"];
const response = await fetch("https://wbiztool.com/api/v2/messages/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "opening-hours-2026-10-20",
},
body: JSON.stringify({
from: 101,
to: [...recipients.map((phone) => ({ phone })), { group: "Bakery staff" }],
text: "We open at 10 tomorrow.",
}),
});
const body = await response.json();
if (response.status === 202) {
for (const message of body.data) console.log(message.id, message.to, message.status);
} else {
console.error("Refused:", body.error.code, body.error.field, body.error.message);
}<?php
$recipients = ['+919876543210', '+447700900123'];
$to = array_map(fn ($phone) => ['phone' => $phone], $recipients);
$to[] = ['group' => 'Bakery staff'];
$ch = curl_init('https://wbiztool.com/api/v2/messages/batch');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: opening-hours-2026-10-20',
],
CURLOPT_POSTFIELDS => json_encode(['from' => 101, 'to' => $to, 'text' => 'We open at 10 tomorrow.']),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 202) {
foreach ($body['data'] as $message) {
echo $message['id'] . ' ' . $message['status'] . "\n";
}
} else {
echo 'Refused: ' . $body['error']['code'] . ' ' . $body['error']['field'];
}الاستجابة (202)، كائن Message واحد لكل مستلم؛ ويشبه الثاني والثالث الأول، مع ضبط to على {"phone": "+447700900123", …} و{"group": "Bakery staff", …}:
{
"data": [
{
"id": 9817264,
"status": "queued",
"from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
"to": { "phone": "+919876543210", "contact_id": 991 },
"text": "We open at 10 tomorrow.",
"media": null,
"send_at": null,
"expires_at": null,
"created_at": "2026-10-19T16:02:40.118Z",
"sent_at": null,
"error": null
}
]
}
أخطاء الإرسال الجماعي#
هي نفسها أخطاء إرسال رسالة واحدة، مع موضع المستلم في field (to[0].phone)، بالإضافة إلى:
| HTTP | الرمز | متى |
|---|---|---|
400 | too_many_recipients | يحتوي to على أكثر من 1,000 عنصر |
400 | validation_failed | to فارغ أو ليس قائمة |
402 | no_credits | لا تتسع القائمة للرسائل المتبقية: يوضّح requested وremaining مقدار الفرق |
429 | number_daily_cap_reached | لا تتسع القائمة لما يتسع له الرقم خلال الساعات الـ24 القادمة: يوضّح requested وroom العدد |
عرض الرسائل#
https://wbiztool.com/api/v2/messagesرسائل مساحة العمل خلال آخر 90 يومًا، الأحدث أولًا، مقسّمة إلى صفحات. ويشمل ذلك الرسائل المرسلة من لوحة التحكم والحملات والتذكيرات والتكاملات وAPI v1، لا رسائل API v2 وحدها. والمفتاح المقيّد ببعض الأرقام لا يرى إلا رسائلها.
معاملات الاستعلام
numberintegerاختياريالرسائل المرسلة من رقم
idهذا فقط.statusstringاختياريالرسائل التي لها هذه الحالة فقط:
queuedأوscheduledأوsentأوdeliveredأوreadأوfailedأوcancelledأوexpired.sincestringاختياريالرسائل المُنشأة في هذا الوقت أو بعده فقط (ISO 8601 مع فرق التوقيت).
untilstringاختياريالرسائل المُنشأة قبل هذا الوقت فقط (ISO 8601 مع فرق التوقيت).
limitintegerاختياريعدد الرسائل في الصفحة، من 1 إلى 100 (الافتراضي 25).
cursorstringاختياريقيمة
next_cursorمن الصفحة السابقة، مع عوامل التصفية نفسها.
يمكن الجمع بين عوامل التصفية. في سلسلة الاستعلام، اكتب + في فرق التوقيت بالشكل %2B (تصل + العادية كمسافة، وتُقرأ هي أيضًا كـ+)، أو استخدم Z.
curl -G https://wbiztool.com/api/v2/messages \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
--data-urlencode "status=failed" \
--data-urlencode "since=2026-10-01T00:00:00+05:30" \
--data-urlencode "limit=100"import os
import requests
headers = {"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"}
params = {"status": "failed", "since": "2026-10-01T00:00:00+05:30", "limit": 100}
failed = []
while True:
page = requests.get("https://wbiztool.com/api/v2/messages",
headers=headers, params=params, timeout=30).json()
failed += page["data"]
if not page["next_cursor"]:
break
params["cursor"] = page["next_cursor"] # same filters, next page
for message in failed:
print(message["id"], message["to"], message["error"]["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const params = new URLSearchParams({ status: "failed", since: "2026-10-01T00:00:00+05:30", limit: "100" });
const failed = [];
while (true) {
const response = await fetch(`https://wbiztool.com/api/v2/messages?${params}`, {
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
const page = await response.json();
failed.push(...page.data);
if (!page.next_cursor) break;
params.set("cursor", page.next_cursor); // same filters, next page
}
for (const message of failed) console.log(message.id, message.to, message.error.message);<?php
$params = ['status' => 'failed', 'since' => '2026-10-01T00:00:00+05:30', 'limit' => 100];
$failed = [];
do {
$ch = curl_init('https://wbiztool.com/api/v2/messages?' . http_build_query($params));
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$page = json_decode(curl_exec($ch), true);
curl_close($ch);
$failed = array_merge($failed, $page['data']);
$params['cursor'] = $page['next_cursor']; // same filters, next page
} while ($page['next_cursor']);
foreach ($failed as $message) {
echo $message['id'] . ' ' . $message['error']['message'] . "\n";
}تكون الاستجابة {"data": [Message, …], "next_cursor": "…" or null}.
أخطاء العرض#
| HTTP | الرمز | متى |
|---|---|---|
400 | validation_failed | ليس number معرّف رقم، أو ليس status إحدى الحالات، أو ليس limit بين 1 و100 |
400 | invalid_datetime | ليس since أو until بصيغة ISO 8601 مع فرق التوقيت |
400 | invalid_cursor | المؤشر تالف أو أُنشئ بعوامل تصفية أخرى |
جلب رسالة#
https://wbiztool.com/api/v2/messages/{id}رسالة واحدة وحالتها الآن.
curl https://wbiztool.com/api/v2/messages/9817263 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"import os
import requests
response = requests.get(
"https://wbiztool.com/api/v2/messages/9817263",
headers={"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"},
timeout=30,
)
message = response.json()
print(message["status"], message["sent_at"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/messages/9817263", {
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
const message = await response.json();
console.log(message.status, message.sent_at);<?php
$ch = curl_init('https://wbiztool.com/api/v2/messages/9817263');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$message = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $message['status'];الاستجابة (200)، لرسالة تم تسليمها:
{
"id": 9817263,
"status": "delivered",
"from": { "id": 101, "phone": "919800000000", "platform": "whatsapp" },
"to": { "phone": "+919876543210", "contact_id": 991 },
"text": "Hi Asha, your order #1042 is ready.",
"media": null,
"send_at": null,
"expires_at": null,
"created_at": "2026-10-18T10:15:02.311Z",
"sent_at": "2026-10-18T10:15:09.870Z",
"error": null
}
الرسالة غير الموجودة، أو التابعة لمساحة عمل أخرى، أو (بالنسبة إلى مفتاح مقيّد ببعض الأرقام) المرسلة من رقم آخر، تُرجع 404 message_not_found.
إلغاء رسالة#
https://wbiztool.com/api/v2/messages/{id}يلغي رسالة لا تزال تنتظر (queued أو scheduled)، أيًّا كان منشئها. تكون الاستجابة 200 مع Message، وحالتها الآن cancelled. وتتلقى نقطة استقبال webhook الحدث message.cancelled.
لا يمكن استرجاع رسالة أُرسلت. والرسالة التي يلتقطها الرقم المرسِل في تلك اللحظة قد تُرسَل رغم ذلك، لذا تحقّق من حالتها بعد ذلك إن كان الأمر مهمًا.
curl -X DELETE https://wbiztool.com/api/v2/messages/9817263 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"import os
import requests
response = requests.delete(
"https://wbiztool.com/api/v2/messages/9817263",
headers={"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"},
timeout=30,
)
body = response.json()
if response.status_code == 200:
print("Cancelled")
elif body["error"]["code"] == "not_cancellable":
print("Too late, it is", body["error"]["status"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/messages/9817263", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
});
const body = await response.json();
if (response.ok) console.log("Cancelled");
else if (body.error.code === "not_cancellable") console.log("Too late, it is", body.error.status);<?php
$ch = curl_init('https://wbiztool.com/api/v2/messages/9817263');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status === 200 ? 'Cancelled' : $body['error']['code'];أخطاء الإلغاء#
| HTTP | الرمز | متى |
|---|---|---|
404 | message_not_found | لا توجد رسالة كهذه لهذا المفتاح |
409 | not_cancellable | لم تعد تنتظر؛ يوضّح status في الخطأ حالتها الآن، مثل sent |
كائن Message#
تُرجع كل عملية في هذه الصفحة كائنات Message، وتحمل أحداث webhook واحدًا منها في data.message.
| الحقل | النوع | الوصف |
|---|---|---|
id | integer | معرّف الرسالة. استخدمه لجلب الرسالة أو إلغائها. |
status | string | موضعها الآن. راجع الحالات. |
from | object | الرقم المرسِل: id، وphone (خاناته مع رمز الدولة، بدون +)، وplatform (whatsapp أو telegram). |
to | object | المستلم: phone (مع +) أو group أو username، وcontact_id، أي جهة الاتصال المحفوظة التي أُرسلت إليها. يُحفظ رقم الهاتف أو المجموعة التي يُرسَل إليها لأول مرة كجهة اتصال. (لا تكون قيمة contact_id هي null إلا في رسالة اختبار إلى رقم غير محفوظ.) |
text | string | النص أو التعليق؛ "" عندما لا يوجد. |
media | object or null | type (image أو file)، وurl، وfile_name (null للصور). قد يكون url رابطًا يعمل لمدة محدودة؛ لا تخزّنه. |
send_at | string or null | الوقت المجدول للإرسال، أو null لـ"الآن". |
expires_at | string or null | الوقت الذي لا تُرسَل بعده، أو null. |
created_at | string | وقت إنشائها. |
sent_at | string or null | وقت إرسالها، بعد أن تُرسَل (sent أو delivered أو read). |
error | object or null | للرسالة failed أو expired، يوضّح message السبب، مثل File exceeds WhatsApp size limit (16MB max). وإلا فهو null. |
الحالات#
| الحالة | المعنى |
|---|---|
queued | تنتظر الإرسال. |
scheduled | تنتظر وقت send_at. |
sent | أُرسلت من رقمك (علامة صح واحدة في WhatsApp). |
delivered | سُلّمت إلى هاتف المستلم (علامتا صح). |
read | قرأها المستلم (علامتا صح زرقاوان). |
failed | تعذّر إرسالها؛ يوضّح error.message السبب. |
cancelled | أُلغيت قبل إرسالها: عبر إلغاء رسالة، أو من لوحة التحكم، أو لأن رقمها أو حملتها أُزيلت. |
expired | لم تُرسَل قبل expires_at. |
يمكن إلغاء queued وscheduled. ويمكن أن تصبح sent لاحقًا delivered ثم read. أما failed وcancelled وexpired وread فهي نهائية. تُبلغ webhooks عن sent وfailed وcancelled وexpired؛ ولمعرفة delivered وread، اجلب الرسالة.
المستلمون#
يقبل to حقلًا واحدًا بالضبط من هذه الحقول:
| الحقل | مثال | من يستلمها |
|---|---|---|
phone | {"phone": "+919876543210"} | رقم هاتف بالصيغة الدولية مع + (E.164). يُسمح بالمسافات والشرطات. |
group | {"group": "Bakery staff"} | مجموعة WhatsApp يكون الرقم المرسِل عضوًا فيها، باسمها الدقيق (حتى 200 حرف). |
contact_id | {"contact_id": 991} | جهة اتصال محفوظة في مساحة العمل، بمعرّفها (قيمة contact_id لرسالة سابقة مثلًا). تُرسَل إلى رقم جهة الاتصال تلك أو مجموعتها. |
username | {"username": "@asha_bakes"} | مستخدم Telegram: @name، أو رابط t.me/name، أو tg: ومعرّف مستخدم. فقط من حساب Telegram، لذا حدّد واحدًا في from (أو اجعل حسابًا واحدًا فقط متصلًا). |
يتطلب الإرسال إلى المجموعات وعلى Telegram أن يكون الرقم المرسِل عضوًا في تلك المجموعة أو قادرًا على الوصول إلى ذلك المستخدم؛ وتظهر المشكلات هنا كرسالة failed، لا كخطأ عند الإرسال.
الوسائط#
يرسل media صورة أو ملفًا، ويكون text تعليقًا عليه. حدّد واحدًا بالضبط من url أو media_id:
media.urlstringإما url أو media_idرابط
httpأوhttpsعام للملف، حتى 1,000 حرف. تُرفض الروابط إلى عناوين خاصة أو محلية بالخطأinvalid_media_url.media.media_idintegerإما url أو media_idملف في مكتبة الوسائط الخاصة بمساحة العمل، من رفع ملف. ارفع الملف مرة واحدة وأرسله كلما شئت.
media.typestringاختياري
imageأوfile. إذا حذفته، فيُرسَل الرابط المنتهي بـ.jpgأو .jpegأو .pngأو .gifأو .webpكصورة وأي رابط آخر كملف؛ أماmedia_idفيستخدم النوع الذي رُفع به الملف.media.file_namestringاختياريلـ
file: الاسم الذي يراه المستلم، مثلinvoice-1042.pdf(حتى 100 حرف). إذا حذفته، فيُؤخذ الاسم من الرابط أو من الملف المرفوع. امتداده يحدّد طريقة إرسال الملف، لذا أضف امتدادًا. يُتجاهل للصور.
{
"to": { "phone": "+919876543210" },
"text": "Your invoice for order #1042",
"media": { "url": "https://example.com/invoices/1042.pdf", "type": "file", "file_name": "invoice-1042.pdf" }
}
يُجلب الملف عند إرسال الرسالة، لا عند استدعاء API، لذا يظهر الرابط المعطّل أو الملف الكبير جدًا كرسالة failed مع السبب في error.message. وقواعد الحجم والنوع هي قواعد v1 نفسها: راجع إرسال الصور والملفات.
الجدولة وانتهاء الصلاحية#
send_atيجدول الرسالة. تبقىscheduledحتى ذلك الوقت، ويمكن إلغاؤها إلى أن تُرسَل. اكتب الوقت مع فرق التوقيت، فـ2026-10-20T09:30:00+05:30تعني 09:30 بتوقيت الهند. وللرسائل المتكررة، استخدم التذكيرات.expires_atموعد نهائي: إذا لم تُرسَل الرسالة بحلوله (لأن الرقم سُجّل خروجه مثلًا)، فتصبحexpiredبدلًا من أن تُرسَل متأخرة. استخدمه لرموز الاستخدام لمرة واحدة، ومواعيد التوصيل، والعروض. تضع مهمة في الخلفية علامة انتهاء الصلاحية بعد 30 ثانية على الأقل من الموعد النهائي، لذا لا تعتمد على مواعيد نهائية أقصر من دقيقة.- يجب أن يكون كلاهما في المستقبل، وأن يكون
expires_atبعدsend_at.
