StampMitraDevelopers

गाइड

e-stamp paper API: catalog से certificate तक पूरा order flow

StampMitra की e-stamp API में सात कदम हैं: /v1/services से catalog, /v1/estamp/states से state और instrument, /v1/estamp/duty/calculate से duty, /v1/orders से order, parties जोड़ना, /v1/payments/intents से payment, और आख़िर में documents से certificate download। duty की रकम सिर्फ़ server निकालता है, आप उसे कभी खुद नहीं निकालते।

लेखक: StampMitra Developer Teamअंतिम अपडेट: यह पेज English में पढ़ें

अगर आप e-stamp paper API ढूँढ रहे हैं, तो StampMitra की e-stamp API एक ऐसा सिलसिला देती है जिसमें आप अपने ऐप से state और article देखते हैं, duty की गणना करवाते हैं, order बनाते हैं, उसमें पक्षकारों (parties) की जानकारी जोड़ते हैं, payment करवाते हैं और आखिर में e-stamp का certificate PDF डाउनलोड करते हैं। हर कदम एक अलग endpoint है और हर endpoint के लिए API key पर अलग scope चाहिए।

ई-स्टांप API इंटीग्रेशन में सबसे ज़रूरी बात यह है कि duty की रकम आपको खुद कभी नहीं निकालनी है। रकम /v1/estamp/duty/calculate से आती है और उसे वैसे ही इस्तेमाल करना है। इस गाइड में हम एक काल्पनिक legal-tech ऐप "NyayaDesk" की नज़र से पूरा flow चलेंगे, जो अपने ग्राहकों के लिए stamp paper जारी करती है।

ध्यान रखें कि StampMitra एक निजी LegalTech प्लेटफ़ॉर्म है (Bani Global Industries LLP द्वारा संचालित), सरकारी एजेंसी या law firm नहीं। यह लेख सामान्य जानकारी है, कानूनी सलाह नहीं। किस दस्तावेज़ पर कौन सा stamp लगेगा, यह अपने वकील या संबंधित राज्य के stamp विभाग से पक्का करें।

मुख्य बातें

  • e-stamp की पूरी सतह एक ही serviceCode estamp के तहत गिनी जाती है। production में इसके लिए आपके खाते में entitlement चाहिए।
  • Base URL https://api-b2b.stampmitra.in है। हर request में Authorization: Bearer <api-key> (या x-api-key) जाता है। sandbox की key sk_test_... और production की sk_live_... होती है।
  • सात कदम: catalog, state/instrument/article, duty calculate, order, parties, payment, documents।
  • scopes: services.read, estamp.read, estamp.duty.calculate, orders.create, estamp.parties.write, payments.write, payments.read, orders.read, documents.read।
  • duty का हिसाब सिर्फ़ server करता है। response की रकम को अपने कोड में बदलना या दोबारा निकालना गलती है।
  • order के details object का e-stamp वाला shape अभी final नहीं है, इसलिए उसे अपने sandbox के जवाबों से जाँचते रहें।
  • हर error { error: { code, message, requestId } } के रूप में आता है। requestId सँभालकर रखें, support को यही चाहिए होगा।
  • sandbox में असली ग्राहक का डेटा न डालें।

e-stamp paper API असल में क्या देती है, और क्या नहीं?

सीधी बात: यह API stamp paper जारी करवाने का पूरा workflow आपके कोड में उतार देती है। आपका ग्राहक अगर किराये का agreement बनवा रहा है, तो आपका ऐप API से पूछ सकता है कि उस राज्य में कौन से instrument उपलब्ध हैं, फिर duty निकलवा सकता है, फिर order बना सकता है और अंत में certificate की PDF ले सकता है।

यह क्या नहीं करती, यह जानना भी उतना ही ज़रूरी है। यह आपको कानूनी सलाह नहीं देती कि कौन सा article चुनें। यह किसी दस्तावेज़ की वैधता या अदालत में स्वीकार होने की गारंटी नहीं देती। और यह duty की कोई दर आपके हाथ में नहीं देती कि आप अपने कोड में hardcode कर लें। दरें राज्य और instrument के हिसाब से बदलती हैं और बदलती रहती हैं, इसलिए जवाब हमेशा duty/calculate से लें।

e-stamp के आठ docs पेज, एक नज़र में

StampMitra के docs में e-stamp के आठ हिस्से हैं। नीचे की तालिका में हर हिस्से का काम और endpoint दिया है, जो सीधे api-products.ts से लिया गया है।

हिस्साEndpointScope
CatalogGET /v1/services, GET /v1/services/:serviceCodeservices.read
Schema / OptionsGET /v1/estamp/schema/:serviceCodeestamp.read
State / Instrument / ArticleGET /v1/estamp/states, GET /v1/estamp/states/:stateCode/instruments, GET /v1/estamp/instruments/:instrumentCode/articlesestamp.read
Duty / ValuePOST /v1/estamp/duty/calculateestamp.duty.calculate
PartiesPOST /v1/estamp/orders/:orderId/partiesestamp.parties.write
OrdersPOST /v1/orders, GET /v1/orders/:id, GET /v1/orders/:id/statusorders.create, orders.read
PaymentPOST /v1/payments/intents, GET /v1/payments/intents/:id, GET /v1/orders/:id/paymentpayments.write, payments.read, orders.read
DocumentsGET /v1/orders/:id/documents, GET /v1/orders/:id/documents/:documentId/downloaddocuments.read

हर हिस्से का विस्तृत reference e-stamp docs में है, और catalog, orders, payment जैसे पेज अलग से खुलते हैं।

शुरू करने से पहले: API key, scope और base URL की तैयारी

कुछ भी कॉल करने से पहले तीन चीज़ें तय कर लें। पहली, base URL: https://api-b2b.stampmitra.in। दूसरी, API key: API key authentication में बताया गया है कि हर protected endpoint को Authorization: Bearer <key> या x-api-key: <key> header चाहिए। तीसरी, scopes: key बनाते समय ही तय होता है कि वह क्या-क्या कर सकती है।

NyayaDesk जैसी टीम के लिए एक अच्छी आदत है कि अलग-अलग काम के लिए अलग key रखें। जो key सिर्फ़ dropdown भरने के लिए है (state, instrument) उसे सिर्फ़ services.read और estamp.read दें। जो key order बनाती है उसे orders.create, estamp.parties.write, payments.write जैसे scope चाहिए। इससे अगर कोई key लीक हो जाए तो नुकसान सीमित रहता है। docs के मुताबिक संवेदनशील scopes पर IP allowlist भी लगाई जा सकती है।

sandbox और production की key

key का environment उसी से तय होता है: sk_test_... sandbox में चलती है और sk_live_... production में। environment server-side तय होता है, आपको अलग URL नहीं बदलना पड़ता। sandbox के कॉल मीटर होते हैं और log होते हैं, लेकिन आपके wallet से पैसे नहीं कटते। production में प्राइस वाली calls आपके fulfilment wallet से कटती हैं। pricing पेज पर वर्तमान दर देखें; e-stamp की हर call की दर ₹5 के रूप में उस पेज से मिलती है। sandbox और production की key का फ़र्क विस्तार से sandbox बनाम production API keys गाइड में है।

पहली जाँच: curl से एक छोटा कॉल

cURL
curl https://api-b2b.stampmitra.in/v1/services \
  -H "Authorization: Bearer sk_test_xxxxxxxx"

अगर जवाब 401 आए तो key गलत है। 403 आए तो key सही है पर services.read scope नहीं है। यही दो जवाब आगे भी बार-बार दिखेंगे, इसलिए इन्हें याद रखें।

पूरे flow का एक काल्पनिक दिन

सुबह दस बजे NyayaDesk के ऐप पर एक किरायेदार, मान लीजिए रश्मि, अपना करार शुरू करती है। ऐप सबसे पहले /v1/services से जाँचता है कि किराये वाली service चालू है या नहीं। फिर वह रश्मि का राज्य पूछता है और उसी राज्य की instruments की सूची मँगवाता है। रश्मि विकल्प चुनती है और ऐप duty का हिसाब करवाता है। रकम सामने आती है, रश्मि अपने मकान-मालिक से फ़ोन पर बात करके हामी भरती है, और ऐप order बना देता है। इसके बाद दोनों के नाम जोड़े जाते हैं, भुगतान होता है, और दोपहर तक certificate रश्मि के खाते में पहुँच जाता है। यह पूरी कथा सात endpoints की कड़ी है, और कोई भी कड़ी टूटे तो ऐप को साफ़ बताना होता है कि कौन सी टूटी।

इस कथा से एक डिज़ाइन सबक निकलता है: ऐप में हर order की अपनी एक छोटी "स्थिति पट्टी" रखिए, जैसे चुनाव, रकम, order, पक्षकार, भुगतान, दस्तावेज़। इससे आपकी टीम और आपके ग्राहक दोनों को पता रहता है कि बात कहाँ तक पहुँची।

Step 1: पता करें कि आपके खाते में कौन सी e-stamp service खुली है

पहला कॉल हमेशा catalog का होना चाहिए। GET /v1/services आपके organization की हर entitled service लौटाता है, verification की भी और e-stamp की भी। docs साफ़ कहते हैं कि e-stamp के लिए अलग catalog endpoint अभी नहीं है; e-stamp के instruments इसी सूची में सामान्य service entry की तरह दिखते हैं, जैसे estamp.instrument.rent_agreement।

JSON
{
  "services": [
    {
      "serviceCode": "estamp.instrument.rent_agreement",
      "name": "Rent Agreement e-Stamp",
      "active": true
    }
  ]
}

यह serviceCode आगे order बनाते समय काम आएगा, इसलिए इसे अपने कोड में hardcode मत कीजिए। हर बार (या कुछ घंटे cache करके) यह सूची मँगवाइए और जो active: true हैं उन्हीं को ग्राहक को दिखाइए। किसी एक service की जानकारी के लिए GET /v1/services/:serviceCode है।

अगर सूची खाली आए

खाली सूची का मतलब आम तौर पर यह होता है कि आपके organization के पास अभी उस service का entitlement नहीं है। तब order बनाने की कोशिश करना बेकार है। support पेज से या [email protected] पर लिखकर पूछें। ध्यान रहे, sandbox में पहुँच production से ज़्यादा खुली हो सकती है और sandbox की सफलता अपने आप production की मंज़ूरी नहीं बन जाती।

NyayaDesk के लिए नियम

NyayaDesk अपने ऐप में एक छोटा नियम रखता है: अगर ग्राहक जिस instrument को माँग रहा है उसका serviceCode सूची में नहीं है, तो "यह सेवा अभी उपलब्ध नहीं" दिखाओ और order की कोशिश ही मत करो। इससे बेवजह के 4xx errors घटते हैं।

चुनी हुई सेवा के इर्द-गिर्द की बातें

कई टीमें catalog वाले कदम को हल्के में ले लेती हैं और सीधे order बनाने लगती हैं। नतीजा यह होता है कि जब किसी ग्राहक के पास वह service खुली ही नहीं होती तो उसे सीधे 400 मिलता है, और ऐप के पास समझाने को कुछ नहीं होता। catalog के जवाब को अपने डेटाबेस में एक छोटी तालिका की तरह रखिए जिसमें serviceCode, नाम और active का झंडा हो, और उसे नियमित अंतराल पर ताज़ा करते रहिए। इससे ऐप के dropdown तेज़ी से खुलते हैं और बेवजह के कॉल घटते हैं।

एक और बात: serviceCode की बनावट (जैसे estamp.instrument.rent_agreement) में आपको आगे के नए instruments का अंदाज़ा लगाने की कोशिश नहीं करनी चाहिए। नया code तभी इस्तेमाल करें जब वह आपके catalog जवाब में दिखे।

Step 2: state, instrument और article कैसे चुनें?

अब ग्राहक के लिए सही विकल्प जुटाने हैं। तीन endpoint मिलकर यह काम करते हैं, और तीनों के लिए estamp.read scope चाहिए।

GET /v1/estamp/states e-stamp के योग्य राज्यों की सूची देता है। यह StampMitra के synced master-data catalogue से आती है। फिर GET /v1/estamp/states/:stateCode/instruments उस राज्य के instruments (यानी articles) देता है। GET /v1/estamp/instruments/:instrumentCode/articles भी है, पर यहाँ एक बारीक बात है जो docs में साफ़ लिखी है: यहाँ instrumentCode को असल में state code की तरह लिया जाता है, और state-scoped सूची से नीचे article का कोई अलग breakdown नहीं है।

cURL
curl https://api-b2b.stampmitra.in/v1/estamp/states \
  -H "Authorization: Bearer sk_test_xxxxxxxx"

curl https://api-b2b.stampmitra.in/v1/estamp/states/MH/instruments \
  -H "Authorization: Bearer sk_test_xxxxxxxx"

response के फ़ील्ड docs में प्रकाशित नहीं हैं, इसलिए आगे के कोड में हम उन्हें सीधे अपने sandbox के जवाब से देखकर जोड़ेंगे। मैं यहाँ कोई फ़ील्ड का नाम नहीं गढ़ूँगा।

schema endpoint क्या करता है

GET /v1/estamp/schema/:serviceCode form बनाने के लिए सामान्य metadata देता है। docs बताते हैं कि e-stamp का केवल एक ही schema है, चाहे आप serviceCode में कुछ भी दें; वह पैरामीटर आगे की संगति के लिए रखा गया है। इसलिए अगर आप अपना form dynamic बनाना चाहते हैं तो इसे एक बार मँगवाकर cache कर लें, हर ग्राहक पर नहीं।

चुनाव में गलती कैसे बचाएँ

ग्राहक से कभी खुला text मत भरवाइए जैसे "राज्य: महाराष्ट्र / Maharashtra / MH"। dropdown ही दिखाइए, जिसकी values API से आई हों। कौन सा article किस दस्तावेज़ पर लगता है, यह कानूनी सवाल है। अगर ग्राहक को संदेह है तो उसे अपने वकील या राज्य के stamp विभाग से पूछने को कहें; NyayaDesk चाहे तो इसका एक छोटा सा disclaimer ऐप में रख सकता है।

सूची को स्क्रीन पर कैसे उतारें

state वाली सूची आम तौर पर एक सीधा dropdown बनती है। instrument वाली सूची को उस dropdown के चुने जाने पर ही मँगवाइए, पहले से नहीं। हर राज्य के लिए अलग कॉल होता है, इसलिए पूरे देश की सूची पहले ही खींच लेना न तो ज़रूरी है न समझदारी। ग्राहक जब राज्य बदले तो नीचे की instrument वाली सूची खाली करके नई मँगवाइए, वरना पुराने राज्य का विकल्प नए राज्य के साथ चला जाएगा, और यह सबसे डरावनी गलतियों में से एक है।

अपने ऐप में चुने हुए state code को स्क्रीन पर नाम के साथ भी दिखाइए, ताकि ग्राहक देख सके कि उसने क्या चुना है। भेजी जाने वाली value वही रहे जो API ने दी है।

Step 3: duty calculate करें, और जवाब को हाथ न लगाएँ

यह कदम पूरे flow की रीढ़ है। POST /v1/estamp/duty/calculate के लिए estamp.duty.calculate scope चाहिए। docs इसे "एकमात्र authoritative pricing calculation" कहते हैं, और साफ़ लिखते हैं कि response की रकम को client-side कभी दोबारा निकाला या override नहीं किया जाता। यह call आपके fulfilment wallet से मीटर होती है।

इसका व्यावहारिक मतलब यह है कि आपके कोड में कहीं भी duty = value * rate जैसी लाइन नहीं होनी चाहिए। न अपनी टेबल, न राज्यों की दरों की कॉपी। दरें बदलती हैं, और एक पुरानी कॉपी ग्राहक को गलत रकम दिखा देगी।

cURL
curl -X POST https://api-b2b.stampmitra.in/v1/estamp/duty/calculate \
  -H "Authorization: Bearer sk_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "...": "request body का सही shape /docs/estamp/estamp-duty-value से लें" }'

इस endpoint का request और response body api-products.ts में प्रकाशित नहीं है, इसलिए ऊपर मैंने जानबूझकर body खाली छोड़ा है। duty calculation docs देखें और sandbox में आज़माकर असली फ़ील्ड पक्के करें।

जवाब को कैसे सँभालें

  • response की रकम और service charge जैसी चीज़ें जैसी हैं वैसी ग्राहक को दिखाइए।
  • उसे अपने order के रिकॉर्ड के साथ सहेज लीजिए, ताकि बाद में विवाद हो तो साबित कर सकें कि ग्राहक को क्या दिखाया गया था।
  • ग्राहक के "पुष्टि करें" दबाने तक रुकिए। calculate करना order बनाना नहीं है।
  • कीमत बदल सकती है, इसलिए अगर ग्राहक ने बहुत देर बाद पुष्टि की तो दोबारा calculate कर लें।

कितनी बार calculate करें

हर keystroke पर नहीं। NyayaDesk ने तय किया कि ग्राहक "रकम दिखाओ" बटन दबाएगा तभी calculate होगा। इससे wallet भी बचता है और 429 (rate limit) का खतरा भी घटता है।

duty के जवाब से जुड़े सवाल

लोग अक्सर पूछते हैं कि क्या वे duty की रकम अपने ऐप में थोड़ी गोल करके या अपने सेवा शुल्क के साथ जोड़कर दिखा सकते हैं। दिखाने का फ़ैसला आपका है, पर जो रकम API से आई है उसे बदलकर आगे के किसी कॉल में भेजना या उसके आधार पर अपनी अलग गणना चलाना वह चीज़ है जिससे docs मना करते हैं। अगर आप अपना कोई अतिरिक्त शुल्क लगाते हैं तो उसे स्क्रीन पर अलग पंक्ति में दिखाइए, ताकि ग्राहक को साफ़ दिखे कि कौन सी रकम किसकी है।

एक और सवाल यह आता है कि क्या duty का calculate करना भी बिल में गिना जाता है। docs बताते हैं कि यह call fulfilment wallet से मीटर होती है, इसलिए production में इसे भी अपने खर्च के हिसाब में रखिए। सटीक दर के लिए pricing पेज देखिए, और ऐप के बाहर कभी किसी पुरानी तालिका पर भरोसा मत कीजिए।

Step 4: order बनाएँ और फिर parties जोड़ें

अब असली order। e-stamp का कोई अलग order endpoint नहीं है; आप सामान्य POST /v1/orders इस्तेमाल करते हैं और serviceCode में e-stamp वाला code देते हैं। scope orders.create चाहिए।

फ़ील्डज़रूरी?मतलब
externalOrderIdहाँआपकी अपनी order reference
externalCustomerIdहाँआपकी अपनी ग्राहक reference
serviceCodeहाँcatalog से मिला e-stamp code
detailsनहींfree-form object; e-stamp का shape अभी final नहीं है
Idempotency-Key (header)नहींदोबारा भेजने पर दोहरा order रोकने के लिए
cURL
curl -X POST https://api-b2b.stampmitra.in/v1/orders \
  -H "Authorization: Bearer sk_test_xxxxxxxx" \
  -H "Idempotency-Key: nd_rent_000184-create" \
  -H "Content-Type: application/json" \
  -d '{
    "externalOrderId": "nd_rent_000184",
    "externalCustomerId": "nd_cust_2291",
    "serviceCode": "estamp.instrument.rent_agreement",
    "details": { "state": "MH", "note": "illustrative only" }
  }'

details का सीधा सबक: docs खुद कहते हैं कि e-stamp के लिए कोई पहली श्रेणी का state, article या parties[] फ़ील्ड नहीं है। इसलिए जो भी आप details में भेजें उसे अपने sandbox में जाँचें और अपने कोड में एक ही जगह (एक ही function) में रखें, ताकि shape बदले तो एक ही जगह बदलना पड़े।

Idempotency-Key क्यों काम की है

मान लीजिए ग्राहक का नेटवर्क टूटा और आपका ऐप retry कर बैठा। बिना idempotency key के आपके पास दो order बन सकते हैं। key ऐसी बनाइए जो एक ही "इरादे" के लिए हमेशा एक जैसी रहे, जैसे externalOrderId के साथ -create। हर retry पर नई random key बनाना उसका मकसद ही खत्म कर देता है।

parties जोड़ना

order बनने के बाद POST /v1/estamp/orders/:orderId/parties से पहले और दूसरे पक्ष (और गवाह) की जानकारी जोड़ी या सुधारी जाती है। scope estamp.parties.write, और यह call भी wallet से मीटर होती है। body का shape docs में प्रकाशित नहीं है, इसलिए parties docs देखें। इतना ज़रूर कहा जा सकता है कि यह endpoint "attach या correct" दोनों के लिए है, यानी गलत नाम पर नया order बनाने की ज़रूरत नहीं।

यहाँ PAN या Aadhaar जैसे असली पहचान नंबर लॉग में मत छापिए। अगर पक्षकार की पहचान जाँचनी हो तो PAN verification गाइड देखें।

order और पक्षकार का क्रम

कुछ टीमें सोचती हैं कि पहले पक्षकार जोड़ लें और फिर order बनाएँ। मगर endpoint का रास्ता ही बताता है कि parties एक बने हुए order के नीचे है (/v1/estamp/orders/:orderId/parties)। यानी क्रम तय है: पहले order, फिर पक्षकार। इसी वजह से NyayaDesk अपने ऐप में पक्षकारों का form पहले भरवा लेता है पर उसे सहेजकर रखता है, और order बनते ही तुरंत उसे भेज देता है।

अगर ग्राहक ने नाम में गलती की हो तो सुधार के लिए वही endpoint फिर इस्तेमाल होता है। इसलिए गलती दिखते ही नया order बनाने की जगह पुराने में सुधार भेजिए। पर ध्यान रहे, भुगतान के बाद कितना सुधार हो सकता है यह docs में प्रकाशित नहीं है, इसलिए यह भुगतान से पहले ही करवा लेना सुरक्षित है।

Step 5: payment intent बनाना और उसकी स्थिति देखना

order के बाद भुगतान। POST /v1/payments/intents (scope payments.write) एक payment intent बनाता है, जो docs के अनुसार Razorpay-backed है। यहाँ भी वैकल्पिक Idempotency-Key header है और उसका इस्तेमाल करना अच्छा रहेगा। intent की मौजूदा स्थिति GET /v1/payments/intents/:id से मिलती है (scope payments.read), और किसी order से जुड़ा payment GET /v1/orders/:id/payment से (scope orders.read)।

intent का request और response body भी api-products.ts में विस्तार से नहीं दिया गया, इसलिए payment docs से देखिए कि कौन से फ़ील्ड भेजने हैं। इतना पक्का है कि intent "किसी order के लिए" बनता है।

ऐप में भुगतान का अनुभव

NyayaDesk में "भुगतान करें" बटन दबाने पर ऐप intent बनाता है और ग्राहक को भुगतान के चरण पर भेजता है। लौटने पर ऐप सिर्फ़ ग्राहक के browser के दावे पर भरोसा नहीं करता कि "payment हो गया"; वह GET /v1/orders/:id/payment से server-to-server जाँचता है। यही पुरानी आदत यहाँ भी काम आती है: स्क्रीन पर "success" दिखना और सच में पैसा पहुँचना दो अलग बातें हैं।

payment फेल हो तो

  • पहले intent की स्थिति देखिए, नया intent बनाने की जल्दी मत कीजिए।
  • नया intent तभी बनाएँ जब पुराना साफ़ तौर पर विफल/समाप्त हो।
  • ग्राहक को साफ़ बताइए कि पैसा कटा है या नहीं; अस्पष्ट संदेश से support टिकट बढ़ते हैं।

भुगतान के दो चेहरे

भुगतान के बारे में सोचते समय दो अलग चीज़ें याद रखिए। एक है "payment intent", यानी भुगतान शुरू करने का इरादा, जिसकी अपनी id और अपनी स्थिति है। दूसरा है "order का payment", यानी उस order से जुड़ा हुआ भुगतान रिकॉर्ड। एक order के लिए अपने ऐप में दोनों को साथ-साथ दिखाने की ज़रूरत नहीं, पर अपने डेटाबेस में दोनों की id रखिए ताकि आगे किसी विवाद में आसानी रहे।

भुगतान पूरा होने के बाद ही order आगे बढ़कर दस्तावेज़ बनाने के चरण में जाता है। इसलिए "दस्तावेज़ कहाँ है?" वाला सवाल आम तौर पर या तो भुगतान की स्थिति में अटका होता है या order के आगे बढ़ने के इंतज़ार में। पहले यही दो जाँचें करें।

Step 6: order की स्थिति, और e-stamp certificate डाउनलोड करना

भुगतान के बाद order आगे बढ़ता है। GET /v1/orders/:id पूरा order देता है और GET /v1/orders/:id/status सिर्फ़ मौजूदा lifecycle status। दोनों के लिए orders.read scope चाहिए। यहाँ :id वह id है जो B2B की तरफ़ से order को मिली, आपकी externalOrderId नहीं।

जब order पूरा हो जाए, तब GET /v1/orders/:id/documents generated दस्तावेज़ों की सूची देता है (जैसे e-stamp certificate PDF)। फिर हर दस्तावेज़ के लिए GET /v1/orders/:id/documents/:documentId/download एक (आम तौर पर छोटी अवधि वाला, signed) URL लौटाता है। दोनों के लिए documents.read scope है।

polling या webhook?

webhooks पेज के अनुसार order के event होते हैं, जैसे order.payment_confirmed, order.fulfilment_completed, order.failed और order.document_ready। लेकिन वही पेज इस सुविधा को "Coming soon" बताता है, इसलिए आज के लिए अपने कोड को polling पर टिकाइए और webhook को बाद की योजना मानिए। webhooks पेज पर स्थिति देख लें। polling में हर कुछ सेकंड की जगह धीरे-धीरे बढ़ता अंतराल रखिए (पहले 5 सेकंड, फिर 10, फिर 30) ताकि rate limit न लगे।

signed URL के साथ सावधानी

download URL छोटी अवधि का होता है। उसे डेटाबेस में हमेशा के लिए मत रखिए। ग्राहक जब भी "डाउनलोड" दबाए, तब नया URL माँगिए। और certificate की PDF को अपने storage में रखते समय एक्सेस सीमित रखिए, क्योंकि उसमें पक्षकारों के नाम होते हैं।

status जाँचने की रणनीति

/status endpoint हल्का है, इसलिए polling के लिए वही चुनिए, पूरा order बार-बार मत मँगवाइए। पर status के जो मान लौटते हैं उन्हें docs में सूचीबद्ध नहीं किया गया है। इसलिए अपने sandbox में एक order आख़िर तक चलाकर देखिए कि कौन-कौन से मान आते हैं, और उन्हें अपने कोड में एक ही जगह (एक enum या constants फ़ाइल) में रखिए। अगर किसी नए अनजाने मान पर आपका कोड अटक जाए तो वह "अज्ञात, support से पूछो" वाले रास्ते पर जाए, चुपचाप आगे न बढ़े।

webhook के उदाहरण payload में orderId, externalOrderId और status जैसे फ़ील्ड दिखाए गए हैं, जो इस बात का संकेत हैं कि जब वह सुविधा चालू होगी तो आपकी अपनी reference भी साथ आएगी। पर आज के लिए इस पर निर्भर न रहें।

Node.js और Python में पूरा flow

नीचे दोनों कोड वही रास्ते इस्तेमाल करते हैं जो ऊपर बताए गए हैं। जहाँ response का फ़ील्ड docs में प्रकाशित नहीं है, वहाँ टिप्पणी में लिखा है कि उसे अपने sandbox जवाब से पक्का करें। कुछ भी अंदाज़े से मत चलाइए।

JavaScript
// Node.js 18+ (बिल्ट-इन fetch)
const BASE = "https://api-b2b.stampmitra.in";
const KEY = process.env.STAMPMITRA_API_KEY; // sk_test_... या sk_live_...

async function call(method, path, body, extraHeaders = {}) {
  const res = await fetch(BASE + path, {
    method,
    headers: {
      Authorization: `Bearer ${KEY}`,
      "Content-Type": "application/json",
      ...extraHeaders,
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const data = await res.json();
  if (!res.ok) {
    const e = data.error || {};
    throw new Error(`${res.status} ${e.code}: ${e.message} (requestId=${e.requestId})`);
  }
  return data;
}

async function issueRentStamp(customer) {
  const { services } = await call("GET", "/v1/services");
  const svc = services.find((s) => s.serviceCode.startsWith("estamp.") && s.active);
  if (!svc) throw new Error("e-stamp service entitled नहीं है");

  // duty: body का shape /docs/estamp/estamp-duty-value से लें
  const duty = await call("POST", "/v1/estamp/duty/calculate", customer.dutyRequest);
  // duty की रकम ग्राहक को जैसी है वैसी दिखाएँ; खुद कुछ न निकालें

  const order = await call(
    "POST",
    "/v1/orders",
    {
      externalOrderId: customer.orderRef,
      externalCustomerId: customer.id,
      serviceCode: svc.serviceCode,
      details: customer.details,
    },
    { "Idempotency-Key": `${customer.orderRef}-create` }
  );
  // order की id का फ़ील्ड नाम अपने sandbox response से पक्का करें
  const orderId = order.id ?? order.orderId;

  await call("POST", `/v1/estamp/orders/${orderId}/parties`, customer.parties);
  return { duty, orderId };
}

async function waitAndDownload(orderId) {
  for (const wait of [5, 10, 30, 30, 60]) {
    const st = await call("GET", `/v1/orders/${orderId}/status`);
    console.log("status:", st);
    // पूरा होने की शर्त अपने sandbox के status मानों से तय करें
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
  const docs = await call("GET", `/v1/orders/${orderId}/documents`);
  return docs;
}
Python
import os, time, requests

BASE = "https://api-b2b.stampmitra.in"
HEADERS = {"Authorization": f"Bearer {os.environ['STAMPMITRA_API_KEY']}"}

def call(method, path, json=None, headers=None):
    r = requests.request(method, BASE + path, json=json,
                         headers={**HEADERS, **(headers or {})}, timeout=30)
    data = r.json()
    if not r.ok:
        e = data.get("error", {})
        raise RuntimeError(f"{r.status_code} {e.get('code')}: {e.get('message')} "
                           f"(requestId={e.get('requestId')})")
    return data

def create_order(order_ref, customer_id, service_code, details):
    return call("POST", "/v1/orders", {
        "externalOrderId": order_ref,
        "externalCustomerId": customer_id,
        "serviceCode": service_code,
        "details": details,
    }, headers={"Idempotency-Key": f"{order_ref}-create"})

def poll_status(order_id):
    for wait in (5, 10, 30, 30, 60):
        st = call("GET", f"/v1/orders/{order_id}/status")
        print("status:", st)
        time.sleep(wait)

ज़्यादा तैयार लाइब्रेरी चाहिए तो SDKs पेज देखें, और Postman में आज़माना हो तो Postman collection है।

गलतियाँ जो टीमें सबसे देर से पकड़ती हैं

कुछ गलतियाँ तुरंत नहीं दिखतीं। जैसे: ऐप में wallet की कमी का 402 आने पर ग्राहक को "तकनीकी समस्या" दिखा देना। असल में यह आपकी तरफ़ की बात है, ग्राहक की नहीं, इसलिए उसे आंतरिक चेतावनी के रूप में अपनी टीम तक पहुँचाइए और ग्राहक को सिर्फ़ "थोड़ी देर बाद कोशिश करें" बताइए। एक और: 502 आने पर तुरंत नया order बनाना। यह कॉल शायद बीच में कहीं पूरा हो चुका हो, इसलिए पहले externalOrderId से अपना रिकॉर्ड देखिए और idempotency key वही रखकर दोबारा भेजिए।

तीसरी देर से पकड़ी जाने वाली गलती: test और live के environment variables का घालमेल। इससे बचने का सबसे सीधा तरीका है कि कोड शुरू होते ही key का prefix पढ़कर लॉग में लिख दें कि आप किस environment में हैं।

आम गलतियाँ और जब कुछ अटक जाए

नीचे की तालिका में वही errors हैं जो docs के common examples में दिखाए गए हैं। ध्यान दें कि e-stamp पेजों पर हर endpoint का अलग errors सेट प्रकाशित नहीं है, इसलिए ये सामान्य, पूरी API वाले नतीजे हैं।

HTTPcodeआम कारणक्या करें
400BAD_REQUESTbody में गलत या कमी वाला फ़ील्ड, या service entitled नहींmessage पढ़ें, body जाँचें
401UNAUTHORIZEDkey गलत/गायबheader और key का environment देखें
402PAYMENT_REQUIREDfulfilment wallet में पर्याप्त balance नहींwallet भरें, फिर retry
403FORBIDDENkey सही पर scope नहींkey में ज़रूरी scope जोड़ें
404NOT_FOUNDगलत id या pathexternalOrderId की जगह असली :id इस्तेमाल करें
429TOO_MANY_REQUESTSrate limit या sandbox quotaरुककर, बढ़ते अंतराल से retry
502INTERNAL_ERRORपीछे की सेवा तक पहुँच नहींथोड़ी देर बाद retry, requestId सँभालें

सबसे आम चूकें

पहली, duty को अपने कोड में दोबारा निकालना। दूसरी, externalOrderId को URL के :id की जगह भेज देना; वह आपकी reference है, B2B की id नहीं। तीसरी, हर retry पर नई Idempotency-Key बनाना। चौथी, एक ही key को पूरी अनुमति दे देना। पाँचवीं, 401 और 403 को एक ही मान लेना: 401 का मतलब पहचान नहीं हुई, 403 का मतलब पहचान हुई पर इजाज़त नहीं।

troubleshooting क्रम

अटकने पर इसी क्रम में जाँचिए। एक, key का environment (test या live)। दो, scope। तीन, catalog में serviceCode active है या नहीं। चार, wallet (सिर्फ़ production)। पाँच, rate limit। छह, error का requestId लेकर support या [email protected] पर लिखिए। सभी errors के सँभालने का तरीका API errors गाइड में विस्तार से है।

बीच में process मर जाए तो recovery और मिलान (reconciliation) कैसे करें?

असली दुनिया में आपका सर्वर किसी भी कदम के बीच मर सकता है: deploy हो गया, मशीन restart हुई, या नेटवर्क ने साथ छोड़ दिया। e-stamp flow में कई अलग कॉल होते हैं, इसलिए पहले से तय रखिए कि हर जगह रुकने पर क्या होगा। इसका सबसे सीधा उपाय यह है कि आप हर order के लिए अपने डेटाबेस में एक छोटी स्थिति-तालिका रखें और हर कॉल से पहले और बाद में उसे अपडेट करें।

तीन खतरनाक जगहें

पहली जगह: order बन गया, पर आपका सर्वर जवाब मिलने से पहले मर गया। आपके रिकॉर्ड में order "बनाया जा रहा है" की हालत में अटका है। यहाँ नया order मत बनाइए। वही externalOrderId और वही Idempotency-Key लेकर POST /v1/orders दोबारा भेजिए। idempotency key का मकसद ही यही है कि दोबारा भेजने पर दोहरा order न बने। अगर आपके पास B2B की order id पहुँच चुकी थी तो सीधे GET /v1/orders/:id से देखिए कि order सचमुच बना है या नहीं।

दूसरी जगह: order बना, पर पक्षकार जुड़ने से पहले process मर गया। यह सबसे आसान स्थिति है क्योंकि parties का endpoint "जोड़ने या सुधारने" दोनों के लिए है। वही जानकारी फिर भेज दीजिए, कुछ बिगड़ेगा नहीं, यानी आपका recovery कोड बस यह देखे कि order का रिकॉर्ड तो है पर "पक्षकार जुड़े" का झंडा नहीं लगा।

तीसरी जगह: payment intent बना या ग्राहक ने भुगतान शुरू किया, पर आपका ऐप बीच में गिर गया। यहाँ सबसे ज़्यादा सावधानी चाहिए। नया intent बनाने से पहले GET /v1/orders/:id/payment से देखिए कि इस order का भुगतान पहले से किस हालत में है, और पुराने intent की स्थिति GET /v1/payments/intents/:id से जाँचिए। जब तक स्थिति साफ़ न हो, ग्राहक से दोबारा भुगतान मत करवाइए, वरना दोहरा भुगतान हो सकता है।

recovery के लिए एक छोटा background job

एक job हर कुछ मिनट पर चलाइए जो आपकी तालिका में उन orders को ढूँढे जो पिछले कुछ मिनट से किसी बीच की स्थिति में अटके हैं। हर ऐसे order के लिए वह उसी क्रम में पूछताछ करे: order, फिर payment, फिर status, फिर documents। job को हर बार बस एक कदम आगे बढ़ाना चाहिए और अपनी जानकारी API के जवाब से ताज़ा करनी चाहिए, अपने अंदाज़े से नहीं। इसके साथ यह भी तय कीजिए कि कितनी कोशिशों के बाद order को "इंसान देखे" वाली कतार में डाल देना है, ताकि कोई order हमेशा के लिए चुपचाप न अटका रहे।

worked example: NyayaDesk की रात की मिलान प्रक्रिया

NyayaDesk हर रात एक मिलान चलाता है। उसकी अपनी तालिका में दिन भर के जो orders हैं (मान लीजिए nd_rent_000184 से आगे के), उन्हें वह एक-एक करके API से मिलाता है। हर order के लिए वह externalOrderId के साथ जुड़ी B2B id से GET /v1/orders/:id/status पूछता है और अपनी स्थिति से तुलना करता है।

तीन तरह के फ़र्क निकलते हैं। पहला: उनके यहाँ "भुगतान बाकी" लिखा है पर API में भुगतान हो चुका है। तब वे अपना रिकॉर्ड सुधारते हैं और आगे का काम जारी करते हैं। दूसरा: उनके यहाँ "पूरा" लिखा है पर documents की सूची में कुछ नहीं। तब वे इसे अधूरा मानकर एक चेतावनी बनाते हैं और अगली सुबह support को सौंपते हैं। तीसरा: API में कोई order है जिसकी उनके डेटाबेस में कोई entry नहीं। यह सबसे गंभीर फ़र्क है, क्योंकि इसका मतलब है कि बनाने के बाद उनका रिकॉर्ड बना ही नहीं। इसे सुलझाने के लिए वे requestId, समय और externalOrderId लेकर [email protected] पर लिखते हैं।

इस पूरी प्रक्रिया की खूबी यह है कि वह हमेशा API को सच का स्रोत मानती है और अपने डेटाबेस को उसके हिसाब से सुधारती है। दूसरी तरफ़ नहीं।

ग्राहक-सहायता की छोटी पुस्तिका

सहायता टीम के लिए तीन-चार जवाब तैयार रखिए। "मेरा पैसा कटा पर दस्तावेज़ नहीं आया": टीम पहले order और payment की स्थिति देखे, फिर documents की सूची। अगर स्थिति अभी चल रही है तो ग्राहक से इंतज़ार करने को कहे। "मेरे नाम में गलती है": parties वाला endpoint सुधार के लिए है, पर भुगतान के बाद कितना सुधार संभव है यह docs में प्रकाशित नहीं, इसलिए support से पूछिए। "डाउनलोड लिंक काम नहीं कर रहा": signed URL की अवधि निकल गई होगी, नया URL माँगिए। हर मामले में टीम के पास ग्राहक की order reference और requestId होने चाहिए।

कब e-stamp API इस्तेमाल करें, कब नहीं?

API तब सही बैठती है जब stamp paper आपके उत्पाद का हिस्सा हो और बार-बार जारी करना पड़े। जैसे NyayaDesk जैसा ऐप, कोई property-tech प्लेटफ़ॉर्म जहाँ किराये के करार बनते हैं, या कोई वकीलों की practice-management टूल जहाँ क्लाइंट के दस्तावेज़ों के साथ stamp भी चाहिए।

स्थितिAPI सही?कारण
महीने में सैकड़ों agreements, ऐप में ही चाहिएहाँautomation, एक ही dashboard
ग्राहक का हर चरण अपने UI में चाहिएहाँstate/instrument dropdown API से
साल में एक-दो बार खुद का एक agreementशायद नहींमैन्युअल रास्ता ज़्यादा सरल है
आप दरों की अपनी टेबल रखना चाहते हैंनहींduty सिर्फ़ server निकालता है
आपको कानूनी सलाह चाहिए कि कौन सा article लगेनहींAPI सलाह नहीं देती, वकील से पूछें
details का पक्का contract चाहिए अभीसावधानीshape अभी final नहीं है

अगर आपकी ज़रूरत सिर्फ़ पहचान जाँचने की है तो e-stamp नहीं, verification products देखें।

सुरक्षा, डेटा और compliance की बातें

e-stamp order में लोगों के नाम, पते और कई बार पहचान की जानकारी होती है। Digital Personal Data Protection Act, 2023 के संदर्भ में सामान्य अच्छी आदतें ये हैं: सहमति लेकर ही डेटा लें, जिस मकसद के लिए लिया उसी के लिए इस्तेमाल करें, और ज़रूरत से ज़्यादा समय तक न रखें। मैंने इस अधिनियम के किसी खास अनुच्छेद की संख्या यहाँ इसलिए नहीं दी कि वह स्रोत इस सत्र में खोलकर जाँची नहीं जा सकी; अपने वकील से ताज़ा नियम पक्के करें।

key की सुरक्षा

  • API key कभी browser या मोबाइल ऐप के कोड में न रखें। कॉल हमेशा आपके server से जाएँ।
  • key को environment variable या secret manager में रखें, git में नहीं।
  • हर काम के लिए कम से कम scope वाली अलग key।
  • संवेदनशील scopes पर IP allowlist लगाएँ, जैसा API key docs बताते हैं।
  • लीक का शक हो तो key तुरंत बदलें।

डेटा की न्यूनतम रखाई

लॉग में पूरी request body मत छापिए। requestId, order id और status काफ़ी हैं। sandbox में असली ग्राहकों का डेटा न डालें; StampMitra की developer privacy policy में sandbox डेटा पर भी यही सुझाव है कि काल्पनिक या anonymised डेटा रखें। इस्तेमाल की शर्तों के लिए API acceptable use policy, API security policy और data processing addendum पढ़ लें।

ग्राहक को क्या दिखाएँ

ग्राहक को बताइए कि stamp paper जारी करना एक कानूनी प्रक्रिया है, और StampMitra का API सिर्फ़ तकनीकी माध्यम है। कोई वादा न करें कि दस्तावेज़ हर हाल में मान्य होगा।

sandbox में टेस्टिंग और production तक का रास्ता

पहले sandbox में पूरा flow चलाइए। sk_test_ key से हर कदम आज़माइए: catalog, state, duty, order, parties, payment, documents। sandbox की calls मीटर होती हैं पर wallet नहीं कटता। कोटा के बारे में ध्यान रखें: docs में sandbox के लिए quota का ज़िक्र है और उसे पार करने पर साफ़ 429 मिलता है। quota की सटीक मात्रा के शब्द अलग पेजों पर अलग हैं, इसलिए अपना असली कोटा अपने dashboard में देखिए।

जाँच-सूची sandbox के लिए

  1. हर endpoint का 401, 403, 404 और 429 रास्ता जानबूझकर चलाकर देखें।
  2. वही Idempotency-Key दो बार भेजकर देखें कि दोहरा order नहीं बनता।
  3. बीच में नेटवर्क काटकर retry का व्यवहार जाँचें।
  4. status polling का अंतराल बढ़ाकर देखें कि rate limit नहीं लगता।
  5. download URL की अवधि निकलने पर नया URL माँगने का रास्ता चलाएँ।

production में जाना

production की key और entitlement अलग हैं। docs के अनुसार sandbox में पहुँच production से अलग हो सकती है, sandbox में सब ठीक चलना production मंज़ूरी की गारंटी नहीं, और sandbox का व्यवहार production के बराबर मान लेना ठीक नहीं। जाने से पहले sk_live_ key अलग बनाइए, wallet में पर्याप्त balance रखिए, और सारे environment variables अलग रखिए ताकि गलती से test key production में न चले। onboarding verification नीति भी एक बार पढ़ लें। शुरुआत छोटे ट्रैफ़िक से कीजिए, फिर बढ़ाइए।

StampMitra आपकी कैसे मदद करता है

StampMitra Bani Global Industries LLP (LLPIN ACI-6373) द्वारा संचालित एक निजी LegalTech प्लेटफ़ॉर्म है। यह सरकारी संस्था या law firm नहीं है, और इसका API कानूनी सलाह नहीं देता। आज की तारीख में StampMitra Developers आपको जो सचमुच देता है वह यह है: e-stamp का catalog (/v1/services), state, instrument और article की खोज, एक authoritative duty calculation, सामान्य orders API के ज़रिये e-stamp order, parties जोड़ने का endpoint, Razorpay-backed payment intent, और पूरा होने पर documents की सूची तथा signed download URL।

आपके लिए इसका फ़ायदा यह है कि NyayaDesk जैसा कोई भी ऐप अलग-अलग पोर्टल पर कर्मचारी भेजे बिना यह काम अपने भीतर कर सकता है। हर call पर requestId मिलता है जिससे support के साथ बातचीत छोटी हो जाती है। sandbox में बिना wallet कटे सब कुछ आज़माया जा सकता है, और pricing पेज पर साफ़ दर दिखती है।

कुछ बातें साफ़ बता देना ज़रूरी है। e-stamp के details का shape अभी final नहीं है, इसलिए उसे बदलाव के लिए तैयार रखिए। webhooks अभी "Coming soon" हैं, इसलिए आज polling ही रास्ता है। हम कुछ भी मंज़ूरी की गारंटी या किसी राज्य के विभाग की तरफ़ से नहीं कहते।

आगे की योजना (सिर्फ़ योजना, वादा नहीं): webhooks का आम उपलब्धता तक पहुँचना, e-stamp के लिए पहली श्रेणी के state, article और parties[] फ़ील्ड, और बेहतर SDK/Postman समर्थन। इन पर नज़र रखने के लिए docs, webhooks और MCP पेज देखते रहिए। शुरू करना हो तो signup कीजिए और quickstart से पहला कॉल चलाइए। सवाल हों तो [email protected] पर लिखिए, या contact पेज देखिए। AI टूल के साथ बनाना चाहें तो Build with AI भी है।

API reference एक नज़र में

e-Stamp Order Creation: paramsPOST /v1/orders

Request parameters

Request parameters
FieldTypeDescription
AuthorizationrequiredheaderBearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted.
Idempotency-KeyheaderOptional idempotency key.
externalOrderIdrequiredstringYour own reference for this order.
externalCustomerIdrequiredstringYour own reference for the customer.
serviceCoderequiredstringThe entitled service to order (e.g. an estamp.* code).
detailsobjectFree-form service-specific payload (e-Stamp field shape is not finalized).
e-Stamp Order Creation: responsePOST /v1/orders
{
  "externalOrderId": "ord_ext_123",
  "createdAt": "2026-10-15T09:41:07.000Z",
  "serviceCode": "estamp.instrument.rent_agreement"
}
e-Stamp Order Creation: pricePOST /v1/orders

e-Stamp Order Creation: ₹5 API fee per successful call, pay-as-you-go (lower on Growth and Scale).

Payment: paramsPOST /v1/payments/intents

Request parameters

Request parameters
FieldTypeDescription
AuthorizationrequiredheaderBearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted.
Idempotency-KeyheaderOptional idempotency key.
externalOrderIdrequiredstringYour reference for the order being paid.
amountMinorrequiredintegerAmount in minor units (paise); positive integer.
currencyrequiredstringCurrency code, at least 3 characters, e.g. INR.
paymentConnectionIdrequiredstringId of one of your active payment connections.
Payment: responsePOST /v1/payments/intents
{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "externalOrderId": "ord_ext_123",
  "coreOrderId": null,
  "amountMinor": 50000,
  "currency": "INR",
  "status": "CREATED",
  "providerIntentId": "order_Nf3k2m9QxPz1Ab",
  "createdAt": "2026-10-15T09:41:07.000Z"
}
Payment: pricePOST /v1/payments/intents

Payment: ₹5 API fee per successful call, pay-as-you-go (lower on Growth and Scale).

Order Status & Document Access: paramsGET /v1/orders/:id/documents

Request parameters

Request parameters
FieldTypeDescription
AuthorizationrequiredheaderBearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted.
Order Status & Document Access: priceGET /v1/orders/:id/documents

Order Status & Document Access: ₹5 API fee per successful call, pay-as-you-go (lower on Growth and Scale).

अक्सर पूछे जाने वाले सवाल

e-stamp paper API से मैं क्या-क्या कर सकता हूँ?

आप उपलब्ध services का catalog देख सकते हैं, राज्य और instrument खोज सकते हैं, duty calculate करवा सकते हैं, order बना सकते हैं, पक्षकार जोड़ सकते हैं, payment intent बना सकते हैं और पूरा होने पर certificate PDF का download URL ले सकते हैं।

e-stamp API का base URL और authentication क्या है?

Base URL https://api-b2b.stampmitra.in है। हर request में Authorization: Bearer <api-key> header जाता है, या x-api-key header भी चलता है। sandbox की key sk_test_ से और production की key sk_live_ से शुरू होती है।

क्या मैं stamp duty की रकम अपने कोड में खुद निकाल सकता हूँ?

नहीं। POST /v1/estamp/duty/calculate ही एकमात्र authoritative गणना है और docs के अनुसार उसकी रकम client-side कभी दोबारा निकाली या बदली नहीं जाती। दरें राज्य और instrument के हिसाब से बदलती हैं, इसलिए हमेशा API का जवाब इस्तेमाल करें।

e-stamp order कैसे बनता है?

e-stamp का अलग order endpoint नहीं है। आप सामान्य POST /v1/orders में externalOrderId, externalCustomerId और e-stamp का serviceCode भेजते हैं, और ज़रूरी विवरण वैकल्पिक details object में रखते हैं। इसके लिए orders.create scope चाहिए।

Idempotency-Key क्यों लगानी चाहिए?

नेटवर्क टूटने पर retry से दोहरा order या दोहरा payment बन सकता है। एक ही इरादे के लिए हमेशा एक जैसी Idempotency-Key भेजने से यह खतरा घटता है। orders और payment intents दोनों में यह वैकल्पिक header उपलब्ध है।

e-stamp certificate कैसे डाउनलोड होता है?

order पूरा होने पर GET /v1/orders/:id/documents दस्तावेज़ों की सूची देता है, और GET /v1/orders/:id/documents/:documentId/download एक आम तौर पर छोटी अवधि वाला signed URL देता है। दोनों के लिए documents.read scope चाहिए।

क्या e-stamp के लिए webhooks उपलब्ध हैं?

webhooks पेज पर order.document_ready और order.fulfilment_completed जैसे events का वर्णन है, पर उस सुविधा को अभी Coming soon बताया गया है। आज के लिए order की स्थिति GET /v1/orders/:id/status से polling करके जाँचें।

sandbox में test करने पर क्या wallet से पैसे कटते हैं?

नहीं, docs के अनुसार sandbox calls मीटर और log होती हैं पर आपके wallet से नहीं कटतीं। production में दाम वाली calls fulfilment wallet से कटती हैं, और balance कम हो तो 402 PAYMENT_REQUIRED मिलता है।

मुझे 403 FORBIDDEN मिले तो क्या करूँ?

403 का मतलब है कि key सही है पर उसमें उस endpoint का scope नहीं है। जैसे duty के लिए estamp.duty.calculate, parties के लिए estamp.parties.write और documents के लिए documents.read चाहिए। key में सही scope जोड़कर दोबारा कोशिश करें।

क्या StampMitra की API कानूनी सलाह या अदालत में मान्यता की गारंटी देती है?

नहीं। StampMitra एक निजी LegalTech प्लेटफ़ॉर्म है, सरकारी एजेंसी या law firm नहीं। API तकनीकी माध्यम है। कौन सा article लगेगा या दस्तावेज़ कैसे स्वीकार होगा, यह अपने वकील या राज्य के stamp विभाग से पक्का करें।

स्रोत

  • StampMitra Developers, e-stamp API reference: /docs/estamp और उसके उप-पेज (catalog, schema, state-instrument-article, duty-value, parties, orders, payment, documents), 2026-10-16 को जाँचा गया।
  • StampMitra Developers, API key authentication: /docs/auth, 2026-10-16।
  • StampMitra Developers, webhooks: /webhooks (स्थिति: Coming soon), 2026-10-16।
  • StampMitra Developers, pricing: /pricing, 2026-10-16।
  • Digital Personal Data Protection Act, 2023 (MeitY / भारत सरकार): सामान्य संदर्भ के तौर पर; इस सत्र में आधिकारिक पाठ खोला नहीं जा सका, इसलिए कोई अनुच्छेद संख्या उद्धृत नहीं की गई।
  • राज्य stamp विभाग और SHCIL के आधिकारिक पोर्टल: दरों और नियमों की ताज़ा जानकारी के लिए सीधे वहीं देखें; इस सत्र में ये पेज खोलकर सत्यापित नहीं हुए।