Messaging API
راهنمای کامل Messaging API نویدا برای ارسال پیام، زمانبندی ارسال، انتخاب حساب، پیگیری وضعیت پیام و مدیریت خطاها.
Messaging API
Messaging API نویدا برای ارسال پیام به یک گیرنده از طریق حسابهای پیامرسان و سرویسهای پیامک متصل به حساب شما طراحی شده است.
در هر درخواست میتوانید گیرنده، محتوای پیام، کانال یا کانالهای ارسال و نحوه استفاده از آنها را مشخص کنید. پس از پذیرش درخواست، نویدا پیام را ایجاد کرده و فرآیند ارسال را بهصورت غیرهمزمان انجام میدهد.
Base URL
احراز هویت
تمام درخواستهای Messaging API باید با یک API Key ارسال شوند.
API Key را تنها در Backend نگهداری کنید و آن را در Frontend، JavaScript مرورگر یا مخازن عمومی قرار ندهید.
ارسال پیام
این Endpoint یک پیام برای یک گیرنده ایجاد میکند. در صورت پذیرفته شدن درخواست، پاسخ 201 Created برگردانده میشود.
ارسال واقعی پیام بهصورت asynchronous انجام میشود؛ بنابراین پاسخ 201 به معنی تحویل پیام به گیرنده نیست، بلکه به معنی پذیرفته شدن درخواست و ایجاد پیام در نویدا است.
سادهترین درخواست
curl -X POST "https://api.navidaa.ir/v1/messages/send" \
-H "X-API-Key: navidaa_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "09123456789",
"message": "سلام، این یک پیام آزمایشی از نویدا است.",
"channels": ["eitaa"]
}'
پارامترهای درخواست
| پارامتر | نوع | الزامی | توضیح |
|---|---|---|---|
to | string | بله | شماره تلفن گیرنده |
message | string | شرطی | متن پیام؛ در صورت نبود template الزامی است |
template | object | شرطی | قالب پیام؛ نمیتواند همراه message باشد |
channels | string / array | بله | مسیر یا مسیرهای ارسال |
strategy | string | خیر | failover یا broadcast |
metadata | object | خیر | اطلاعات دلخواه مرتبط با پیام |
send_at | datetime | خیر | زمان دقیق ارسال |
delay | string | خیر | تأخیر نسبت به زمان فعلی |
to — گیرنده
شماره تلفن گیرنده است. نویدا فرمتهای متداول شماره تلفن ایران را میپذیرد:
شماره پس از پردازش به فرمت استاندارد ذخیره و برگردانده میشود:
در مستندات و کدهای خود پیشنهاد میشود از فرمتهای متداول شماره موبایل ایران استفاده نمایید.
message — متن پیام
{
"message": "سلام، سفارش شما با موفقیت ثبت شد."
}
- متن پیام نمیتواند خالی باشد.
- پس از حذف فاصلههای ابتدا و انتها نباید خالی شود.
- در تنظیمات فعلی حداکثر 1000 کاراکتر است.
- نمیتواند همزمان با
templateارسال شود.
ارسال با Template
اگر پیام دارای ساختار ثابتی است، میتوانید بهجای ارسال مستقیم متن از قالبهای ساختهشده در داشبورد استفاده نمایید.
{{name}} عزیز،
سفارش {{order_id}} با موفقیت ثبت شد.
curl -X POST "https://api.navidaa.ir/v1/messages/send" \
-H "X-API-Key: navidaa_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "09123456789",
"template": {
"id": 12,
"parameters": {
"name": "علی",
"order_id": "A-123"
}
},
"channels": ["bale"]
}'
تمام پارامترهای تعریفشده در قالب باید دقیقاً ارسال شوند. ارسال پارامتر اضافه یا حذف یکی از پارامترهای موردنیاز باعث رد شدن درخواست خواهد شد.
نام پارامترها باید با حرف انگلیسی یا _ شروع شوند و تنها شامل حروف انگلیسی، اعداد و _ باشند.
یک Template بدون پارامتر نیز معتبر است:
{
"template": {
"id": 15,
"parameters": {}
}
}
در هر درخواست فقط یکی از message یا template را ارسال نمایید.
انتخاب کانال
فیلد channels مشخص میکند پیام از چه کانال یا کانالهایی ارسال شود.
یک کانال
{
"channels": "eitaa"
}
{
"channels": ["eitaa"]
}
چند کانال
{
"channels": ["eitaa", "bale", "sms"]
}
ترتیب کانالها در حالت failover اهمیت دارد: Eitaa → Bale → SMS
انتخاب حساب مشخص
این در حالتی هست که به عنوان مثال شما چندین حساب از یک پیامرسان خاص را دارید. برای مثال شما دو حساب ایتا را در داشبورد متصل کردهاید و نیاز دارید یکی از آنها را انتخاب کنید.
{
"channels": [
{
"channel": "eitaa",
"account_id": 15
},
{
"channel": "sms",
"account_id": 22
}
]
}
account_id مربوط به هر حسابتان را میتوانید در داشبورد پیدا کنید.
اگر account_id را مشخص نکنید، نویدا این منطق را استفاده میکند:
- اگر فقط یک حساب فعال برای آن کانال، مثلا ایتا، وجود داشته باشد: همان حساب استفاده میشود.
- اگر چند حساب از کانال وجود داشته باشد: حساب پیشفرض استفاده میشود که در داشبورد میتوانید آن را تعیین نمایید.
- در صورتی که چند حساب وجود داشته باشد و شما پیشفرضی را تعیین نکرده باشید: درخواست رد میشود و خطای
channel_ambiguousرا دریافت خواهید کرد.
اگر برای یک کانال چند حساب دارید، پیشنهاد میشود یک حساب پیشفرض تعیین نمایید.
Strategy یا روش ارسال
زمانی که شما میخواهید پیام خود را از چند حساب یا کانال ارسال کنید این فیلد معنا پیدا میکند.
strategy مشخص میکند نویدا چگونه از کانالهای انتخابشده استفاده کند. مقدار پیشفرض failover است.
Failover
در حالت failover، نویدا کانالها را بهترتیب بررسی میکند. اگر تلاش اول ناموفق شود، از طریق کانال بعدی اقدام میکند.
{
"to": "09123456789",
"message": "سفارش شما ثبت شد.",
"channels": ["eitaa", "bale", "sms"],
"strategy": "failover"
}
اگر ارسال از Eitaa موفق شود، Bale و SMS دیگر استفاده نخواهند شد. تنها در صورتی که تمام مسیرها ناموفق باشند، وضعیت نهایی پیام failed خواهد بود.
Broadcast
در حالت broadcast، پیام از تمام کانالهای انتخابشده برای همان یک گیرنده ارسال میشود.
{
"to": "09123456789",
"message": "اطلاعیه جدید برای حساب شما",
"channels": ["eitaa", "bale"],
"strategy": "broadcast"
}
Broadcast در Messaging API به معنی ارسال به چند شماره تلفن نیست. اگر برخی کانالها موفق و برخی ناموفق باشند، وضعیت پیام میتواند partial_failed باشد.
Metadata
با metadata میتوانید اطلاعات دلخواه سیستم خود را همراه پیام ذخیره نمایید.
{
"metadata": {
"order_id": "A-123",
"user_id": "42"
}
}
این اطلاعات در فرآیند ارسال دخالتی ندارند و برای مرتبط کردن پیام نویدا با دادههای سیستم شما مناسب هستند. برای مثال: order_id، user_id، invoice_id یا ticket_id.
metadata هنگام دریافت وضعیت پیام نیز برگردانده خواهد شد.
زمانبندی ارسال
پیام میتواند بلافاصله یا در آینده ارسال شود. دو روش برای زمانبندی وجود دارد: send_at و delay. در یک درخواست فقط یکی از این دو قابل استفاده است.
ارسال در زمان مشخص — send_at
{
"to": "09123456789",
"message": "یادآوری جلسه شما",
"channels": ["eitaa"],
"send_at": "2026-09-20T18:00:00+03:30"
}
send_at باید یک تاریخ معتبر ISO 8601 باشد. اگر timezone ارسال نشود، مثل 2026-09-20T18:00:00، زمان براساس منطقه زمانی Asia/Tehran تفسیر میشود.
در صورت ارسال timezone، مثل 2026-09-20T18:00:00+03:30، نویدا زمان را به UTC تبدیل و ذخیره میکند. حداکثر زمان قابل برنامهریزی در حال حاضر ۳۰ روز آینده است.
ارسال با تأخیر — delay
{
"delay": "30m"
}
واحدهای پشتیبانیشده: s ثانیه، m دقیقه، h ساعت، d روز.
نمونههای معتبر: 30s، 15m، 2h، 3d
نمونههای نامعتبر: 0m، 30 minutes، 2 hours
مقدار delay نیز نمیتواند پیام را بیش از ۳۰ روز در آینده زمانبندی کند.
Idempotency
برای جلوگیری از ایجاد چند پیام مشابه در اثر retry شدن درخواست از سمت سیستم خود، میتوانید از Header اختیاری Idempotency-Key استفاده نمایید.
curl -X POST "https://api.navidaa.ir/v1/messages/send" \
-H "X-API-Key: navidaa_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: order-A-123-created" \
-H "Content-Type: application/json" \
-d '{
"to": "09123456789",
"message": "سفارش شما ثبت شد.",
"channels": ["eitaa"]
}'
اگر همان Key با همان Request دوباره ارسال شود، پیام جدیدی ایجاد نمیشود و پاسخ قبلی بازگردانده خواهد شد. در این حالت Header پاسخ شامل Idempotency-Replayed: true خواهد بود.
اگر همان Key با محتوای متفاوت ارسال شود، خطای 409 idempotency_key_conflict دریافت میکنید. اگر درخواست قبلی با همان Key هنوز در حال پردازش باشد، خطای 409 idempotency_key_in_progress برمیگردد.
حداکثر طول Idempotency Key برابر با 255 کاراکتر است.
نمونه کامل ارسال
curl -X POST "https://api.navidaa.ir/v1/messages/send" \
-H "X-API-Key: navidaa_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: order-A-123-shipped" \
-H "Content-Type: application/json" \
-d '{
"to": "09123456789",
"template": {
"id": 12,
"parameters": {
"name": "علی",
"order_id": "A-123"
}
},
"channels": ["eitaa", "bale", "sms"],
"strategy": "failover",
"metadata": {
"order_id": "A-123"
},
"delay": "5m"
}'
در این درخواست، گیرنده 09123456789 است، محتوا از Template شماره 12 ساخته میشود، مسیر ارسال Eitaa → Bale → SMS است، استراتژی Failover است، زمان ارسال پنج دقیقه دیگر است و Metadata شامل order_id ذخیره میشود.
پاسخ ایجاد پیام
{
"message_id": "7bc41a7b-3d61-47e3-9da1-8f1812d19c41",
"status": "queued",
"strategy": "failover",
"scheduled_for": null,
"template": null,
"current_channel": {
"type": "messenger",
"provider": "eitaa",
"credential_id": 15,
"label": "حساب ایتا فروشگاه"
}
}
| فیلد | توضیح |
|---|---|
message_id | شناسه عمومی پیام برای پیگیری بعدی |
status | وضعیت فعلی پیام |
strategy | روش ارسال انتخابشده |
scheduled_for | زمان برنامهریزیشده یا null |
template | اطلاعات قالب در صورت استفاده |
current_channel | مسیر فعلی یا اولین مسیر حلشده |
message_id را برای بررسی وضعیت بعدی پیام نگهداری نمایید.
مشاهده وضعیت پیام
curl "https://api.navidaa.ir/v1/messages/7bc41a7b-3d61-47e3-9da1-8f1812d19c41" \ -H "X-API-Key: navidaa_live_xxxxxxxxxxxxxxxxxxxx"
{
"message_id": "7bc41a7b-3d61-47e3-9da1-8f1812d19c41",
"status": "sent",
"to": "+989123456789",
"strategy": "failover",
"scheduled_for": null,
"template": null,
"metadata": {
"order_id": "A-123"
},
"successful_attempts": 1,
"failed_attempts": 0,
"created_at": "2026-09-16T10:00:00Z",
"completed_at": "2026-09-16T10:00:02Z",
"attempts": [
{
"sequence": 1,
"channel": {
"type": "messenger",
"provider": "eitaa",
"credential_id": 15,
"label": "حساب ایتا فروشگاه"
},
"status": "sent",
"error_code": null,
"error_message": null,
"provider_error": null,
"due_at": "2026-09-16T10:00:00Z",
"attempted_at": "2026-09-16T10:00:01Z",
"finished_at": "2026-09-16T10:00:02Z"
}
]
}
بخش attempts نتیجه هر تلاش واقعی ارسال را نمایش میدهد و در سناریوهای Failover برای بررسی اینکه هر کانال چه نتیجهای داشته بسیار مفید است.
وضعیتهای پیام
| وضعیت | توضیح |
|---|---|
queued | پیام پذیرفته شده و منتظر ارسال یا زمان برنامهریزیشده است |
sending | حداقل یک تلاش ارسال در حال پردازش است |
sent | فرآیند پیام با نتیجه موفق تکمیل شده است |
failed | تمام تلاشهای موردنیاز ناموفق بودهاند |
partial_failed | در Broadcast حداقل یک ارسال موفق و حداقل یک ارسال ناموفق بوده است |
Attemptهای هر پیام نیز میتوانند وضعیتهای pending، sending، sent و failed داشته باشند.
هزینه ارسال
هزینه نویدا براساس ارسال موفق از حسابهای پیامرسان شما محاسبه میشود. ارسال ناموفق هزینهای از کیف پول نویدا کسر نمیکند.
| نتیجه | هزینه نویدا |
|---|---|
| Messenger success | دارای هزینه |
| Messenger failed | بدون هزینه |
| SMS success | بدون هزینه Navidaa |
| SMS failed | بدون هزینه Navidaa |
در SMS، هزینه ارسال مستقیماً توسط سرویسدهنده SMS متصل شما محاسبه میشود.
در حالت failover هنگام پذیرش درخواست، موجودی کافی برای یک ارسال موفق پیامرسان بررسی میشود. در حالت broadcast، کیف پول باید موجودی کافی برای حداکثر تعداد ارسالهای موفق و قابل محاسبه در مسیر را داشته باشد.
اگر موجودی کافی نباشد، خطای insufficient_balance دریافت خواهید کرد.
Rate Limit
Messaging API دارای محدودیتهایی در سطح مشتری، شماره گیرنده و حساب پیامرسان است. علاوه بر محدودیت پلن، هر حساب متصل نیز محدودیت ارسال مستقل دارد.
| کانال | حداکثر پیشفرض |
|---|---|
| Eitaa | 30 پیام در دقیقه |
| Bale | 30 پیام در دقیقه |
| Soroush+ | 20 پیام در دقیقه |
| Rubika | 20 پیام در دقیقه |
| Telegram | 20 پیام در دقیقه |
حداقل فاصله پیشفرض میان دو ارسال از یک حساب: 1000ms.
اگر یک Account در وضعیت cooldown باشد یا به محدودیت خود رسیده باشد، آن Attempt ارسال نمیشود و در حالت failover نویدا میتواند مسیر بعدی را امتحان کند.
خطاهای API
ساختار استاندارد خطا:
{
"error": {
"code": "template_parameters_mismatch",
"message": "Template parameters must exactly match the template placeholders.",
"details": {
"template_id": 12,
"expected": ["name", "order_id"],
"missing": [],
"extra": ["foo"]
}
},
"request_id": "..."
}
request_id را هنگام ارتباط با پشتیبانی نگهداری نمایید؛ این شناسه میتواند برای بررسی درخواست مشخص استفاده شود.
| Code | معنی |
|---|---|
invalid_phone | شماره گیرنده معتبر نیست |
message_required | نه Message و نه Template معتبر ارسال نشده است |
message_too_long | متن از حداکثر طول مجاز بیشتر است |
channels_required | کانال ارسال مشخص نشده است |
invalid_strategy | Strategy معتبر نیست |
invalid_delay | مقدار Delay معتبر نیست |
schedule_must_be_future | زمان ارسال باید در آینده باشد |
schedule_too_far | زمان ارسال بیش از محدوده مجاز است |
template_not_found | قالب موردنظر پیدا نشد |
template_invalid | قالب قابل استفاده نیست |
template_parameters_mismatch | پارامترها با قالب مطابقت ندارند |
channel_unavailable | کانال موردنظر در دسترس نیست |
channel_ambiguous | برای کانال چند حساب وجود دارد و حساب مشخصی قابل انتخاب نیست |
channel_account_not_found | Account موردنظر یافت نشد |
channel_account_mismatch | Account با Channel درخواستشده مطابقت ندارد |
duplicate_channel | یک مسیر تکراری در Channels ارسال شده است |
sms_message_config_missing | تنظیمات لازم حساب SMS کامل نیست |
insufficient_balance | موجودی کیف پول کافی نیست |
idempotency_key_too_long | Idempotency Key بیش از حد مجاز است |
idempotency_key_conflict | Key قبلاً با Payload دیگری استفاده شده است |
idempotency_key_in_progress | درخواست قبلی با همان Key هنوز در حال پردازش است |
test_key_not_allowed | Test Key برای این Endpoint قابل استفاده نیست |
نکات مهم
پیش از ارسال پیام به این موارد توجه نمایید:
channelsهمیشه الزامی است.- تنها یکی از
messageیاtemplateقابل استفاده است. - تنها یکی از
send_atیاdelayقابل استفاده است. - هر Request تنها برای یک گیرنده ایجاد میشود.
broadcastبه معنی ارسال در چند کانال برای همان گیرنده است.- ارسال واقعی بهصورت غیرهمزمان انجام میشود؛ برای نتیجه نهایی از
message_idاستفاده نمایید.