वर्चुअल नंबर, ऑर्डर्स, और अकाउंट बैलेंस तक प्रोग्रामैटिक एक्सेस।
अनुशंसित
⟩आधिकारिक SDKs से शुरू करें
नई integrations के लिए TypeScript/JavaScript या Python SDK का उपयोग करें। दोनों SDK डिफ़ॉल्ट रूप से सार्वजनिक /v2 API का उपयोग करते हैं, सुरक्षित retries में idempotency keys सुरक्षित रखते हैं, typed errors देते हैं, और OTP lifecycle को consistent रखते हैं।
किसी सटीक स्थिर टियर-स्लॉट के लिए product_id से ऑर्डर बनाएं, या catalog_product_id, वैकल्पिक operator_id, min_price/max_price और retry-safe routed paid calls के लिए idempotency key के साथ ऑर्डर बनाएं।
catalog_product_idmax_priceIdempotency-Key
02
OTP का उपयोग करें
OTP का इंतज़ार करें, उसे लक्ष्य ऐप में दर्ज करें, फिर ऑर्डर बंद करने के लिए finish कॉल करें।
waitForOtpwait_for_otpfinish
03
Resend केवल जरूरत पर
Resend के बाद TypeScript में afterCode या Python में after_code के साथ नए code का इंतज़ार करें।
can_resendresend_available_at
import { SmscodeClient, OtpTimeoutError } from "@smscode/sdk";const client = new SmscodeClient({ token: process.env.SMSCODE_TOKEN! });let orderId: number | undefined;try { const created = await client.orders.create({ catalog_product_id: Number(process.env.SMSCODE_CATALOG_PRODUCT_ID), max_price: "0.50", quantity: 1, }); const order = created.orders[0]!; orderId = order.id; const first = await client.orders.waitForOtp(orderId, { timeoutMs: 120_000 }); console.log(first.otpCode); // इस कोड को लक्ष्य ऐप में दर्ज करें। await client.orders.finish(orderId);} catch (err) { if (err instanceof OtpTimeoutError && orderId !== undefined) { const current = await client.orders.get(orderId); if (current.can_cancel) await client.orders.cancel(orderId); } throw err;}
import osfrom smscode import OtpTimeoutError, SmscodeClientwith SmscodeClient(token=os.environ["SMSCODE_TOKEN"]) as client: created = client.orders.create( catalog_product_id=int(os.environ["SMSCODE_CATALOG_PRODUCT_ID"]), max_price="0.50", quantity=1, ) order = created.orders[0] order_id = int(order["id"]) try: first = client.orders.wait_for_otp(order_id, timeout_ms=120_000) print(first.otp_code) # इस कोड को लक्ष्य ऐप में दर्ज करें। client.orders.finish(order_id) except OtpTimeoutError: current = client.orders.get(order_id) if current["can_cancel"]: client.orders.cancel(order_id) raise
Resend timing के लिए can_resend और resend_available_at का उपयोग करें। Lower-level resend timestamps internal हैं और public response fields नहीं हैं।
⟩अवलोकन
/v1 API के सभी मनी फ़ील्ड IDR में हैं (इंडोनेशियन रुपिया), पूर्णांक इकाइयों के रूप में — उदाहरण के लिए "price": 15000 और "balance": 500000 का मतलब Rp 15,000 और Rp 500,000 है। उसी लेजर के USD-नेटिव प्रोजेक्शन के लिए, ऊपर दिए गए वर्शन टॉगल से v2 API पर स्विच करें।
⟩ऑथेंटिकेशन
सभी API रिक्वेस्ट के लिए Bearer token ज़रूरी है। डैशबोर्ड में Account Settings से एक जनरेट करें, फिर हर रिक्वेस्ट में शामिल करें:
Authorization:Bearer YOUR_API_TOKEN
बिना वैध token वाली रिक्वेस्ट को 401 UNAUTHORIZED रिस्पॉन्स मिलता है।
⟩बेस URL
नीचे दिए गए सभी endpoint पाथ इसके रिलेटिव हैं:
https://api.smscode.gg/v1
⟩रिस्पॉन्स फ़ॉर्मेट
हर रिस्पॉन्स एक कंसिस्टेंट एन्वेलप के साथ JSON लौटाता है। सभी रिस्पॉन्स में डीबगिंग के लिए x-request-id हेडर शामिल होता है।
/v1 API के सभी मनी फ़ील्ड IDR में हैं (इंडोनेशियन रुपिया), पूर्णांक इकाइयों के रूप में — उदाहरण के लिए "price": 15000 और "balance": 500000 का मतलब Rp 15,000 और Rp 500,000 है। उसी लेजर के USD-नेटिव प्रोजेक्शन के लिए, ऊपर दिए गए वर्शन टॉगल से v2 API पर स्विच करें।
किसी देश + सेवा के लिए चुने जा सकने वाले ऑपरेटर लौटाता है। अगर वास्तविक ऑपरेटर और Any stock दोनों उपलब्ध हों, तो response में operator_id null वाली Any row शामिल होती है; अगर operator-specific उत्पाद नहीं हैं, तो सूची खाली होती है।
एक नया वर्चुअल नंबर ऑर्डर बनाता है। बैलेंस ऑटोमैटिकली कटता है। नेटवर्क रिट्राई पर डुप्लिकेट ऑर्डर रोकने के लिए वैकल्पिक Idempotency-Key हेडर सपोर्ट करता है।
रिक्वेस्ट बॉडी
नाम
टाइप
ज़रूरी
विवरण
product_id
integer
नहीं
सीधे ऑर्डर करने के लिए सटीक स्थिर टियर-स्लॉट product ID। या तो यह दें या catalog_product_id, दोनों नहीं।
catalog_product_id
integer
नहीं
रूटेड देश+प्लेटफ़ॉर्म umbrella ID। सर्वर वर्तमान matching tier चुनता है। यह दें या product_id।
operator_id
integer
नहीं
/catalog/operators से वैकल्पिक ऑपरेटर ID। केवल catalog_product_id के साथ मान्य; Any के लिए छोड़ दें।
min_price
integer
नहीं
वैकल्पिक price floor। IDR integer। केवल catalog_product_id के साथ मान्य।
max_price
integer
नहीं
वैकल्पिक price cap। IDR integer। केवल catalog_product_id के साथ मान्य।
prefer_provider
string
नहीं
वैकल्पिक प्रोवाइडर कोड, जब ऑफ़र बराबर हों तो इसे प्राथमिकता दी जाती है।
policy
string
नहीं
वैकल्पिक रूटिंग नीति, केवल catalog_product_id के साथ मान्य। मान: cheapest (डिफ़ॉल्ट) सबसे कम कीमत वाला स्वस्थ ऑफ़र चुनता है; best_success पहले हाल की डिलीवरी सफलता के आधार पर ऑफ़र को क्रमबद्ध करता है। best_success हर प्रोवाइडर को पिछले 30 पूर्ण दिनों में OTP पाने वाले ऑर्डर के अनुपात पर 10% बैंड में आँकता है, और किसी प्रोवाइडर को तभी गिनता है जब उस अवधि में उसके कम से कम 20 ऑर्डर हों — इस सीमा से नीचे या बिना इतिहास वाले प्रोवाइडर तटस्थ माने जाते हैं, इसलिए नए ऑफ़र कभी उपेक्षित नहीं होते (वैकल्पिक; संकेत तटस्थ से शुरू होता है)। यदि prefer_provider भी सेट है, तो पसंदीदा प्रोवाइडर फिर भी सबसे पहले रहता है।
quantity
integer
नहीं
आइटम की संख्या (1-100, डिफ़ॉल्ट 1)
डुप्लिकेट ऑर्डर बनाए बिना सुरक्षित रूप से रिट्राई करने के लिए Idempotency-Key हेडर पास करें। key में अक्षर, अंक, हाइफ़न और अंडरस्कोर (A-Z a-z 0-9 _ -) हो सकते हैं, अधिकतम 128 कैरेक्टर; अमान्य key को 422 VALIDATION_ERROR के साथ अस्वीकार किया जाता है। एक ही key और एक ही body के साथ रिट्राई करने पर मूल रिज़ल्ट दोबारा मिलता है (आंशिक सफलता के failed_count सहित)। ऐसा रिट्राई जो प्रोवाइडर तक पहुँच गया पर विफल हो गया, रिकॉर्ड हो जाता है और दोबारा वही एरर लौटाता है — दोबारा कोशिश के लिए नई key का इस्तेमाल करें। बिना साइड-इफ़ेक्ट वाली विफलताएँ (अपर्याप्त बैलेंस, कोई उपलब्ध ऑफ़र नहीं) key को रिलीज़ कर देती हैं, इसलिए आप टॉप-अप करके उसी key के साथ रिट्राई कर सकते हैं। किसी key को अलग body के साथ दोबारा इस्तेमाल करने पर 422 IDEMPOTENCY_KEY_REUSED मिलता है, और उस key के साथ अभी चल रहे रिक्वेस्ट पर 409 REQUEST_IN_PROGRESS मिलता है। create रिस्पॉन्स में failed_reason फ़ील्ड हमेशा null होता है — यह केवल ऑर्डर poll/list के समय भरता है।
एग्ज़ांपल रिक्वेस्ट
curl -s -X POST https://api.smscode.gg/v1/orders/create \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: unique-request-id-123" \ -d '{"product_id":142,"quantity":1}'# Or route by catalog_product_id — the server picks a current tier.# product_id is the stable exact tier-slot id. catalog_product_id is the# country+platform umbrella for routed ordering. Optional min_price/max_price# bound the tier; operator_id scopes to a carrier from /catalog/operators.# Pass EITHER product_id OR catalog_product_id.curl -s -X POST https://api.smscode.gg/v1/orders/create \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: unique-request-id-124" \ -d '{"catalog_product_id":87,"min_price":12000,"max_price":20000,"operator_id":433}'
पूरा हो चुका नंबर रीएक्टिवेट करता है — नया नंबर किराए पर लिए बिना उसी नंबर को दूसरे वेरिफ़िकेशन कोड के लिए दोबारा ऑर्डर करता है। केवल वही पूरा हो चुका ऑर्डर योग्य है जिसका नंबर रीएक्टिवेशन सपोर्ट करता है (ऑर्डर पर can_reactivate चेक करें, या reactivate-options से प्रीव्यू करें)। रीएक्टिवेट किया गया चाइल्ड एक नया ऑर्डर होता है, जो create जैसी ही शेप में लौटाया जाता है; बैलेंस ऑटोमैटिकली कट जाता है।
रिक्वेस्ट बॉडी
नाम
टाइप
ज़रूरी
विवरण
id
integer
हाँ
रीएक्टिवेट किया जाने वाला पूरा हो चुका ऑर्डर।
max_price
integer
नहीं
वैकल्पिक कॉस्ट सीलिंग। IDR integer। अगर लाइव कॉस्ट इससे ज़्यादा हो तो रीएक्टिवेशन 422 VALIDATION_ERROR के साथ अस्वीकार कर दिया जाता है।
create की तरह यह भी एक money mutation है — सुरक्षित रिट्राई के लिए Idempotency-Key हेडर पास करें (एक create और एक reactivate कभी भी एक ही key पर नहीं टकरा सकते)। किसी key को अलग body के साथ दोबारा इस्तेमाल करने पर 422 IDEMPOTENCY_KEY_REUSED मिलता है, और उस key के साथ अभी सेटल हो रहे रिक्वेस्ट पर 409 REQUEST_IN_PROGRESS मिलता है। जिस नंबर को रीएक्टिवेट नहीं किया जा सकता, वह 409 CONFLICT लौटाता है; बैलेंस बहुत कम होने पर 409 INSUFFICIENT_BALANCE मिलता है।
अभी रीएक्टिवेशन पर कितना चार्ज होगा, इसका प्रीव्यू देता है। केवल-पढ़ने के लिए — कोई Idempotency-Key इस्तेमाल नहीं करता और कुछ भी नहीं बनाता। कॉस्ट को IDR integer के रूप में लौटाता है। यह केवल उसी पूरा हो चुके ऑर्डर के लिए उपलब्ध है जिसका नंबर रीएक्टिवेशन सपोर्ट करता है।
पाथ पैरामीटर्स
नाम
टाइप
ज़रूरी
विवरण
id
integer
हाँ
वह ऑर्डर ID जिसके लिए रीएक्टिवेशन कॉस्ट का प्रीव्यू करना है (path parameter)।
अपना webhook URL और/या secret अपडेट करें। पहली बार URL सेट करने पर secret ऑटो-जनरेट होता है। क्लियर करने के लिए खाली स्ट्रिंग भेजें। URL HTTPS होना चाहिए।
रिक्वेस्ट बॉडी
नाम
टाइप
ज़रूरी
विवरण
webhook_url
string
नहीं
Webhook इवेंट प्राप्त करने के लिए HTTPS URL (क्लियर करने के लिए खाली स्ट्रिंग)
webhook_secret
string
नहीं
HMAC-SHA256 सिग्नेचर के लिए शेयर्ड secret (पहली बार सेट पर छोड़ने पर ऑटो-जनरेट)
आपके कॉन्फ़िगर किए गए webhook URL पर एक टेस्ट इवेंट भेजता है। आपके सर्वर से HTTP स्टेटस कोड लौटाता है। लाइव होने से पहले endpoint वेरिफाई करने के लिए उपयोगी।
पैरामीटर्स
कोई नहीं
एग्ज़ांपल रिक्वेस्ट
curl -s -X POST https://api.smscode.gg/v1/webhook/test \ -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/webhook/test", { method: "POST", headers: { Authorization: "Bearer YOUR_API_TOKEN" },});const data = await res.json();
पोलिंग के बजाय ऑर्डर इवेंट्स के लिए रियल-टाइम पुश नोटिफ़िकेशन प्राप्त करने हेतु webhook URL कॉन्फ़िगर करें। बॉट स्क्रिप्ट्स के लिए यह रेकमेंडेड तरीक़ा है।
इवेंट्स
इवेंट
ट्रिगर
order.otp_received
नया SMS मिला; पहचाना गया कोड null हो सकता है
order.completed
ऑर्डर कम्प्लीट मार्क हुआ (मैन्युअली या एक्सपायरी द्वारा)
order.expired
कोई SMS मिलने से पहले ऑर्डर एक्सपायर हुआ (बैलेंस रिफंड)
order.canceled
यूज़र द्वारा ऑर्डर कैंसल (बैलेंस रिफंड)
हर नया SMS यह event भेजता है। otp_message मौजूद होने पर otp_code null हो सकता है। कई SMS event क्रम से बाहर आ सकते हैं; पुराने aggregate pair को अनदेखा करने के लिए sms_revision का उपयोग करें।
हर webhook रिक्वेस्ट में X-Webhook-Signature हेडर शामिल होता है जिसमें रिक्वेस्ट बॉडी का HMAC-SHA256 सिग्नेचर होता है, आपके webhook_secret को key के रूप में उपयोग करते हुए:
रिक्वेस्ट ऑथेंटिक है यह सुनिश्चित करने के लिए अपने सर्वर पर इस सिग्नेचर को वेरिफाई करें। डिलीवरी फ़ायर-एंड-फ़ॉरगेट है जिसमें 3-सेकंड टाइमआउट और कोई रिट्राई नहीं।
⟩रेट लिमिट्स
API रिक्वेस्ट प्रति endpoint ग्रुप rate-limited हैं। लिमिट पार करने पर 429 Too Many Requests रिस्पॉन्स मिलता है जिसमें Retry-After हेडर बताता है कितने सेकंड इंतज़ार करना है।
Endpoint ग्रुप
लिमिट
विंडो
कैटलॉग (देश, सर्विसेज़, प्रोडक्ट्स, एक्सचेंज रेट)
5,000 रिक्वेस्ट
60 सेकंड
बैलेंस
600 रिक्वेस्ट
60 सेकंड
ऑर्डर पढ़ना (सूची, गेट, एक्टिव)
5,000 रिक्वेस्ट
60 सेकंड
ऑर्डर बनाना
3,000 रिक्वेस्ट
60 सेकंड
ऑर्डर कैंसल करना
1,000 रिक्वेस्ट
60 सेकंड
ऑर्डर कार्रवाइयाँ (finish, resend)
1,000 रिक्वेस्ट
60 सेकंड
Webhook कॉन्फ़िगरेशन (गेट, अपडेट)
600 रिक्वेस्ट
60 सेकंड
Webhook टेस्ट
10 रिक्वेस्ट
60 सेकंड
⟩एरर कोड
एरर रिस्पॉन्स में error.code में इनमें से एक कोड शामिल होता है:
कोड
HTTP
विवरण
UNAUTHORIZED
401
API token गायब या अमान्य
FORBIDDEN
403
एक्सेस अस्वीकृत
NOT_FOUND
404
रिसोर्स नहीं मिला (ऑर्डर, एक्सचेंज रेट, आदि)
CONFLICT
409
डुप्लिकेट रिक्वेस्ट या रिसोर्स कॉन्फ़्लिक्ट
INSUFFICIENT_BALANCE
409
ऑर्डर बनाने के लिए पर्याप्त बैलेंस नहीं
VALIDATION_ERROR
422
रिक्वेस्ट पैरामीटर्स वैलिडेशन में फ़ेल
RATE_LIMIT_EXCEEDED
429
बहुत ज़्यादा रिक्वेस्ट (Retry-After हेडर देखें)
INTERNAL_ERROR
500
इंटरनल सर्वर एरर
PROVIDER_ERROR
422
अपस्ट्रीम SMS प्रोवाइडर ने रिक्वेस्ट रिजेक्ट की। ऑर्डर बनाने में विफलता पर error में details हो सकता है: cause_counts (पुराने product_id ऑर्डर — कारण के अनुसार गिनती) या attempts (catalog_product_id ऑर्डर — प्रति प्रयास परिणाम), जिनके मान ok, no_numbers, insufficient_balance, price_rejected, provider_unavailable, provider_account_balance, provider_error होते हैं।
NO_OFFER_AVAILABLE
422
अनुरोधित प्रोडक्ट और नीति (मूल्य सीमा, उपलब्धता) से मेल खाता कोई सक्रिय ऑफ़र नहीं है।
CANCEL_TOO_EARLY
409
ऑर्डर कैंसल करने के लिए बहुत नया — 2 मिनट इंतज़ार करें
REQUEST_IN_PROGRESS
409
इस idempotency key के साथ एक क्रिएट रिक्वेस्ट अभी भी चल रहा है
IDEMPOTENCY_KEY_REUSED
422
यह idempotency key पहले से किसी अलग रिक्वेस्ट body के साथ इस्तेमाल हो चुकी है
SERVICE_UNAVAILABLE
503
सर्विस अस्थायी रूप से अनुपलब्ध (मेंटेनेंस)
⟩अवलोकन
/v2 API के सभी मनी फ़ील्ड USD में हैं, जो एक मनी ऑब्जेक्ट के रूप में लौटाए जाते हैं — { "amount": "0.92", "currency": "USD", "canonical_amount": 15000, "canonical_currency": "IDR" }। amount एक दशमलव स्ट्रिंग है; canonical_amount सटीक IDR लेजर वैल्यू है (रिकंसिलिएशन के लिए इसका उपयोग करें)। लागू किया गया USD/IDR rate प्रति रिस्पॉन्स एक बार meta.fx में दर्शाया जाता है। v2 v1 के समान ही IDR लेजर पर रेंडर-टाइम USD प्रोजेक्शन है — यह कभी भी USD स्टोर या ट्रांज़ैक्ट नहीं करता।
/v2 API के सभी मनी फ़ील्ड USD में हैं, जो एक मनी ऑब्जेक्ट के रूप में लौटाए जाते हैं — { "amount": "0.92", "currency": "USD", "canonical_amount": 15000, "canonical_currency": "IDR" }। amount एक दशमलव स्ट्रिंग है; canonical_amount सटीक IDR लेजर वैल्यू है (रिकंसिलिएशन के लिए इसका उपयोग करें)। लागू किया गया USD/IDR rate प्रति रिस्पॉन्स एक बार meta.fx में दर्शाया जाता है। v2 v1 के समान ही IDR लेजर पर रेंडर-टाइम USD प्रोजेक्शन है — यह कभी भी USD स्टोर या ट्रांज़ैक्ट नहीं करता।
किसी देश + सेवा के लिए चुने जा सकने वाले ऑपरेटर लौटाता है। अगर वास्तविक ऑपरेटर और Any stock दोनों उपलब्ध हों, तो response में operator_id null वाली Any row शामिल होती है; अगर operator-specific उत्पाद नहीं हैं, तो सूची खाली होती है।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
GET/catalog/exchange-rate
करेंसी कन्वर्ज़न के लिए उपयोग किया जाने वाला वर्तमान USD/IDR एक्सचेंज रेट लौटाता है।
पैरामीटर्स
कोई नहीं — v2 हमेशा USD/IDR लौटाता है; v1 का ?pair पैरामीटर नज़रअंदाज़ किया जाता है।
v2:{ pair, rate, rate_as_of } लौटाता है (कोई base_currency/quote_currency नहीं, कोई meta रैपर नहीं — रेट ही डेटा है)। ?pair को नज़रअंदाज़ किया जाता है — v2 हमेशा USD/IDR लौटाता है (v1 ?pair का सम्मान करता है)। यदि कोई उपयोग योग्य रेट नहीं है तो 503 FX_RATE_UNAVAILABLE लौटाता है।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
GET/orders
ऑथेंटिकेटेड यूज़र के ऑर्डर्स की सूची लौटाता है, सबसे हाल के पहले। स्टेटस और offset के ज़रिए पेजिनेशन द्वारा फ़िल्टरिंग सपोर्ट करता है।
क्वेरी पैरामीटर्स
नाम
टाइप
ज़रूरी
विवरण
limit
integer
नहीं
अधिकतम रिज़ल्ट (1-100, डिफ़ॉल्ट 20)
offset
integer
नहीं
स्किप करने के लिए रिज़ल्ट की संख्या (डिफ़ॉल्ट 0)
status
string
नहीं
स्टेटस से फ़िल्टर करें: ACTIVE, OTP_RECEIVED, COMPLETED, CANCELED, EXPIRED (केस-इनसेंसिटिव)
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
GET/orders/{id}
ID के अनुसार एक ऑर्डर लौटाता है। सिर्फ़ ऑथेंटिकेटेड यूज़र के ऑर्डर लौटाता है।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
GET/orders/active
सभी वर्तमान एक्टिव ऑर्डर्स (ACTIVE + OTP_RECEIVED) की सूची। OTP स्टेटस अपडेट के लिए पोल करने हेतु इसका उपयोग करें।
v2: यह एंडपॉइंट मनी-बेयरिंग नहीं है — यह न amount लौटाता है और न meta.fx (v1 जैसी ही संरचना, /v2 के अंतर्गत)।
POST/orders/create
एक नया वर्चुअल नंबर ऑर्डर बनाता है। बैलेंस ऑटोमैटिकली कटता है। नेटवर्क रिट्राई पर डुप्लिकेट ऑर्डर रोकने के लिए वैकल्पिक Idempotency-Key हेडर सपोर्ट करता है।
रिक्वेस्ट बॉडी
नाम
टाइप
ज़रूरी
विवरण
product_id
integer
नहीं
सीधे ऑर्डर करने के लिए सटीक स्थिर टियर-स्लॉट product ID। या तो यह दें या catalog_product_id, दोनों नहीं।
catalog_product_id
integer
नहीं
रूटेड देश+प्लेटफ़ॉर्म umbrella ID। सर्वर वर्तमान matching tier चुनता है। यह दें या product_id।
operator_id
integer
नहीं
/catalog/operators से वैकल्पिक ऑपरेटर ID। केवल catalog_product_id के साथ मान्य; Any के लिए छोड़ दें।
min_price
string
नहीं
वैकल्पिक price floor। USD decimal string (जैसे "0.30")। केवल catalog_product_id के साथ मान्य।
max_price
string
नहीं
वैकल्पिक price cap। USD decimal string (जैसे "0.50")। केवल catalog_product_id के साथ मान्य।
prefer_provider
string
नहीं
वैकल्पिक प्रोवाइडर कोड, जब ऑफ़र बराबर हों तो इसे प्राथमिकता दी जाती है।
policy
string
नहीं
वैकल्पिक रूटिंग नीति, केवल catalog_product_id के साथ मान्य। मान: cheapest (डिफ़ॉल्ट) सबसे कम कीमत वाला स्वस्थ ऑफ़र चुनता है; best_success पहले हाल की डिलीवरी सफलता के आधार पर ऑफ़र को क्रमबद्ध करता है। best_success हर प्रोवाइडर को पिछले 30 पूर्ण दिनों में OTP पाने वाले ऑर्डर के अनुपात पर 10% बैंड में आँकता है, और किसी प्रोवाइडर को तभी गिनता है जब उस अवधि में उसके कम से कम 20 ऑर्डर हों — इस सीमा से नीचे या बिना इतिहास वाले प्रोवाइडर तटस्थ माने जाते हैं, इसलिए नए ऑफ़र कभी उपेक्षित नहीं होते (वैकल्पिक; संकेत तटस्थ से शुरू होता है)। यदि prefer_provider भी सेट है, तो पसंदीदा प्रोवाइडर फिर भी सबसे पहले रहता है।
quantity
integer
नहीं
आइटम की संख्या (1-100, डिफ़ॉल्ट 1)
डुप्लिकेट ऑर्डर बनाए बिना सुरक्षित रूप से रिट्राई करने के लिए Idempotency-Key हेडर पास करें। key में अक्षर, अंक, हाइफ़न और अंडरस्कोर (A-Z a-z 0-9 _ -) हो सकते हैं, अधिकतम 128 कैरेक्टर; अमान्य key को 422 VALIDATION_ERROR के साथ अस्वीकार किया जाता है। एक ही key और एक ही body के साथ रिट्राई करने पर मूल रिज़ल्ट दोबारा मिलता है (आंशिक सफलता के failed_count सहित)। ऐसा रिट्राई जो प्रोवाइडर तक पहुँच गया पर विफल हो गया, रिकॉर्ड हो जाता है और दोबारा वही एरर लौटाता है — दोबारा कोशिश के लिए नई key का इस्तेमाल करें। बिना साइड-इफ़ेक्ट वाली विफलताएँ (अपर्याप्त बैलेंस, कोई उपलब्ध ऑफ़र नहीं) key को रिलीज़ कर देती हैं, इसलिए आप टॉप-अप करके उसी key के साथ रिट्राई कर सकते हैं। किसी key को अलग body के साथ दोबारा इस्तेमाल करने पर 422 IDEMPOTENCY_KEY_REUSED मिलता है, और उस key के साथ अभी चल रहे रिक्वेस्ट पर 409 REQUEST_IN_PROGRESS मिलता है। create रिस्पॉन्स में failed_reason फ़ील्ड हमेशा null होता है — यह केवल ऑर्डर poll/list के समय भरता है।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
POST/orders/cancel
एक एक्टिव ऑर्डर कैंसल करता है। रेंटल कॉस्ट आपके अकाउंट बैलेंस में रिफंड हो जाती है।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
POST/orders/finish
OTP प्राप्त होने के बाद ऑर्डर को कम्प्लीट मार्क करता है। एक्सपायरी का इंतज़ार करने के बजाय नंबर तुरंत रिलीज़ होता है।
पूरा हो चुका नंबर रीएक्टिवेट करता है — नया नंबर किराए पर लिए बिना उसी नंबर को दूसरे वेरिफ़िकेशन कोड के लिए दोबारा ऑर्डर करता है। केवल वही पूरा हो चुका ऑर्डर योग्य है जिसका नंबर रीएक्टिवेशन सपोर्ट करता है (ऑर्डर पर can_reactivate चेक करें, या reactivate-options से प्रीव्यू करें)। रीएक्टिवेट किया गया चाइल्ड एक नया ऑर्डर होता है, जो create जैसी ही शेप में लौटाया जाता है; बैलेंस ऑटोमैटिकली कट जाता है।
रिक्वेस्ट बॉडी
नाम
टाइप
ज़रूरी
विवरण
id
integer
हाँ
रीएक्टिवेट किया जाने वाला पूरा हो चुका ऑर्डर।
max_price
string
नहीं
वैकल्पिक कॉस्ट सीलिंग। USD decimal string (जैसे "0.50")। अगर लाइव कॉस्ट इससे ज़्यादा हो तो रीएक्टिवेशन 422 VALIDATION_ERROR के साथ अस्वीकार कर दिया जाता है।
create की तरह यह भी एक money mutation है — सुरक्षित रिट्राई के लिए Idempotency-Key हेडर पास करें (एक create और एक reactivate कभी भी एक ही key पर नहीं टकरा सकते)। किसी key को अलग body के साथ दोबारा इस्तेमाल करने पर 422 IDEMPOTENCY_KEY_REUSED मिलता है, और उस key के साथ अभी सेटल हो रहे रिक्वेस्ट पर 409 REQUEST_IN_PROGRESS मिलता है। जिस नंबर को रीएक्टिवेट नहीं किया जा सकता, वह 409 CONFLICT लौटाता है; बैलेंस बहुत कम होने पर 409 INSUFFICIENT_BALANCE मिलता है।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
GET/orders/{id}/reactivate-options
अभी रीएक्टिवेशन पर कितना चार्ज होगा, इसका प्रीव्यू देता है। केवल-पढ़ने के लिए — कोई Idempotency-Key इस्तेमाल नहीं करता और कुछ भी नहीं बनाता। कॉस्ट को FX रसीद के साथ USD money object के रूप में लौटाता है। यह केवल उसी पूरा हो चुके ऑर्डर के लिए उपलब्ध है जिसका नंबर रीएक्टिवेशन सपोर्ट करता है।
पाथ पैरामीटर्स
नाम
टाइप
ज़रूरी
विवरण
id
integer
हाँ
वह ऑर्डर ID जिसके लिए रीएक्टिवेशन कॉस्ट का प्रीव्यू करना है (path parameter)।
v2: मनी फ़ील्ड USD मनी ऑब्जेक्ट हैं और रिस्पॉन्स में एक ही meta.fx { pair, rate, rate_as_of } होता है। rate प्रति 1 USD पूर्णांक IDR है, इसलिए USD = canonical_amount / rate। टोटल में 2 दशमलव; प्रति-आइटम कीमत/रिफ़ंड में 4 दशमलव उपयोग होते हैं। पूर्णतः धनात्मक राशि कभी भी 0.00 में राउंड नहीं होती। rate_as_of उस रेट का RFC3339 टाइमस्टैम्प (+00:00 रूप) है, या जब कोई टाइमस्टैम्प दर्ज नहीं है तो null।
केवल v2: यदि कोई उपयोग योग्य USD/IDR रेट उपलब्ध नहीं है, तो मनी एंडपॉइंट मनी बॉडी के बजाय Retry-After हेडर के साथ 503 FX_RATE_UNAVAILABLE लौटाते हैं। v1 यह कभी नहीं लौटाता।
GET/webhook
आपकी वर्तमान webhook नोटिफ़िकेशन कॉन्फ़िगरेशन लौटाता है।
अपना webhook URL और/या secret अपडेट करें। पहली बार URL सेट करने पर secret ऑटो-जनरेट होता है। क्लियर करने के लिए खाली स्ट्रिंग भेजें। URL HTTPS होना चाहिए।
रिक्वेस्ट बॉडी
नाम
टाइप
ज़रूरी
विवरण
webhook_url
string
नहीं
Webhook इवेंट प्राप्त करने के लिए HTTPS URL (क्लियर करने के लिए खाली स्ट्रिंग)
webhook_secret
string
नहीं
HMAC-SHA256 सिग्नेचर के लिए शेयर्ड secret (पहली बार सेट पर छोड़ने पर ऑटो-जनरेट)
आपके कॉन्फ़िगर किए गए webhook URL पर एक टेस्ट इवेंट भेजता है। आपके सर्वर से HTTP स्टेटस कोड लौटाता है। लाइव होने से पहले endpoint वेरिफाई करने के लिए उपयोगी।
पैरामीटर्स
कोई नहीं
एग्ज़ांपल रिक्वेस्ट
curl -s -X POST https://api.smscode.gg/v2/webhook/test \ -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v2/webhook/test", { method: "POST", headers: { Authorization: "Bearer YOUR_API_TOKEN" },});const data = await res.json();
पोलिंग के बजाय ऑर्डर इवेंट्स के लिए रियल-टाइम पुश नोटिफ़िकेशन प्राप्त करने हेतु webhook URL कॉन्फ़िगर करें। बॉट स्क्रिप्ट्स के लिए यह रेकमेंडेड तरीक़ा है।
इवेंट्स
इवेंट
ट्रिगर
order.otp_received
नया SMS मिला; पहचाना गया कोड null हो सकता है
order.completed
ऑर्डर कम्प्लीट मार्क हुआ (मैन्युअली या एक्सपायरी द्वारा)
order.expired
कोई SMS मिलने से पहले ऑर्डर एक्सपायर हुआ (बैलेंस रिफंड)
order.canceled
यूज़र द्वारा ऑर्डर कैंसल (बैलेंस रिफंड)
हर नया SMS यह event भेजता है। otp_message मौजूद होने पर otp_code null हो सकता है। कई SMS event क्रम से बाहर आ सकते हैं; पुराने aggregate pair को अनदेखा करने के लिए sms_revision का उपयोग करें।
हर webhook रिक्वेस्ट में X-Webhook-Signature हेडर शामिल होता है जिसमें रिक्वेस्ट बॉडी का HMAC-SHA256 सिग्नेचर होता है, आपके webhook_secret को key के रूप में उपयोग करते हुए:
रिक्वेस्ट ऑथेंटिक है यह सुनिश्चित करने के लिए अपने सर्वर पर इस सिग्नेचर को वेरिफाई करें। डिलीवरी फ़ायर-एंड-फ़ॉरगेट है जिसमें 3-सेकंड टाइमआउट और कोई रिट्राई नहीं।
⟩रेट लिमिट्स
API रिक्वेस्ट प्रति endpoint ग्रुप rate-limited हैं। लिमिट पार करने पर 429 Too Many Requests रिस्पॉन्स मिलता है जिसमें Retry-After हेडर बताता है कितने सेकंड इंतज़ार करना है।
Endpoint ग्रुप
लिमिट
विंडो
कैटलॉग (देश, सर्विसेज़, प्रोडक्ट्स, एक्सचेंज रेट)
5,000 रिक्वेस्ट
60 सेकंड
बैलेंस
600 रिक्वेस्ट
60 सेकंड
ऑर्डर पढ़ना (सूची, गेट, एक्टिव)
5,000 रिक्वेस्ट
60 सेकंड
ऑर्डर बनाना
3,000 रिक्वेस्ट
60 सेकंड
ऑर्डर कैंसल करना
1,000 रिक्वेस्ट
60 सेकंड
ऑर्डर कार्रवाइयाँ (finish, resend)
1,000 रिक्वेस्ट
60 सेकंड
Webhook कॉन्फ़िगरेशन (गेट, अपडेट)
600 रिक्वेस्ट
60 सेकंड
Webhook टेस्ट
10 रिक्वेस्ट
60 सेकंड
⟩एरर कोड
एरर रिस्पॉन्स में error.code में इनमें से एक कोड शामिल होता है:
कोड
HTTP
विवरण
UNAUTHORIZED
401
API token गायब या अमान्य
FORBIDDEN
403
एक्सेस अस्वीकृत
NOT_FOUND
404
रिसोर्स नहीं मिला (ऑर्डर, एक्सचेंज रेट, आदि)
CONFLICT
409
डुप्लिकेट रिक्वेस्ट या रिसोर्स कॉन्फ़्लिक्ट
INSUFFICIENT_BALANCE
409
ऑर्डर बनाने के लिए पर्याप्त बैलेंस नहीं
VALIDATION_ERROR
422
रिक्वेस्ट पैरामीटर्स वैलिडेशन में फ़ेल
RATE_LIMIT_EXCEEDED
429
बहुत ज़्यादा रिक्वेस्ट (Retry-After हेडर देखें)
INTERNAL_ERROR
500
इंटरनल सर्वर एरर
PROVIDER_ERROR
422
अपस्ट्रीम SMS प्रोवाइडर ने रिक्वेस्ट रिजेक्ट की। ऑर्डर बनाने में विफलता पर error में details हो सकता है: cause_counts (पुराने product_id ऑर्डर — कारण के अनुसार गिनती) या attempts (catalog_product_id ऑर्डर — प्रति प्रयास परिणाम), जिनके मान ok, no_numbers, insufficient_balance, price_rejected, provider_unavailable, provider_account_balance, provider_error होते हैं।
NO_OFFER_AVAILABLE
422
अनुरोधित प्रोडक्ट और नीति (मूल्य सीमा, उपलब्धता) से मेल खाता कोई सक्रिय ऑफ़र नहीं है।
CANCEL_TOO_EARLY
409
ऑर्डर कैंसल करने के लिए बहुत नया — 2 मिनट इंतज़ार करें
REQUEST_IN_PROGRESS
409
इस idempotency key के साथ एक क्रिएट रिक्वेस्ट अभी भी चल रहा है
IDEMPOTENCY_KEY_REUSED
422
यह idempotency key पहले से किसी अलग रिक्वेस्ट body के साथ इस्तेमाल हो चुकी है
SERVICE_UNAVAILABLE
503
सर्विस अस्थायी रूप से अनुपलब्ध (मेंटेनेंस)
FX_RATE_UNAVAILABLE
503
USD/IDR एक्सचेंज रेट अनुपलब्ध (v2 मनी एंडपॉइंट) — Retry-After हेडर के साथ 503 लौटाता है।
v1 → v2
⟩v1 से v2 में माइग्रेशन
v1 IDR देता है; v2 USD देता है। दोनों वर्शन स्थायी रूप से साथ-साथ रहते हैं — कोई सनसेट नहीं है। प्रति इंटीग्रेशन एक वर्शन चुनें; बेस पाथ मिक्स न करें। मनी कैसे दर्शाई जाती है, इसके अलावा v2 v1 के समान है।
product_id स्थिर SMSCode tier-slot ID है। अगर आप वही सटीक tier ऑर्डर करना चाहते हैं तो इसे सहेजें; इसकी कीमत और उपलब्धता उसी row में बदल सकती है। catalog_product_id routed ordering के लिए स्थिर देश+प्लेटफ़ॉर्म umbrella है; जब आप चाहते हैं कि सर्वर वर्तमान matching tier चुने, तो इसे वैकल्पिक operator_id, min_price, max_price, prefer_provider और policy के साथ उपयोग करें।