SMSCode API कैसे इस्तेमाल करें — डेवलपर गाइड (2026)

SMSCode API कैसे इस्तेमाल करें — डेवलपर गाइड (2026)

SMSCode एक REST API प्रदान करता है जो डेवलपर को वर्चुअल नंबर प्रोग्रामेटिक रूप से अनुरोध करने, SMS कोड प्राप्त करने, और अनुमति मिलने पर नंबर रद्द करने देता है। मौजूदा स्टॉक, उपलब्ध संख्या और पूर्णांक IDR मूल्य के लिए हर बार catalog endpoint को authority मानें।

यह गाइड सब कुछ कवर करती है: प्रमाणीकरण, एंडपॉइंट, अनुरोध-प्रतिक्रिया प्रारूप, SMS के लिए मतदान, त्रुटि प्रबंधन, और Python, Node.js, और PHP में पूरे कोड उदाहरण।

TL;DR: SMSCode API एक REST API है। Bearer token से प्रमाणित करें। नंबर अनुरोध के लिए POST /v1/orders/create कॉल करें, OTP मतदान के लिए GET /v1/orders/{id}, और मौजूदा snapshot में can_cancel: true होने पर रद्द करने के लिए POST /v1/orders/cancel। कीमत और उपलब्धता catalog से, तथा भुगतान विकल्प अपने अकाउंट के Deposit पेज से जाँचें। API कुंजी पाएँ

SMSCode API कौन इस्तेमाल करता है?

तकनीकी विवरण में जाने से पहले, यहाँ बताया है API किसके लिए बना है:

ऐप डेवलपर और QA टेस्टर: फ़ोन वेरिफिकेशन शामिल करने वाले पंजीकरण और ऑनबोर्डिंग प्रवाह परीक्षण करना। स्वचालित परीक्षणों के दौरान मैन्युअल रूप से SMS वेरिफिकेशन से गुज़रने की जगह, API आपके परीक्षण सूट को प्रोग्रामेटिक रूप से संभालने देता है।

विकास हैकर और डिजिटल विपणक: शोध, विज्ञापन, या बहु-अकाउंट वर्कफ़्लो के लिए प्लेटफ़ॉर्म पर अकाउंट निर्माण स्वचालित करना। (प्लेटफ़ॉर्म की सेवा की शर्तों के अनुसार ज़िम्मेदारी से इस्तेमाल करें।)

स्क्रेपिंग और डेटा शोध: शोध प्लेटफ़ॉर्म पर एकाधिक अकाउंट बनाना जहाँ प्रत्येक अकाउंट फ़ोन वेरिफिकेशन माँगता है।

SaaS उत्पाद: ऐसे उपकरण बनाना जो अपने उत्पाद के वर्कफ़्लो के हिस्से के रूप में SMS वेरिफिकेशन एकीकृत करते हैं।

बॉट डेवलपर: प्लेटफ़ॉर्म ऑनबोर्डिंग प्रवाह पूरा करने वाले बॉट बनाना जिनमें फ़ोन वेरिफिकेशन शामिल है।

मुद्रा अनुबंध: v1 catalog की price और balance की balance फ़ील्ड पूर्णांक IDR में हैं। UI में दिखाई गई स्थानीय तुलना या भुगतान विकल्प को API response की मुद्रा न समझें।

API कुंजी कैसे पाएँ

चरण 1: smscode.gg/auth/signup पर ईमेल से पंजीकरण करें।

चरण 2: डैशबोर्ड में लॉगिन करें और अकाउंट सेटिंग पर जाएँ।

चरण 3: API कुंजी अनुभाग खोजें और अपनी कुंजी बनाएँ या कॉपी करें।

चरण 4: अकाउंट के Deposit पेज पर उपलब्ध किसी वर्तमान माध्यम से बैलेंस जोड़ें — उपलब्ध माध्यम समय और अकाउंट के अनुसार बदल सकते हैं।

आपकी API कुंजी एक लंबी अक्षरांकीय स्ट्रिंग है। इसे पासवर्ड की तरह व्यवहार करें — सार्वजनिक भंडारों में प्रतिबद्ध न करें, साझा न करें, और अगर समझौते का संदेह हो तो पुनर्जनन करें।

API बेस URL और प्रमाणीकरण

सभी SMSCode API अनुरोध यहाँ जाते हैं:

https://api.smscode.gg/v1/

प्रमाणीकरण HTTP हेडर में bearer token इस्तेमाल करता है:

Authorization: Bearer YOUR_API_KEY

हर अनुरोध में यह हेडर शामिल होना चाहिए। वैध API कुंजी के बिना अनुरोध 401 Unauthorized वापस करते हैं।

मुख्य API वर्कफ़्लो

वर्चुअल नंबर पाने और OTP प्राप्त करने के मानक वर्कफ़्लो में तीन चरण हैं:

चरण 1: उत्पाद चुनें और नंबर अनुरोध करें — catalog से catalog_product_id लें, फिर एक स्थिर request body से नंबर खरीदें

चरण 2: SMS का मतदान करें — OTP आने तक ऑर्डर स्थिति जाँचते रहें

चरण 3: OTP इस्तेमाल करेंotp_message पढ़ें, फिर lifecycle को COMPLETED, CANCELED या EXPIRED तक ट्रैक करें

चरण 1: उपलब्ध सेवाएँ और देश देखें

नंबर अनुरोध करने से पहले, आप जाँच सकते हैं कि कौन सी सेवाएँ और देश उपलब्ध हैं और उनकी क़ीमतें क्या हैं।

एंडपॉइंट: GET /v1/catalog/products

उदाहरण अनुरोध:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.smscode.gg/v1/catalog/products?country_id=7&platform_id=1"

उदाहरण प्रतिक्रिया:

{
  "success": true,
  "data": [
    {
      "id": 1024,
      "name": "WhatsApp - Indonesia",
      "catalog_product_id": 88,
      "country_id": 7,
      "platform_id": 1,
      "available": 142,
      "price": 8500,
      "active": true
    }
  ],
  "meta": { "page": 1, "limit": 1000, "count": 1 }
}

available जाँचें और खरीद के लिए catalog_product_id सुरक्षित रखें।

चरण 2: वर्चुअल नंबर अनुरोध करें

एंडपॉइंट: POST /v1/orders/create

अनुरोध निकाय:

{
  "catalog_product_id": 88,
  "quantity": 1
}

curl से उदाहरण:

curl --connect-timeout 5 --max-time 30 -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-example-001" \
  -d '{"catalog_product_id": 88, "quantity": 1}' \
  "https://api.smscode.gg/v1/orders/create"

सफलता प्रतिक्रिया:

{
  "success": true,
  "data": {
    "orders": [{
      "id": 90210,
      "status": "ACTIVE",
      "phone_number": "+14155551234",
      "otp_code": null,
      "otp_received_at": null,
      "expires_at": "2026-03-17T10:25:00Z",
      "failed_reason": null,
      "product_id": 1024,
      "catalog_product_id": 88,
      "operator_id": null,
      "operator_name": null,
      "amount": 750000,
      "can_finish": false,
      "can_resend": false,
      "can_cancel": false,
      "can_replace": false,
      "can_reactivate": false,
      "resend_available_at": null,
      "cancel_available_at": "2026-03-17T10:02:00Z",
      "replace_available_at": "2026-03-17T10:02:00Z"
    }],
    "failed_count": 0
  }
}

id संग्रहित करें — OTP का मतदान करने और ज़रूरत हो तो रद्द करने के लिए इस्तेमाल करते हैं।

Nonblank string phone_number मिले तभी उसे इस्तेमाल करें; resolved create में यह field absent, null या blank भी हो सकती है। नीचे के छोटे उदाहरण तत्काल assignment मानते हैं, जबकि production client को उसी order ID पर एक bounded GET के बाद भी assignment न मिले तो create को दोहराए बिना अलग pending_assignment outcome लौटाना चाहिए। अस्पष्ट network या 5xx परिणाम पर केवल यही Idempotency-Key और बिल्कुल यही JSON body सीमित बार दोहराएँ; नया key या बदला body इस्तेमाल न करें।

चरण 3: SMS (OTP) का मतदान करें

ऐप में नंबर दर्ज करने और OTP अनुरोध करने के बाद, आने वाले SMS की जाँच करने के लिए ऑर्डर एंडपॉइंट का मतदान करें।

एंडपॉइंट: GET /v1/orders/{id}

उदाहरण:

curl --connect-timeout 5 --max-time 30 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.smscode.gg/v1/orders/90210"

V1OrderSummary projection, अभी SMS नहीं (चुने हुए fields, पूरी wire response नहीं):

{
  "success": true,
  "data": {
    "id": 90210,
    "phone_number": "+14155551234",
    "status": "ACTIVE",
    "otp_code": null,
    "otp_message": null,
    "sms_revision": 0,
    "can_cancel": true
  }
}

V1OrderSummary projection, SMS प्राप्त (चुने हुए fields, पूरी wire response नहीं):

{
  "success": true,
  "data": {
    "id": 90210,
    "phone_number": "+14155551234",
    "status": "OTP_RECEIVED",
    "otp_code": null,
    "otp_message": "Your Discord verification code is: 847291",
    "sms_revision": 1,
    "can_cancel": false
  }
}

हर order का आख़िरी स्वीकार किया गया revision -1 से शुरू करें। केवल non-boolean integer sms_revision, जो उस baseline से strictly greater हो, और nonblank string otp_message साथ मिलें तो baseline बढ़ाकर message surface करें। यह काम OTP_RECEIVED या otp_code पर निर्भर नहीं है और COMPLETED, CANCELED या EXPIRED जाँचने से पहले होता है; invalid, पुराना या blank evidence baseline नहीं बदलता।

सीमित polling करें: अपने workload के लिए bounded interval और absolute local deadline चुनें, लेकिन server के expires_at और नवीनतम order snapshot को authoritative मानें। नीचे positive Retry-After को अधिकतम 60 सेकंड तक मानने की सीमा client की local policy है, API SLA नहीं; header न मिले या malformed हो तो अधिकतम 30 सेकंड का bounded fallback अपनाएँ। हर sleep को deadline में बची अवधि तक clamp करें और हर GET के connect तथा total transport timeout को भी उसी बची अवधि के भीतर रखें, ताकि in-flight transport भी absolute deadline से bounded रहे।

चरण 4: नंबर रद्द करें

अगर आपको नंबर की ज़रूरत नहीं रही, पहले मौजूदा order snapshot पढ़ें। केवल can_cancel: true होने पर cancel request भेजें।

एंडपॉइंट: POST /v1/orders/cancel

curl --connect-timeout 5 --max-time 30 -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id": 90210}' \
  "https://api.smscode.gg/v1/orders/cancel"

प्रतिक्रिया:

{
  "success": true,
  "data": {
    "order_id": 90210,
    "status": "CANCELED",
    "refund_amount": 750000,
    "new_balance": 2000000
  }
}

Cancel response मिलने के बाद server की lifecycle और balance policy को authoritative मानें।

बैलेंस जाँचें

एंडपॉइंट: GET /v1/balance

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.smscode.gg/v1/balance"

प्रतिक्रिया:

{
  "success": true,
  "data": {
    "currency": "IDR",
    "balance": 246500
  }
}

balance IDR में पूर्णांक राशि है; इसे दशमलव या किसी दूसरी मुद्रा में न बदलें।

पूरे कोड उदाहरण

Python उदाहरण

import json
import requests
import time
import uuid

API_KEY = "your_api_key_here"
BASE_URL = "https://api.smscode.gg/v1"
ORDER_TIMEOUT = (5, 30)
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def get_virtual_number(catalog_product_id: int) -> dict:
    """एक logical purchase के लिए stable key और body से नंबर अनुरोध करें।"""
    body = {"catalog_product_id": catalog_product_id, "quantity": 1}
    idempotency_key = str(uuid.uuid4())
    response = requests.post(
        f"{BASE_URL}/orders/create",
        headers={**HEADERS, "Idempotency-Key": idempotency_key},
        json=body,
        timeout=ORDER_TIMEOUT,
    )
    response.raise_for_status()
    return response.json()["data"]["orders"][0]

def wait_for_otp(order_id: int, timeout_seconds: int = 300, poll_interval: int = 5) -> str | None:
    """OTP प्राप्त होने या टाइमआउट तक मतदान करें।"""
    start_time = time.time()
    last_seen_revision = -1

    while time.time() - start_time < timeout_seconds:
        response = requests.get(
            f"{BASE_URL}/orders/{order_id}",
            headers=HEADERS,
            timeout=ORDER_TIMEOUT,
        )
        response.raise_for_status()
        data = response.json()["data"]

        revision = data.get("sms_revision")
        message = data.get("otp_message")
        # OTP_RECEIVED informational है; SMS delivery revision evidence से तय होती है।
        if (
            type(revision) is int
            and revision > last_seen_revision
            and isinstance(message, str)
            and message.strip()
        ):
            last_seen_revision = revision
            return message
        if data["status"] in ("COMPLETED", "CANCELED", "EXPIRED"):
            return None

        time.sleep(poll_interval)

    return None

def cancel_order(order_id: int) -> None:
    """मौजूदा snapshot अनुमति दे तभी नंबर ऑर्डर रद्द करें।"""
    current = requests.get(
        f"{BASE_URL}/orders/{order_id}",
        headers=HEADERS,
        timeout=ORDER_TIMEOUT,
    ).json()["data"]
    if current["can_cancel"]:
        requests.post(
            f"{BASE_URL}/orders/cancel",
            headers=HEADERS,
            json={"id": order_id},
            timeout=ORDER_TIMEOUT,
        )

def get_otp_for_service(catalog_product_id: int) -> str | None:
    """पूरा वर्कफ़्लो: नंबर अनुरोध करें, OTP प्रतीक्षा करें, OTP वापस करें।"""
    order = get_virtual_number(catalog_product_id)
    order_id = order["id"]

    # `phone_number` assignment तक optional/nullable है। Resolved create resolved
    # ही रहता है: उसी id पर एक bounded read, दूसरा paid create कभी नहीं।
    number = order.get("phone_number")
    if not (isinstance(number, str) and number.strip()):
        # pending_assignment: order resolved और charged है; इसे अभी कहीं दर्ज न करें
        # और दूसरा create न बनाएँ। id से polling assignment देख लेगा।
        print(f"pending_assignment: order {order_id} को अभी नंबर नहीं मिला")
        return None

    print(f"नंबर मिला: {number}")
    print("यह नंबर लक्षित सेवा में दर्ज करें OTP प्राप्त करने के लिए...")

    # स्वचालन में, यहाँ SMS ट्रिगर करें
    # उदाहरण: selenium_driver.find_element(...).send_keys(number)

    otp = wait_for_otp(order_id)

    if otp:
        print(f"OTP प्राप्त: {otp}")
        return otp
    else:
        print("कोई OTP नहीं आया — cancel eligibility जाँची जा रही है")
        cancel_order(order_id)
        return None

# उपयोग
otp = get_otp_for_service(catalog_product_id=88)
if otp:
    print(f"यह OTP इस्तेमाल करें: {otp}")

Node.js उदाहरण

const { Agent, fetch } = require('undici');

const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.smscode.gg/v1';
const orderDispatcher = new Agent({ connectTimeout: 5_000 });
const orderTransport = () => ({
  dispatcher: orderDispatcher,
  signal: AbortSignal.timeout(30_000)
});
const headers = { Authorization: `Bearer ${API_KEY}` };

async function getVirtualNumber(catalogProductId) {
  const body = { catalog_product_id: catalogProductId, quantity: 1 };
  const idempotencyKey = crypto.randomUUID();
  const response = await fetch(`${BASE_URL}/orders/create`, {
    method: 'POST',
    headers: {
      ...headers,
      'Content-Type': 'application/json',
      'Idempotency-Key': idempotencyKey
    },
    body: JSON.stringify(body),
    ...orderTransport()
  });
  const payload = await response.json();
  if (!response.ok || !payload.success) throw new Error(payload.error?.message);
  return payload.data.orders[0];
}

async function waitForOTP(orderId, timeoutMs = 300000, pollIntervalMs = 5000) {
  const deadline = Date.now() + timeoutMs;
  let lastSeenRevision = -1;

  while (Date.now() < deadline) {
    const response = await fetch(`${BASE_URL}/orders/${orderId}`, {
      headers,
      ...orderTransport()
    });
    const data = (await response.json()).data;

    const revision = data.sms_revision;
    const message = data.otp_message;
    // OTP_RECEIVED informational है; SMS delivery revision evidence से तय होती है।
    if (
      Number.isInteger(revision) &&
      revision > lastSeenRevision &&
      typeof message === 'string' &&
      message.trim()
    ) {
      lastSeenRevision = revision;
      return message;
    }
    if (['COMPLETED', 'CANCELED', 'EXPIRED'].includes(data.status)) {
      return null;
    }

    await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
  }

  return null;
}

async function cancelOrder(orderId) {
  const currentResponse = await fetch(`${BASE_URL}/orders/${orderId}`, {
    headers,
    ...orderTransport()
  });
  const current = (await currentResponse.json()).data;
  if (current.can_cancel) {
    await fetch(`${BASE_URL}/orders/cancel`, {
      method: 'POST',
      headers: { ...headers, 'Content-Type': 'application/json' },
      body: JSON.stringify({ id: orderId }),
      ...orderTransport()
    });
  }
}

async function getOTPForService(catalogProductId) {
  const order = await getVirtualNumber(catalogProductId);
  const orderId = order.id;

  // `phone_number` assignment तक optional/nullable है। उसी id पर एक bounded read,
  // दूसरा paid create कभी नहीं।
  const isAssigned = (v) => typeof v === 'string' && v.trim() !== '';
  const number = order.phone_number;
  if (!isAssigned(number)) {
    // pending_assignment: order resolved और charged है; अभी कहीं दर्ज न करें।
    return { kind: 'pending_assignment', orderId };
  }

  console.log(`नंबर मिला: ${number}`);
  console.log('OTP प्राप्त करने के लिए लक्षित सेवा में दर्ज करें...');

  // यहाँ स्वचालन में SMS ट्रिगर करें

  const otp = await waitForOTP(orderId);

  if (otp) {
    console.log(`OTP प्राप्त: ${otp}`);
    return otp;
  } else {
    console.log('कोई OTP नहीं आया — cancel eligibility जाँची जा रही है');
    await cancelOrder(orderId);
    return null;
  }
}

// उपयोग
getOTPForService(88)
  .then(result => {
    // `getOTPForService` एक discriminated union लौटाता है। pending_assignment एक
    // truthy object है, इसलिए बिना जाँच के यह `[object Object]` छापेगा और
    // भुगतान किया गया orderId खो देगा।
    if (result && result.kind === 'pending_assignment') {
      console.log(`pending_assignment: order ${result.orderId} को अभी नंबर नहीं मिला`);
      return;
    }
    if (result) console.log(`यह OTP इस्तेमाल करें: ${result}`);
  })
  .catch(console.error);

PHP उदाहरण

<?php

define('API_KEY', 'your_api_key_here');
define('BASE_URL', 'https://api.smscode.gg/v1');

function smscode_request($method, $endpoint, $body = null, $extra_headers = []) {
    $url = BASE_URL . $endpoint;
    $headers = [
        'Authorization: Bearer ' . API_KEY,
        'Content-Type: application/json',
    ];
    $headers = array_merge($headers, $extra_headers);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($method === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    }

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

function get_virtual_number($catalog_product_id) {
    $body = ['catalog_product_id' => $catalog_product_id, 'quantity' => 1];
    $idempotency_key = bin2hex(random_bytes(16));
    $result = smscode_request(
        'POST',
        '/orders/create',
        $body,
        ['Idempotency-Key: ' . $idempotency_key]
    );
    return $result['data']['orders'][0];
}

function wait_for_otp($order_id, $timeout = 300, $poll_interval = 5) {
    $deadline = time() + $timeout;
    $lastSeenRevision = -1;

    while (time() < $deadline) {
        $result = smscode_request('GET', "/orders/$order_id");
        $data = $result['data'];

        $smsRevision = $data['sms_revision'] ?? null;
        $otpMessage = $data['otp_message'] ?? null;
        // OTP_RECEIVED informational है; SMS delivery revision evidence से तय होती है।
        if (is_int($smsRevision) &&
            $smsRevision > $lastSeenRevision &&
            is_string($otpMessage) &&
            trim($otpMessage) !== '') {
            $lastSeenRevision = $smsRevision;
            return $otpMessage;
        }
        if (in_array($data['status'], ['COMPLETED', 'CANCELED', 'EXPIRED'])) {
            return null;
        }

        sleep($poll_interval);
    }

    return null;
}

function cancel_order($order_id) {
    $current = smscode_request('GET', "/orders/$order_id");
    if ($current['data']['can_cancel']) {
        smscode_request('POST', '/orders/cancel', ['id' => $order_id]);
    }
}

// उपयोग
$order = get_virtual_number(88);
$order_id = $order['id'];

// `phone_number` assignment तक optional/nullable है। उसी id पर एक bounded read,
// दूसरा paid create कभी नहीं।
$number = $order['phone_number'] ?? null;
if (!(is_string($number) && trim($number) !== '')) {
    $current = smscode_request('GET', "/orders/$order_id");
    $number = is_array($current) ? ($current['data']['phone_number'] ?? null) : null;
}
if (!(is_string($number) && trim($number) !== '')) {
    // pending_assignment: order resolved और charged है; अभी कहीं दर्ज न करें।
    echo "pending_assignment: order $order_id को अभी नंबर नहीं मिला\n";
    exit(0);
}

echo "नंबर मिला: $number\n";
echo "Discord में दर्ज करें और OTP अनुरोध करें...\n";

// यहाँ स्वचालन में SMS ट्रिगर करें

$otp = wait_for_otp($order_id);

if ($otp) {
    echo "OTP प्राप्त: $otp\n";
} else {
    echo "कोई OTP नहीं — cancel eligibility जाँची जा रही है\n";
    cancel_order($order_id);
}

त्रुटि प्रबंधन

स्थिर error.code और उसके OpenAPI में घोषित HTTP स्टेटस पर branch करें:

error.code HTTP कैसे संभालें
UNAUTHORIZED 401 Bearer token जाँचें
NOT_FOUND 404 resource ID और authenticated account जाँचें
INSUFFICIENT_BALANCE 409 एक POST के बाद रुकें और बैलेंस जोड़ें
VALIDATION_ERROR 422 request body और catalog ID सुधारें
RATE_LIMIT_EXCEEDED 429 सकारात्मक Retry-After या सीमित fallback delay इस्तेमाल करें
INTERNAL_ERROR 500 paid create को ambiguous मानें और reconciliation करें

त्रुटि प्रतिक्रिया प्रारूप:

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Your balance is too low. Please add funds to your account."
  }
}

data एक्सेस करने से पहले हमेशा प्रतिक्रिया में success जाँचें।

दर सीमा और सर्वोत्तम अभ्यास

दर सीमाएँ: संख्यात्मक quota hardcode न करें। इस उदाहरण में 429 Too Many Requests का positive Retry-After client-local 60 सेकंड पर cap है—यह API SLA नहीं है। Header गायब या अमान्य हो तो अधिकतम 30 सेकंड का fallback लें। हर sleep को absolute polling deadline में बची अवधि तक clamp करें और हर GET का connect तथा total transport timeout भी उसी बची अवधि में समाए:

from urllib3.util import Timeout

def poll_with_backoff(
    order_id, max_attempts=60, local_interval=3, timeout_seconds=300
):
    """सभी retries को application-local absolute deadline के भीतर रखें।"""
    deadline = time.time() + max(0, timeout_seconds)
    last_seen_revision = -1

    for attempt in range(max_attempts):
        remaining_seconds = deadline - time.time()
        if remaining_seconds <= 0:
            return None
        request_total_seconds = min(30, remaining_seconds)
        request_connect_seconds = min(5, request_total_seconds)
        request_timeout = Timeout(
            connect=request_connect_seconds,
            total=request_total_seconds,
        )

        response = requests.get(
            f"{BASE_URL}/orders/{order_id}",
            headers=HEADERS,
            timeout=request_timeout,
        )
        if response.status_code == 429:
            raw_retry_after = response.headers.get("Retry-After", "")
            try:
                parsed_retry_after = int(raw_retry_after)
            except (TypeError, ValueError):
                parsed_retry_after = 0
            delay = (
                min(parsed_retry_after, 60)
                if parsed_retry_after > 0
                else min(2 ** attempt, 30)
            )
            remaining_seconds = max(0, deadline - time.time())
            if remaining_seconds <= 0:
                return None
            time.sleep(min(delay, remaining_seconds))
            continue

        response.raise_for_status()
        result = response.json()["data"]
        revision = result.get("sms_revision")
        message = result.get("otp_message")
        # OTP_RECEIVED informational है; SMS delivery revision evidence से तय होती है।
        if (
            type(revision) is int
            and revision > last_seen_revision
            and isinstance(message, str)
            and message.strip()
        ):
            last_seen_revision = revision
            return result
        if result["status"] in ("COMPLETED", "CANCELED", "EXPIRED"):
            return None
        remaining_seconds = max(0, deadline - time.time())
        if remaining_seconds <= 0:
            return None
        time.sleep(min(max(local_interval, 0), remaining_seconds))
    return None

कैटलॉग एंडपॉइंट को बार-बार न दबाएँ: ज़रूरत के अनुसार कम समय के लिए cache कर सकते हैं, लेकिन खरीद से पहले price, available और active को mutable live values मानें।

जो ऑर्डर नहीं चाहिए उन्हें रद्द करें: नवीनतम snapshot पढ़ें और केवल can_cancel: true होने पर cancel request भेजें; client-side timeout से refund न मानें।

Catalog से वर्तमान चयन करें: खरीद से पहले integer IDR price, integer available और active पढ़ें; पुराने hardcoded product assumptions पर निर्भर न रहें।

समानांतर अनुरोध सावधानी से संभालें: समानांतर स्वचालन चलाते समय, सुनिश्चित करें कि हर कार्यकर्ता का अपना ऑर्डर आईडी ट्रैक हो।

Selenium / Playwright स्वचालन के साथ एकीकरण

एक सामान्य पैटर्न है SMSCode API को ब्राउज़र स्वचालन के साथ जोड़ना:

from selenium import webdriver
from selenium.webdriver.common.by import By
import requests
import time

def automate_discord_signup():
    API_KEY = "your_api_key"
    headers = {"Authorization": f"Bearer {API_KEY}"}

    # चरण 1: US नंबर लें
    body = {"catalog_product_id": 88, "quantity": 1}
    idempotency_key = "order-example-001"
    order = requests.post(
        "https://api.smscode.gg/v1/orders/create",
        headers={**headers, "Idempotency-Key": idempotency_key},
        json=body,
        timeout=(5, 30),
    ).json()["data"]["orders"][0]

    order_id = order["id"]

    # `phone_number` assignment तक optional/nullable है। उसी id पर एक bounded read;
    # नंबर मिले बिना ब्राउज़र फ़ॉर्म में कुछ दर्ज न करें, दूसरा paid create कभी नहीं।
    number = order.get("phone_number")
    if not (isinstance(number, str) and number.strip()):
        current = requests.get(
            f"https://api.smscode.gg/v1/orders/{order_id}",
            headers=headers,
            timeout=(5, 30),
        ).json()
        if current.get("success"):
            number = current["data"].get("phone_number")
    if not (isinstance(number, str) and number.strip()):
        # pending_assignment: order resolved और charged है; registration शुरू न करें।
        print(f"pending_assignment: order {order_id} को अभी नंबर नहीं मिला")
        return None

    # चरण 2: ब्राउज़र में नंबर इस्तेमाल करें
    driver = webdriver.Chrome()
    driver.get("https://discord.com/register")

    # रजिस्ट्रेशन फ़ॉर्म भरें
    driver.find_element(By.NAME, "phone").send_keys(number)
    driver.find_element(By.XPATH, "//button[@type='submit']").click()

    time.sleep(2)  # SMS अनुरोध जाने का इंतज़ार

    # चरण 3: OTP का मतदान करें
    deadline = time.time() + 120
    otp = None
    last_seen_revision = -1

    while time.time() < deadline:
        resp = requests.get(
            f"https://api.smscode.gg/v1/orders/{order_id}",
            headers=headers,
            timeout=(5, 30),
        ).json()["data"]

        revision = resp.get("sms_revision")
        message = resp.get("otp_message")
        # OTP_RECEIVED informational है; SMS delivery revision evidence से तय होती है।
        if (
            type(revision) is int
            and revision > last_seen_revision
            and isinstance(message, str)
            and message.strip()
        ):
            last_seen_revision = revision
            otp = message
            break

        if resp["status"] in ("COMPLETED", "CANCELED", "EXPIRED"):
            break

        time.sleep(5)

    if otp:
        # चरण 4: ब्राउज़र में OTP दर्ज करें
        driver.find_element(By.NAME, "code").send_keys(otp)
        driver.find_element(By.XPATH, "//button[@type='submit']").click()
        print(f"वेरिफिकेशन पूरी: {otp}")
    else:
        print("OTP नहीं आया")
        current = requests.get(
            f"https://api.smscode.gg/v1/orders/{order_id}",
            headers=headers,
            timeout=(5, 30),
        ).json()["data"]
        if current["can_cancel"]:
            requests.post(
                "https://api.smscode.gg/v1/orders/cancel",
                headers=headers,
                json={"id": order_id},
                timeout=(5, 30),
            )

    driver.quit()

API बनाम मैन्युअल उपयोग — कब क्या इस्तेमाल करें

परिदृश्य API इस्तेमाल करें डैशबोर्ड इस्तेमाल करें
एक नंबर परीक्षण करना नहीं हाँ
10+ अकाउंट स्वचालित करना हाँ नहीं
विकास/QA पाइपलाइन हाँ नहीं
सेवा सीखना नहीं हाँ
थोक वेरिफिकेशन परीक्षण हाँ नहीं
कभी-कभी व्यक्तिगत उपयोग नहीं हाँ

ज़्यादातर व्यक्तिगत भारतीय उपयोगकर्ताओं के लिए, वेब डैशबोर्ड सरल है। API डेवलपर और स्वचालन उपयोग के मामलों के लिए है।

वर्तमान API authority कहाँ देखें

जाँच SMSCode v1 authority
मौजूदा उत्पाद GET /v1/catalog/products
मूल्य और बैलेंस पूर्णांक IDR
उपलब्ध भुगतान माध्यम अकाउंट का Deposit पेज
ऑर्डर रद्द करने की अनुमति नवीनतम can_cancel

किसी स्थिर लेख या प्रतिस्पर्धी मूल्य तालिका के बजाय live catalog और अपने Deposit पेज को वर्तमान स्रोत मानें।

और भी उपयोगी लेख

SMSCode और वर्चुअल नंबर के बारे में अधिक जानने के लिए:

पंजीकरण करें और SMSCode API कुंजी पाएँ

FAQ

SMSCode API कुंजी कहाँ मिलती है?

SMSCode अकाउंट में लॉगिन करें, अकाउंट सेटिंग पर जाएँ, और API कुंजी अनुभाग खोजें। कुंजी कॉपी करें और रहस्य की तरह व्यवहार करें।

API के लिए देश और सेवा कोड क्या हैं?

Catalog endpoint में country_id और platform_id देकर उपलब्ध products पाएँ। खरीद के लिए response का catalog_product_id इस्तेमाल करें।

अगर कोई OTP नहीं आए तो?

अगर rental window में कोई OTP नहीं आता, ऑर्डर EXPIRED हो सकता है। इसे terminal मानें। किसी नई खरीद से पहले पुरानी attempt की स्थिति और idempotency evidence का reconciliation पूरा करें।

क्या एक साथ कई नंबर अनुरोध हो सकते हैं?

हाँ। /v1/orders/create पर हर logical purchase के लिए अलग स्थिर Idempotency-Key और body रखें। हर response के data.orders[0].id को अलग ट्रैक करें।

API अनुरोधों की गति कैसे नियंत्रित करें?

Application concurrency सीमित रखें। 429 Too Many Requests आने पर इस guide का client positive Retry-After को local policy के रूप में अधिकतम 60 सेकंड तक मानता है—यह API SLA नहीं है। Header गायब या अमान्य हो तो अधिकतम 30 सेकंड का fallback लें। Sleep को बची absolute deadline तक clamp करें और हर GET के connect तथा total transport timeout को भी उसी बची अवधि से bound करें।

क्या API सभी देशों और सेवाओं के साथ काम करता है?

API उन्हीं देशों और सेवाओं के साथ काम करता है जो catalog में सक्रिय उत्पाद के रूप में लौटते हैं। अनुरोध करने से पहले उपलब्धता और पूर्णांक IDR मूल्य जाँचने के लिए catalog endpoint इस्तेमाल करें।

क्या बैलेंस ख़र्च किए बिना API परीक्षण हो सकता है?

API नंबर अनुरोधों के लिए असली बैलेंस माँगता है। Cancel को मुफ्त परीक्षण मानकर automation न बनाएँ: मौजूदा snapshot में can_cancel जाँचें और server की order तथा balance policy को authoritative मानें।

SMSCode आज़माने के लिए तैयार?

अकाउंट बनाएं और दो मिनट से भी कम में अपना पहला वर्चुअल नंबर पाएं।

शुरू करें →