بازگشت به همه مقالات
راهنماها·2026-08-01·7 دقیقه مطالعه

خودکارسازی دریافت کد تأیید SMS: راهنمای کامل API

از ساخت کلید API تا ثبت سفارش و دریافت کد — مثال‌های واقعی curl، محدودیت‌های نرخ، و نکاتی که همه در آن‌ها گیر می‌کنند.

وب‌سایت برای ثبت‌نام‌های گاه‌به‌گاه کافی است: چند کلیک می‌زنید و منتظر یک پیامک می‌مانید. اما وقتی تست‌های خودکار می‌نویسید، اسکریپت ثبت‌نام انبوه دارید، یک CI pipeline دارید، یا رباتی نیاز دارد بدون دخالت انسان کد تأیید را بگیرد، دیگر کافی نیست. وب‌سایت از پس این کار برنمی‌آید. API برمی‌آید. این مقاله هر چیزی را که برای رسیدن از صفر به یک فرایند کاری واقعی لازم دارید در بر می‌گیرد.

گام 1: یک کلید API بگیرید

وارد شوید و به /account/api-keys بروید تا یکی بسازید. کلیدها به‌شکل jm_ به‌همراه یک رشته تصادفی هستند. متن ساده فقط یک‌بار نمایش داده می‌شود — ما هش آن را ذخیره می‌کنیم، نه خود کلید را، پس اگر آن را گم کنید گزینه‌ی «بازیابی کلیدم» وجود ندارد. آن را حذف کنید و یکی تازه بسازید.

هر درخواست از احراز هویت استاندارد Bearer استفاده می‌کند:

Authorization: Bearer jm_your_key

با کلید مثل یک رمز عبور رفتار کنید — آن را در یک repo عمومی commit نکنید، برای دیباگ کردن توسط شخص دیگری در یک چت پیست نکنید. اگر گمان می‌کنید لو رفته، به /account/api-keys برگردید، آن را حذف کنید و یکی تازه صادر کنید؛ کلید قدیمی همان لحظه از کار می‌افتد.

گام 2: یک سرویس و یک کشور انتخاب کنید

ثبت سفارش به دو چیز نیاز دارد: service (کد سرویس) و country (شناسه کشور). با فهرست‌کردن کاتالوگ شروع کنید:

curl https://jiema.my/api/v1/services \
  -H "Authorization: Bearer jm_your_key"

هر مورد یک فیلد code دارد (برای Telegram برابر tg است) — همان را مستقیماً به نقطه پایانی سفارش بدهید؛ این کار مطمئن‌تر از ساختن دوباره‌ی یک slug توسط خودتان است. برای دیدن قیمت و موجودی زنده‌ی یک سرویس خاص در همه‌ی کشورها، پارامتر service را اضافه کنید:

curl "https://jiema.my/api/v1/prices?service=tg" \
  -H "Authorization: Bearer jm_your_key"

هر مدخل درون items شامل countryId / priceCents / count (تعداد شماره‌های موجود در حال حاضر) است. پیش از ثبت سفارش count را بررسی کنید — صفر یعنی سفارش شکست می‌خورد، پس یک درخواست را برای فهمیدن این موضوع به روش سخت هدر ندهید.

گام 3: سفارش را ثبت کنید

curl -X POST https://jiema.my/api/v1/orders \
  -H "Authorization: Bearer jm_your_key" \
  -H "Content-Type: application/json" \
  -d '{"service":"tg","country":"6"}'

یک سفارش موفق یک شماره تلفن و زمان انقضا برمی‌گرداند:

{
  "ok": true,
  "data": {
    "id": "cm...",
    "status": "WAITING",
    "phone": "62812xxxxxxx",
    "expiresAt": "2026-08-01T12:15:00.000Z",
    "chargedCents": "40"
  }
}

هزینه در همین مرحله کسر می‌شود — chargedCents مقداری است که واقعاً کسر شده (بر حسب سنت). این شماره را برای دریافت کد تأیید به اپلیکیشن هدف بدهید، سپس به مرحله بعد بروید.

گام 4: کد را با استعلام دوره‌ای دریافت کنید

اینجا از WebSocket یا webhook push خبری نیست — محتوای پیامک را با استعلام دوره‌ای از GET /api/v1/orders/:id دریافت می‌کنید، تا وقتی که smsBody دیگر null نباشد:

while true; do
  RESP=$(curl -s https://jiema.my/api/v1/orders/$ORDER_ID \
    -H "Authorization: Bearer jm_your_key")
  BODY=$(echo "$RESP" | jq -r '.data.smsBody')
  if [ "$BODY" != "null" ]; then
    echo "Code received: $BODY"
    break
  fi
  sleep 5
done

پنج ثانیه نقطه شروع معقولی است — شماره به‌مدت 15 دقیقه معتبر است، و محدودیت 60 درخواست در دقیقه برای استعلام‌ها جای کافی باقی می‌گذارد. اگر بی‌حوصله‌اید سه ثانیه هم کار می‌کند؛ استعلام‌گرفتن هر ثانیه کد را سریع‌تر به شما نمی‌رساند، فقط سهمیه محدودیت نرخ‌تان را هدر می‌دهد.

نکات مهم

  • محدودیت‌های نرخ به‌ازای هر کاربر اعمال می‌شود، نه هر کلید. نقاط پایانی نوشتن (order / cancel / next-sms) برای هر کاربر به 10 درخواست در دقیقه محدودند؛ استعلام‌ها به 60 در دقیقه. ساختن کلیدهای بیشتر سقفتان را بالاتر نمی‌برد — همه یک محدودیت مشترک را به اشتراک می‌گذارند.
  • شماره‌ها بعد از 15 دقیقه منقضی می‌شوند. شماره‌ی استفاده‌نشده‌ای که بدون دریافت کد منقضی شود به‌طور خودکار بازپرداخت می‌شود — لازم نیست درخواستش را بدهید. اما اگر pipeline خودتان پیش از استفاده‌ی واقعی از شماره مدت زیادی آن را نگه دارد (مثلاً گیرافتاده در یک صف)، تا زمانی که به آن برسید دیگر مرده خواهد بود.
  • یک شماره می‌تواند بیش از یک کد دریافت کند. اگر اپلیکیشن هدف پیامک را در دو مرحله بفرستد (یک تأیید ثبت‌نام، سپس یک کد ورود جدا)، پس از رسیدن اولی POST /api/v1/orders/:id/next-sms را صدا بزنید تا به ما بگویید «کار با این یکی تمام شد، به گوش‌دادن ادامه بده» — لازم نیست برای شماره‌ی جدید سفارش تازه‌ای ثبت کنید.
  • پس از رسیدن کد، cancel دیگر کار نمی‌کند. POST /api/v1/orders/:id/cancel تا زمانی‌که شماره هنوز منتظر کد است فوراً بازپرداخت می‌کند. همین‌که smsBody یک‌بار غیر null شود، همان فراخوانی به‌جای آن خطای CODE_RECEIVED برمی‌گرداند — شما همان چیزی را که پولش را داده بودید گرفته‌اید، پس راه برگشتی نیست.
  • فقط یک‌بار status را چک نکنید و رهایش نکنید. status از WAITING به RECEIVED می‌رود. اگر تا زمان انقضا روی WAITING بماند، معمولاً مشکل نرخ تحویل همان ترکیب خاص کشور/سرویس است — ثبت یک سفارش تازه در کشوری دیگر معمولاً سریع‌تر از صبرکردن نتیجه می‌دهد.

مراحل بعدی

این‌ها روند اصلی از سفارش تا کد را پوشش می‌دهد. فهرست کامل فیلدها، کدهای خطا، و حالت‌های حاشیه‌ای برای هر نقطه پایانی در /api-docs موجود است. اگر این را در مقیاس بزرگ اجرا می‌کنید — مثلاً فرایند تأیید ده‌ها حساب را هم‌زمان زنده نگه می‌دارید — حلقه استعلام هر سفارش را جدا و مستقل زمان‌بندی کنید. آن‌ها را در یک حلقه‌ی سریالی صف نکنید، وگرنه شماره‌های قبلی منقضی می‌شوند درحالی‌که هنوز منتظر اولی هستید.

از هر سفارش هر کسی که دعوت می‌کنید ۱۰٪ کسب کنید

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

دریافت لینک من