ملی ای‌پی‌آی

وب‌سرویس پیامک OTP

کد تأیید ورود و ثبت‌نام را با یک فراخوان به گوشی کاربرتان بفرستید و با فراخوان دوم بسنجید. ملی ای‌پی‌آی هر پیامک را از چند ارائه‌دهندهٔ پیامک جداگانه می‌فرستد: اگر یکی کند شد، قطع شد یا درخواست را رد کرد، همان کد در چند ثانیه از مسیر بعدی می‌رود. قطعی یک سرویس پیامک دیگر یعنی صفحهٔ ورودِ بسته برای کاربران شما نیست.

ساخت کلید و شروعاین سرویس به‌زودی برای همهٔ حساب‌ها باز می‌شود.

ارسال از چند مسیر، یعنی کدی که می‌رسد

بیشتر سرویس‌های پیامک یک خط و یک مسیر دارند و روزی که آن مسیر کند یا قطع شود، کاربر شما پشت صفحهٔ ورود می‌ماند. ملی ای‌پی‌آی پشت هر درخواست چند ارائه‌دهندهٔ پیامک مستقل دارد و جابه‌جایی بینشان خودکار است:

  1. ۱ارسال از مسیر اولدرخواست شما به مسیر اصلی می‌رود. در بیشتر موارد کار همین‌جا تمام است و پاسخ موفق برمی‌گردد.
  2. ۲مسیر اول جواب نداداگر پاسخ در مهلت چند ثانیه‌ای نرسید، خطای شبکه رخ داد یا ارائه‌دهنده درخواست را رد کرد، منتظر نمی‌مانیم و بی‌درنگ سراغ مسیر بعدی می‌رویم.
  3. ۳همان کد از مسیر دومکد عوض نمی‌شود. حتی اگر پیامک اول دیر برسد و کاربر دو پیامک بگیرد، هر دو یک کد دارند و هیچ‌کدام دیگری را باطل نمی‌کند.
  4. ۴یک پاسخ، یک هزینهشما فقط یک پاسخ می‌گیرید و فقط یک بار هزینه می‌دهید. تلاش ناموفق مسیر اول هزینه‌اش با ماست.

چرا این سرویس

  • بدون وابستگی به یک سرویس پیامکقطعی، کندی یا بسته‌شدن خط یک ارائه‌دهنده، ورود کاربران شما را متوقف نمی‌کند. جابه‌جایی خودکار است و کاری از سمت شما نمی‌خواهد.
  • فقط پیامک ارسال‌شده هزینه داردورودی نامعتبر، عبور از سقف ارسال و پیامکی که هیچ مسیری نپذیرفت، رایگان‌اند. سنجش کد همیشه رایگان است.
  • کد و شماره را نگه نمی‌داریمشمارهٔ موبایل و کد فقط به شکل درهم‌سازی‌شده ذخیره می‌شوند؛ برای سنجش همین کافی است و نشت داده چیزی از کاربران شما بیرون نمی‌دهد.
  • ساخت و سنجش کد با ماکد تصادفی را ما می‌سازیم، مهلتش را نگه می‌داریم و تلاش‌های نادرست را می‌شماریم. لازم نیست جدول کد و زمان‌سنج خودتان را بسازید.

ارسال کد

یک درخواست POST /api/v1/sms/otp/ با کلید API در هدر Authorization: Bearer (یا X-API-Key).

  • mobile: شمارهٔ موبایل ایران، با ارقام فارسی یا لاتین. لازم.
  • code: اختیاری. اگر بفرستید همان کد می‌رود؛ فقط رقم، ۴ تا ۱۰ رقم.
  • length: طول کد ساخته‌شده، ۴ تا ۸ رقم، پیش‌فرض ۵. کد ساخته‌شده در پاسخ برنمی‌گردد.
  • ttlSeconds: اعتبار کد، ۶۰ تا ۹۰۰ ثانیه، پیش‌فرض ۱۲۰.
curl -X POST https://melliapi.net/api/v1/sms/otp/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mobile": "09121234567", "length": 5, "ttlSeconds": 120}'

پاسخ موفق (مبلغ واقعی در billing.amountRial):

{
  "ok": true,
  "requestId": "req_7f3c…",
  "otpId": "otp_1a9e…",
  "status": "sent",
  "expiresAt": "2026-11-03T10:02:00.000Z",
  "billing": { "amountRial": … }
}

سنجش کد

کدی که کاربر وارد کرده را با POST /api/v1/sms/otp/verify/ بسنجید. آخرین کد ارسال‌شده به همان شماره، از همان حساب، سنجیده می‌شود. هر کد ۵ بار قابل سنجش است و کد درست فقط یک بار پذیرفته می‌شود. سنجش رایگان است.

curl -X POST https://melliapi.net/api/v1/sms/otp/verify/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mobile": "09121234567", "code": "48213"}'
{ "ok": true, "requestId": "req_…", "valid": true }

{ "ok": true, "requestId": "req_…", "valid": false,
  "reason": "invalid_code", "remainingAttempts": 3 }

مقدارهای reason: invalid_code (کد نادرست)، expired (مهلت گذشته)، already_used (قبلاً پذیرفته شده)، too_many_attempts (قفل شده) و not_found (کدی برای این شماره فرستاده نشده).

خطاها

کدHTTPمعنا
invalid_input۴۰۰شماره، کد، طول یا مهلت نامعتبر است؛ فیلد خطادار در error.field آمده.
unauthorized۴۰۱کلید API ارسال نشده یا معتبر نیست.
insufficient_funds۴۰۲موجودی برای یک پیامک کافی نیست؛ هیچ پیامکی نرفت.
ip_not_allowed۴۰۳IP شما در فهرست مجاز کلید نیست.
rate_limited۴۲۹سقف ارسال به این شماره یا سقف دقیقه‌ای رد شده؛ retryAfterSeconds را ببینید.
sms_unavailable۵۰۳هیچ مسیری پیامک را نپذیرفت؛ مبلغی کسر نشد.
service_disabled۵۰۳سرویس موقتاً ارائه نمی‌شود.

آنچه این سرویس نمی‌کند

  • پیامک تبلیغاتی و انبوه نمی‌فرستد؛ فقط کد تأیید یک‌بارمصرف.
  • متن پیامک ثابت و خنثی است و فقط کد را دارد؛ نام برند شما در آن نمی‌آید.
  • فقط شمارهٔ موبایل ایران را می‌پذیرد.
  • اگر همهٔ مسیرها هم‌زمان در دسترس نباشند، پاسخ خطا با کد sms_unavailable می‌گیرید و مبلغی کسر نمی‌شود؛ چند ثانیه بعد دوباره تلاش کنید.
  • رسیدن پیامک به گوشی به روشن‌بودن گوشی و پوشش اپراتور هم بستگی دارد؛ ما پذیرش پیامک را تضمین می‌کنیم، نه خاموش‌نبودن گوشی کاربر.

پرسش‌های متداول

وقتی یک سرویس پیامک قطع است، کاربر من چه می‌بیند؟

هیچ چیز متفاوتی. درخواست شما در چند ثانیه از مسیر دیگری فرستاده می‌شود و پاسخی که می‌گیرید همان پاسخ موفق همیشگی است. فقط اگر همهٔ مسیرها با هم در دسترس نباشند خطا می‌گیرید، و آن هم بدون کسر هزینه است.

کد را خودم بسازم یا شما بسازید؟

هر دو ممکن است. اگر فیلد code را نفرستید، کدی تصادفی با طولی که خواسته‌اید (چهار تا هشت رقم) ساخته می‌شود و در پاسخ برنمی‌گردد؛ برای سنجش از نقطهٔ verify استفاده کنید. اگر کد را خودتان بفرستید، همان فرستاده می‌شود و باز هم می‌توانید با verify بسنجید.

هزینه دقیقاً کی کسر می‌شود؟

فقط وقتی یکی از مسیرهای ارسال پیامک را پذیرفت. پیش از ارسال، مبلغ یک پیامک قفل می‌شود و اگر ارسال ممکن نشد همان لحظه آزاد می‌شود. مبلغ کسرشده در پاسخ هر درخواست در billing.amountRial نوشته شده است. سنجش کد رایگان است.

اعتبار کد چقدر است و چند بار می‌شود اشتباه وارد کرد؟

پیش‌فرض دو دقیقه است و با ttlSeconds می‌توانید آن را بین یک تا پانزده دقیقه بگذارید. هر کد پنج بار قابل سنجش است و بعد قفل می‌شود، تا کد کوتاه با حدس‌زدن شکسته نشود. کد درست هم فقط یک بار پذیرفته می‌شود.

جلوی ارسال پیامک‌های پشت‌سرهم به یک شماره گرفته می‌شود؟

بله. به هر شماره در هر دقیقه یک کد و در هر ساعت حداکثر شش کد فرستاده می‌شود. درخواست اضافه با خطای rate_limited و زمان انتظار رد می‌شود و هزینه‌ای ندارد. این سقف از کیف پول شما در برابر ربات‌هایی که فرم ورود را بمباران می‌کنند هم محافظت می‌کند.

برای شروع چه لازم دارم؟

یک حساب کسب‌وکار، یک کلید API از پنل و موجودی. همان کلیدی که برای استعلام‌ها و هوش مصنوعی دارید اینجا هم کار می‌کند و هزینه از همان موجودی کسر می‌شود. قرارداد جدا یا خط اختصاصی لازم نیست. کلید را از بخش کلیدهای پنل بسازید.

ساخت کلید و شروعاین سرویس به‌زودی برای همهٔ حساب‌ها باز می‌شود.