LOCA در الکامپ ۱۴۰۵ · مسیر هوشمند را از نزدیک تجربه کنید · سالن 38B، غرفه 18LOCA در الکامپ ۱۴۰۵ · سالن 38B، غرفه 18

مشاهده جزئیات

توسعه‌دهندگان / مستندات

LOCA Developer Docs

شروع سریع API لوکا

برای اولین ارسال فقط به یک API Key، یک سرویس فعال و یک درخواست نیاز دارید.

شروع سریع

برای اولین ارسال به سه چیز نیاز دارید: API Key، یک سرویس فعال، و یک درخواست. ساختار درخواست برای همه کانال‌ها یکسان است — فقط channel و در صورت نیاز service_id را عوض کنید.

  • ۱ — ثبت‌نام کنید و وارد پنل LOCA شوید.
  • ۲ — از بخش توسعه‌دهندگان یک API Key بسازید. مقدار کلید فقط همان لحظه نمایش داده می‌شود؛ حتماً ذخیره‌اش کنید.
  • ۳ — اولین درخواست را با هدر X-API-Key ارسال کنید.
POST/api/v1/messages/send

اولین ارسال

درخواست پذیرفته می‌شود و پیام در صف قرار می‌گیرد (۲۰۲).

نمونه درخواست
POST /api/v1/messages/send
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "channel": "sms",
  "service_id": "YOUR_SERVICE_ID",
  "message_list": [
    {
      "phone": "09123456789",
      "text": "سلام از LOCA"
    }
  ]
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}

احراز هویت

هر درخواست به API باید API Key شما را در هدر X-API-Key داشته باشد.

هدر نمونه: X-API-Key: YOUR_API_KEY خطاهای رایج: • بدون کلید → 401 MISSING_AUTH • کلید نامعتبر یا غیرفعال → 403 INVALID_API_KEY • بیش از حد مجاز درخواست → 429 API_KEY_RATE_LIMIT_EXCEEDED

می‌توانید چند API Key برای یک حساب بسازید. مقدار کلید فقط یک‌بار — هنگام ساخت — نمایش داده می‌شود؛ حتماً آن را ذخیره کنید. برای تعویض کلید، یک کلید جدید بسازید و کلید قبلی را غیرفعال یا حذف کنید.

GET/api/v1/api-keys

لیست کلیدها

لیست API Keyهای حساب شما. مقدار کلید در پاسخ برنمی‌گردد.

نمونه درخواست
GET /api/v1/api-keys
X-API-Key: <API_KEY>
POST/api/v1/api-keys

ایجاد کلید

کلید جدید می‌سازد (۲۰۱). فیلد api_key فقط در همین پاسخ نمایش داده می‌شود.

نمونه درخواست
POST /api/v1/api-keys
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "name": "Production",
  "rate_limit_per_min": 600
}
  • rate_limit_per_min پیش‌فرض: ۶۰۰ درخواست در دقیقه.
  • مشاهده: GET /api/v1/api-keys/{id} · ویرایش: PATCH · حذف: DELETE (۲۰۴)

ارسال پیام

ارسال پیام از طریق POST /api/v1/messages/send انجام می‌شود. برای هر کانال همان endpoint را استفاده کنید — فقط channel و service_id را عوض کنید.

  • کانال‌های پشتیبانی‌شده: sms, voice, rubika, bale, eitaa, soroush_plus
  • whatsapp در صورت داشتن سرویس فعال در دسترس است.
  • یکی از channel یا routing_strategy_id الزامی است — هر دو را با هم نفرستید.
  • پاسخ ارسال ۲۰۲ است. وضعیت فوری: queued، queued_with_rejections، queued_for_approval.
POST/api/v1/messages/send

ارسال پیام

حداکثر ۱۰۰٬۰۰۰ گیرنده در هر درخواست.

فیلدنوعتوضیح
channelstringنام کانال — اگر routing_strategy_id نفرستید، اجباری است
routing_strategy_iduuidشناسه مسیر هوشمند — جایگزین channel
service_idstringشناسه سرویس کانال (external_service_id از GET /api/v1/channel-services/me)
channel_service_idsobjectservice_id جدا برای هر کانال — فقط در ارسال با مسیر هوشمند
campaign_namestringنام کمپین — اختیاری
message_listلازمarrayلیست گیرنده‌ها: phone, text, file_id؛ اختیاری: channel_texts, channel_file_ids
phonebook_selectionobjectانتخاب از دفترچه تلفن: group_ids / contact_ids / exclude_contact_ids
link_typestringنوع لینک کوتاه: unique_per_recipient | single_for_campaign
original_urlstringآدرس مقصد برای لینک کوتاه
smart_link_iduuidشناسه لینک هوشمند — اولویت بالاتر از original_url
voice_max_attemptsintتعداد تلاش — ۱ تا ۳، فقط برای channel=voice
voice_retry_interval_secondsintفاصله بین تلاش‌ها — ۶۰ تا ۲۵۹۲۰۰ ثانیه
نمونه درخواست
POST /api/v1/messages/send
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "channel": "sms",
  "service_id": "YOUR_SERVICE_ID",
  "campaign_name": "welcome",
  "message_list": [
    { "phone": "09123456789", "text": "سلام از LOCA" }
  ]
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}
POST/api/v1/messages/sendBulkMessages

ارسال نظیر به نظیر

برای ارسال متن متفاوت به هر گیرنده. ساختار بدنه همان ارسال پیام است.

نمونه درخواست
POST /api/v1/messages/sendBulkMessages
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "channel": "bale",
  "service_id": "YOUR_SERVICE_ID",
  "message_list": [
    { "phone": "09137234754", "text": "سلام علی" },
    { "phone": "09137552590", "text": "سلام سارا" }
  ]
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}

ارسال ثابت

یک متن یا فایل ثابت برای همه گیرنده‌ها. یکی از این سه روش گیرنده را مشخص کنید: receptors، draft_id، یا phonebook_selection.

POST/api/v1/messages/sendBulkStaticMessages

ارسال ثابت

حداکثر ۱۰۰٬۰۰۰ گیرنده. SMS فایل ندارد. در بله، ارسال فقط با فایل و بدون متن مجاز نیست.

فیلدنوعتوضیح
channelstringنام کانال — یا routing_strategy_id
routing_strategy_iduuidشناسه مسیر هوشمند — به‌جای channel
service_idstringشناسه سرویس کانال
messagestringمتن ثابت — حداکثر ۴۰۰۰ کاراکتر
file_idstringشناسه فایل — حداقل یکی از message یا file_id لازم است
receptorsarrayلیست گیرنده‌ها: [{ receptor }]
draft_iduuidشناسه پیش‌نویس از precheck-file
phonebook_selectionobjectانتخاب از دفترچه: group_ids, contact_ids, exclude_contact_ids
idempotency_keystringکلید یکتا برای جلوگیری از ارسال تکراری
link_type / original_url / smart_link_idتنظیمات لینک کوتاه
نمونه درخواست
POST /api/v1/messages/sendBulkStaticMessages
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "channel": "sms",
  "service_id": "YOUR_SERVICE_ID",
  "campaign_name": "static-test",
  "message": "سلام، این پیام برای همه است",
  "receptors": [
    { "receptor": "09123456789" },
    { "receptor": "09120000000" }
  ]
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}
  • پاسخ ممکن است شامل skipped_invalid_input_lines و skipped_duplicate_input_lines باشد.

ارسال پویا

متن هر گیرنده از ستون‌های فایل Excel یا CSV ساخته می‌شود. بعد از آپلود، ردیف‌ها روی سرور ذخیره می‌مانند — در مرحله ارسال فایل را دوباره نفرستید.

  • ۱ — فایل را آپلود کنید: POST /api/v1/messages/parse-dynamic-file (فرمت: xlsx, xls, csv). ردیف اول هدر است؛ ستون اول شماره موبایل.
  • ۲ — (اختیاری) هزینه دقیق را محاسبه کنید: POST /api/v1/messages/prepare-dynamic-send
  • ۳ — منتظر آماده شدن بمانید: GET /api/v1/messages/prepare-dynamic-send/{job_id}
  • ۴ — ارسال کنید: POST /api/v1/messages/sendBulkDynamicMessages با draft_id و message_template (مثلاً «سلام {{name}}»)
POST/api/v1/messages/parse-dynamic-file

آپلود فایل پویا

فایل را می‌خواند و draft_id برمی‌گرداند. هدر ستون‌ها و نمونه ردیف‌ها در پاسخ است.

نمونه درخواست
POST /api/v1/messages/parse-dynamic-file
X-API-Key: <API_KEY>
POST/api/v1/messages/sendBulkDynamicMessages

ارسال پویا

با draft_id از مرحله قبل، پیام‌ها را ارسال می‌کند (۲۰۲).

نمونه درخواست
POST /api/v1/messages/sendBulkDynamicMessages
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "draft_id": "DRAFT_UUID",
  "channel": "sms",
  "service_id": "YOUR_SERVICE_ID",
  "campaign_name": "dynamic-test",
  "message_template": "سلام {{name}}، کد شما {{code}} است"
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}

ارسال از فایل

برای ارسال به لیست شماره از فایل txt یا csv. می‌توانید اول فایل را بررسی کنید و با draft_id در ارسال ثابت استفاده کنید، یا مستقیم ارسال کنید.

POST/api/v1/messages/precheck-file

بررسی فایل شماره

فایل را می‌خواند و draft_id به همراه آمار شماره‌های معتبر و نامعتبر برمی‌گرداند.

نمونه درخواست
POST /api/v1/messages/precheck-file
X-API-Key: <API_KEY>
POST/api/v1/messages/sendBulkFromFile

ارسال مستقیم از فایل

فایل شماره را آپلود و مستقیم ارسال می‌کند. اگر channel نفرستید، rubika پیش‌فرض است.

فیلدنوعتوضیح
fileلازمfileفایل txt یا csv
channelstringنام کانال
service_idstringشناسه سرویس کانال
routing_strategy_idstringشناسه مسیر هوشمند — اختیاری
default_textstringمتن پیش‌فرض پیام
default_file_idstringشناسه فایل پیش‌فرض
campaign_namestringنام کمپین
نمونه درخواست
POST /api/v1/messages/sendBulkFromFile
X-API-Key: <API_KEY>

Template

الگوها متن ازپیش‌تعریف‌شده با متغیر هستند — مثل {code} برای OTP. هر الگو می‌تواند برای چند کانال تعریف شود. فقط الگوی تأییدشده (approved) قابل ارسال است.

  • GET /api/v1/message-templates — لیست الگوها
  • POST /api/v1/message-templates — ساخت الگو (با ?submit=true برای ارسال به تأیید)
  • GET /api/v1/message-templates/{id} — جزئیات
  • PUT /api/v1/message-templates/{id} — ویرایش
  • POST /api/v1/message-templates/{id}/submit — ارسال برای تأیید
  • DELETE /api/v1/message-templates/{id} — حذف (۲۰۴)
POST/api/v1/message-templates

ایجاد الگو

الگوی جدید می‌سازد. حداقل یک کانال لازم است. sms و eitaa از مدیا پشتیبانی نمی‌کنند.

نمونه درخواست
POST /api/v1/message-templates
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "name": "ورود",
  "template_type": "otp",
  "channels": [
    { "channel": "sms", "body": "کد تأیید شما: {code}" }
  ]
}
POST/api/v1/messages/sendBulkTemplateMessages

ارسال با الگو

حداکثر ۱۰۰٬۰۰۰ گیرنده. مدیا از الگوی تأییدشده استفاده می‌شود — file_id روی گیرنده قبول نمی‌شود.

نمونه درخواست
POST /api/v1/messages/sendBulkTemplateMessages
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "template_code": "otp_login",
  "channel": "sms",
  "service_id": "YOUR_SERVICE_ID",
  "receptors": [
    {
      "phone": "09123456789",
      "parameters": { "code": "438291" }
    }
  ]
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}

OTP

OTP از همان endpoint ارسال با الگو است — فقط الگویی با template_type=otp و وضعیت approved استفاده کنید.

  • کد OTP را سیستم شما تولید می‌کند و در parameters می‌فرستید — LOCA کد را generate یا verify نمی‌کند.
  • الگوی otp نمی‌تواند مدیا داشته باشد.
  • Voice OTP: متن الگو فقط یک متغیر مثل {code} یا عدد ۳ تا ۸ رقمی باشد.
  • file_id روی گیرنده نفرستید.
POST/api/v1/messages/sendBulkTemplateMessages

ارسال OTP

الگوی otp باید تأییدشده (approved) باشد.

نمونه درخواست
POST /api/v1/messages/sendBulkTemplateMessages
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "template_code": "otp_login",
  "channel": "sms",
  "service_id": "YOUR_SERVICE_ID",
  "campaign_name": "OTP Login",
  "receptors": [
    {
      "phone": "09123456789",
      "parameters": { "code": "438291" }
    }
  ]
}
نمونه پاسخ
{
  "campaign_id": "…",
  "batch_id": "…",
  "approval_queue_id": null,
  "total_received": 1,
  "accepted": 1,
  "rejected": 0,
  "status": "queued",
  "cost": {
    "total": 1.0,
    "per_message": 1.0,
    "currency": "unit"
  },
  "wallet": {
    "balance": 999,
    "reserved": 1
  },
  "api_version": "v2"
}

مسیر هوشمند

به‌جای انتخاب یک کانال، می‌توانید routing_strategy_id بفرستید تا LOCA کانال‌ها را به ترتیب اولویت امتحان کند. channel و routing_strategy_id را با هم نفرستید.

فعلاً فقط استراتژی priority_fallback پشتیبانی می‌شود: کانال‌ها یکی‌یکی به ترتیب priority_order امتحان می‌شوند. فیلدهای timeout_seconds و delivery_policy ذخیره می‌شوند ولی هنوز در ارسال اعمال نمی‌شوند.
POST/api/v1/routing-strategies

ایجاد مسیر هوشمند

استراتژی جدید می‌سازد. همچنین: GET لیست · GET/PUT/DELETE /{id} · حذف: ۲۰۴

نمونه درخواست
POST /api/v1/routing-strategies
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "name": "OTP fallback",
  "strategy_type": "priority_fallback",
  "channel_priorities": [
    { "channel": "sms", "priority_order": 1, "is_active": true },
    { "channel": "voice", "priority_order": 2, "is_active": true }
  ]
}
POST/api/v1/routing-strategies/{id}/send

ارسال با مسیر هوشمند

پیام را با استراتژی مشخص‌شده ارسال می‌کند (۲۰۲).

نمونه درخواست
POST /api/v1/routing-strategies/{id}/send
X-API-Key: <API_KEY>
Content-Type: application/json

{
  "message_list": [
    { "phone": "09123456789", "text": "کد تأیید: 438291" }
  ],
  "campaign_name": "otp-route"
}

وضعیت پیام

هر پیام دو وضعیت دارد: status وضعیت کلی در LOCA و provider_status وضعیت گزارش‌شده از سمت کانال. برای فیلتر از status_filter و provider_status_filter استفاده کنید.

statusمعنی
queuedدر صف ارسال
pendingمنتظر ارسال به کانال
pending_confirmationارسال شده — منتظر تأیید نهایی
sendingدر حال ارسال
sentارسال موفق
deliveredتحویل داده شده (SMS / WhatsApp)
seenخوانده شده (Rubika / Bale / WhatsApp)
failedناموفق
expiredمنقضی شده
GET/api/v1/messages

لیست پیام‌ها

فیلتر: campaign_id, batch_id, phone, status. صفحه‌بندی: page, page_size (حداکثر ۲۰۰).

نمونه درخواست
GET /api/v1/messages
X-API-Key: <API_KEY>

کمپین‌ها

  • GET /api/v1/campaigns — لیست کمپین‌ها (page, page_size≤۲۰۰, status, search, date_from, date_to)
  • GET /api/v1/campaigns/{id}/stats — آمار کمپین
  • GET /api/v1/campaigns/{id}/messages — پیام‌های کمپین (page_size حداکثر ۲۰۰)
  • GET /api/v1/campaigns/{id}/recipients — گیرنده‌ها (فقط کمپین‌های مسیر هوشمند)
  • POST /api/v1/campaigns/{id}/sync-messages — همگام‌سازی وضعیت با کانال (۲۰۲)
  • GET /api/v1/campaigns/{id}/sync-status/{request_id} — پیگیری همگام‌سازی
  • GET /api/v1/campaigns/export — خروجی Excel همه کمپین‌ها
  • GET /api/v1/campaigns/{id}/messages/export — خروجی Excel پیام‌های یک کمپین

وضعیت کمپین: pending (در انتظار)، running (در حال اجرا)، completed (تمام‌شده)، paused (متوقف)، failed (ناموفق).

خطاها

خطاها با HTTP status code و یک body ساختاریافته برمی‌گردند:

GET/api/v1/…

شکل پاسخ خطا

در خطاهای اعتبارسنجی، detail ممکن است آرایه‌ای از جزئیات فیلدها باشد و error.code برابر VALIDATION_ERROR شود.

نمونه درخواست
GET /api/v1/…
X-API-Key: <API_KEY>
نمونه پاسخ
{
  "detail": {
    "error": {
      "code": "INVALID_API_KEY",
      "message": "…"
    }
  }
}
HTTPcodeمعنی
401MISSING_AUTHAPI Key ارسال نشده
403INVALID_API_KEYکلید نامعتبر یا غیرفعال
429API_KEY_RATE_LIMIT_EXCEEDEDبیش از حد مجاز درخواست
400INVALID_JSONبدنه JSON معتبر نیست
400INVALID_PAYLOADساختار بدنه نادرست
422VALIDATION_ERRORخطا در اعتبارسنجی فیلدها
402INSUFFICIENT_BALANCEموجودی کافی نیست
400WALLET_NOT_FOUNDکیف پول یافت نشد
403WALLET_NOT_ACTIVEکیف پول غیرفعال است
400TEMPLATE_NOT_FOUNDالگو یافت نشد
400TEMPLATE_CHANNEL_NOT_APPROVEDالگو برای این کانال تأیید نشده
400CHANNEL_OR_STRATEGY_REQUIREDchannel یا routing_strategy_id لازم است
400CHANNEL_AND_STRATEGY_CONFLICTchannel و routing_strategy_id با هم مجاز نیست
400TOO_MANY_RECEPTORSتعداد گیرنده بیش از حد مجاز
429RATE_LIMIT_EXCEEDEDسقف سرعت ارسال
429TOO_MANY_CONCURRENT_BATCHESتعداد batch همزمان بیش از حد
413FILE_TOO_LARGEحجم فایل بیش از حد مجاز
404CAMPAIGN_NOT_FOUNDکمپین یافت نشد

محدودیت‌ها

موردمقدار
گیرنده در هر درخواستحداکثر ۱۰۰٬۰۰۰
page_size لیست کمپین / پیام / messagesحداکثر ۲۰۰
page_size لیست مدیاحداکثر ۱۰۰ (پیش‌فرض ۲۴)
حجم فایل مدیا۱۰ مگابایت
batch در دقیقه۱۵۰ (پیش‌فرض)
پیام در ساعت۵۰٬۰۰۰ (پیش‌فرض)
batch همزمان۱۰ (پیش‌فرض)
درخواست در دقیقه (API Key)۶۰۰ (پیش‌فرض)
تلاش مجدد voice۱ تا ۳

کیف پول

هزینه ارسال و موجودی کیف پول به واحد اعتبار محاسبه می‌شود. فیلدهای *_rial معادل ریالی برای نمایش هستند.

GET/api/v1/wallet/me

موجودی

موجودی فعلی، اعتبار رزروشده و مجموع مصرف.

نمونه درخواست
GET /api/v1/wallet/me
X-API-Key: <API_KEY>
GET/api/v1/wallet/transactions

تراکنش‌ها

تاریخچه تراکنش‌ها. page پیش‌فرض ۵۰، حداکثر ۱۰۰. نوع‌ها: charge (شارژ)، reserve (رزرو ارسال)، adjust، refund.

نمونه درخواست
GET /api/v1/wallet/transactions
X-API-Key: <API_KEY>

سرویس‌ها

قبل از ارسال، سرویس‌های فعال کانال‌های خود را ببینید. در درخواست ارسال، فیلد service_id همان external_service_id است.

GET/api/v1/channel-services/me

سرویس‌های من

لیست سرویس‌های فعال هر کانال: id, channel, external_service_id, display_name, status.

نمونه درخواست
GET /api/v1/channel-services/me
X-API-Key: <API_KEY>

مدیا

  • POST /api/v1/media/upload — آپلود فایل (file_type اختیاری: File | Image | Video | Voice | Music)
  • GET /api/v1/media — لیست فایل‌ها
  • GET /api/v1/media/{id} — جزئیات
  • GET /api/v1/media/{id}/download — دانلود فایل

حداکثر حجم: ۱۰ مگابایت. Voice فقط فرمت wav. شناسه file_id برگشتی را در ارسال استفاده کنید.

قیمت

GET/api/v1/pricing/rates

تعرفه

تعرفه پلن فعال. فیلتر اختیاری: channel, sub_type, category, only_active.

نمونه درخواست
GET /api/v1/pricing/rates
X-API-Key: <API_KEY>
POST/api/v1/pricing/calculate-cost

برآورد هزینه

قبل از ارسال، هزینه تقریبی را محاسبه می‌کند.

نمونه درخواست
POST /api/v1/pricing/calculate-cost
X-API-Key: <API_KEY>

برای شروع، از بخش «شروع سریع» و «احراز هویت» بالای همین صفحه استفاده کنید. بازگشت به معرفی API