अगर आप किसी प्रॉपर्टी ऐप के लिए रेंट एग्रीमेंट ई-स्टांप API जोड़ना चाहते हैं, तो StampMitra की API में इसका रास्ता एक तय क्रम में चलता है: पहले आपकी organization के लिए entitled e-stamp service देखी जाती है, फिर state और article की जानकारी से फ़ॉर्म बनता है, फिर POST /v1/orders से order बनता है, उसके बाद उसी order के orderId पर parties जुड़ती हैं, और आख़िर में payment होकर certificate document मिलता है।
इस गाइड में हम एक काल्पनिक ब्रोकर ऐप "GharSaathi" के सहारे चलेंगे, जिसमें किरायेदार का onboarding होता है और ऐप को रेंट एग्रीमेंट का e-stamp हर बार हाथ से नहीं कटवाना पड़ता। यहाँ बताए सारे endpoint, scope और header src/data/api-products.ts में दर्ज दस्तावेज़ से लिए गए हैं।
एक बात शुरू में ही साफ़ कर दें। e-stamp के कई endpoint (schema, states, duty calculate, parties, payment intent, status, documents) के request और response body अभी publicly दस्तावेज़ में नहीं हैं। इसलिए जहाँ body दिखाई गई है, वहाँ उसे साफ़ शब्दों में "placeholder" लिखा गया है। उसे असली contract न मानें। स्टैंप ड्यूटी की कोई राशि यहाँ नहीं लिखी गई, क्योंकि नियम राज्य-दर-राज्य अलग हैं और सही आँकड़ा API का duty calculate endpoint देता है।
मुख्य बातें
- e-stamp का documented क्रम है: order बनाना, फिर parties (इसके लिए
orderIdचाहिए), फिर payment, फिर status देखकर documents लेना। - Base URL
https://api-b2b.stampmitra.inहै और हर कॉल मेंAuthorization: Bearer <api-key>(याx-api-key) लगता है। sandbox keysk_test_...और production keysk_live_...होती है। - हर endpoint का अपना scope है:
services.read,estamp.read,estamp.duty.calculate,orders.create,estamp.parties.write,payments.write,orders.read,documents.read। scope कम हुआ तो403 FORBIDDENआता है। POST /v1/ordersएक generic endpoint है। e-stamp के लिएserviceCode(जैसेestamp.instrument.rent_agreement) और free-formdetailsभेजा जाता है, और इसdetailsका आकार अभी तय नहीं है।- duty की राशि आपके ऐप में कभी अपने आप नहीं निकालनी है। API का duty calculate जवाब ही आख़िरी माना जाता है।
- stamp duty और रजिस्ट्रेशन के नियम राज्य के हिसाब से बदलते हैं। अपने मामले में क्या लागू होता है, यह किसी योग्य वकील या संबंधित राज्य के स्टांप विभाग से पक्का करें।
- हर error का आकार एक ही है:
{ "error": { "code", "message", "requestId" } }। support को लिखते समयrequestIdज़रूर भेजें। Idempotency-Keyheader order बनाने और payment intent बनाने, दोनों पर optional है, पर दोबारा retry वाले ऐप में इसे लगाना समझदारी है।
GharSaathi की कहानी: एक किरायेदार, एक ऐप, एक एग्रीमेंट
मान लीजिए GharSaathi नाम का एक छोटा ब्रोकर ऐप है। यह नाम और कंपनी पूरी तरह काल्पनिक है, बस समझाने के लिए। ऐप में एक फ़्लैट का मालिक अपनी प्रॉपर्टी डालता है, ब्रोकर उसे किरायेदार से मिलवाता है, और बात पक्की होते ही ऐप को रेंट एग्रीमेंट की तैयारी करनी होती है।
पहले यह काम व्हाट्सऐप पर चलता था। किरायेदार से आधार की फ़ोटो माँगी जाती, मालिक से बैंक डिटेल, फिर कोई एजेंट किसी स्टांप वेंडर के पास जाता। हर चरण में देरी होती थी और आधी जानकारी बार-बार पूछनी पड़ती थी। ऐप के founder ने तय किया कि onboarding के आख़िरी पन्ने पर "रेंट एग्रीमेंट तैयार करें" का बटन होगा, और उसके पीछे StampMitra की API चलेगी।
यहाँ एक अच्छी बात यह है कि e-stamp का हर चरण ऐप की किसी स्क्रीन से जुड़ जाता है। किरायेदार जब राज्य चुनता है, तब states endpoint काम आता है। जब मालिक और किरायेदार के नाम भरे जाते हैं, तब parties endpoint। जब "भुगतान करें" दबता है, तब payment intent। और जब ऐप के "मेरे दस्तावेज़" पन्ने में PDF दिखना है, तब documents endpoint। यानी आपको API को अलग से समझने की बजाय अपनी स्क्रीन का क्रम देखना है, और हर स्क्रीन के पीछे एक कॉल बैठा देनी है।
इस गाइड में आगे यही क्रम चलेगा। हर चरण में हम बताएँगे कि कौन-सा endpoint है, कौन-सा scope चाहिए, कहाँ body documented है और कहाँ नहीं, और ग़लती होने पर क्या दिखेगा। अगर आप पहले सिर्फ़ order के ढाँचे को छोटे रूप में पढ़ना चाहते हैं, तो e-stamp API order flow की गाइड अलग से मौजूद है।
यह गाइड किसके लिए है
यह उन डेवलपर्स के लिए है जो किसी ब्रोकर ऐप, प्रॉपर्टी मैनेजमेंट टूल, को-लिविंग प्लेटफ़ॉर्म या किराया-संग्रह ऐप में रेंट एग्रीमेंट का e-stamp जोड़ना चाहते हैं। अगर आप एक बार का एग्रीमेंट खुद बनवा रहे हैं, तो API की ज़रूरत नहीं है। API तब काम की है जब आपके पास हर महीने कई किरायेदार आते हैं और आप चाहते हैं कि प्रक्रिया ऐप के अंदर ही पूरी हो।
एक दिन की झलक: ऑनबोर्डिंग के पीछे क्या चलता है
सुबह दस बजे GharSaathi का एक ब्रोकर, मान लीजिए रेखा, अपने फ़ोन पर एक नया किरायेदार जोड़ती है। ऐप तुरंत सर्वर से पूछता है कि इस खाते पर रेंट एग्रीमेंट वाली service चालू है या नहीं। चालू है, इसलिए "एग्रीमेंट तैयार करें" का बटन दिखता है। किरायेदार राज्य चुनता है, ऐप उसी राज्य के विकल्प मँगवाकर दिखाता है, और जब बाकी ब्योरा भर जाता है तब लागत का अनुमान स्क्रीन पर आता है।
दोपहर तक मकान मालिक और किरायेदार, दोनों अपने नाम और ज़रूरी जानकारी ऐप में भर चुके होते हैं। शाम को भुगतान होता है और अगली सुबह रेखा के ऐप में "मेरे दस्तावेज़" में PDF दिखती है। रेखा ने इस बीच किसी स्टांप वेंडर को फ़ोन नहीं किया, और किरायेदार को किसी दफ़्तर के चक्कर नहीं लगाने पड़े। यह कहानी काल्पनिक है, पर इसमें हर क़दम किसी न किसी endpoint से जुड़ता है, और वही जुड़ाव आपको अपने डिज़ाइन में सबसे पहले तय करना चाहिए।
इंटीग्रेशन से पहले अपनी टीम से पूछने लायक़ सवाल
कोड लिखने से पहले तीन सवाल हल कर लीजिए। पहला, आपके ऐप में किरायेदार का डेटा कहाँ रखा जाता है और उसे StampMitra को भेजने की सहमति किस स्क्रीन पर ली जाती है? दूसरा, भुगतान का बोझ किसके पास रहेगा, ग्राहक के पास या आपके wallet पर? तीसरा, अगर e-stamp बनने में देर हो जाए तो ग्राहक को क्या दिखेगा? इन तीनों के जवाब तय हों तो बाक़ी इंटीग्रेशन सीधा है।
शुरू करने से पहले: API key, scope और sandbox
e-stamp की कॉल करने से पहले तीन चीज़ें तैयार चाहिए: एक API key, उस key पर सही scopes, और production के लिए entitlement। हर protected endpoint पर Authorization: Bearer <key> या x-api-key: <key> header लगता है, और यह API key authentication की docs में लिखा है।
sandbox key से शुरुआत
साइन-अप के बाद आपको तुरंत sk_test_... से शुरू होने वाली sandbox key मिलती है। pricing पेज के अनुसार sandbox में test-mode कॉल sandbox डेटा पर असीमित हैं। इसलिए पहले पूरा फ़्लो sandbox पर चलाएँ, अपने ऐप की हर स्क्रीन जोड़ें, और तभी production का सोचें। sandbox और production key का अंतर विस्तार से sandbox बनाम production key की गाइड में है।
Production की sk_live_... key तभी असली काम करती है जब आपकी organization के पास e-stamp का production entitlement हो। दस्तावेज़ के अनुसार पूरा e-stamp हिस्सा एक ही service code estamp पर gate होता है, यानी duty, parties और order, सब एक ही entitlement के तहत मीटर होते हैं।
scopes की सूची
Key बनाते समय हर काम के लिए अलग scope देना पड़ता है। यह ज़रूरी है कि आप key को उतने ही scope दें जितने की ज़रूरत है। नीचे की तालिका दस्तावेज़ में दिए endpoint और उनके scope का मिलान है।
| काम | Method और path | Scope |
|---|---|---|
| entitled services देखना | GET /v1/services | services.read |
| schema, states, instruments, articles | GET /v1/estamp/... | estamp.read |
| duty calculate | POST /v1/estamp/duty/calculate | estamp.duty.calculate |
| order बनाना | POST /v1/orders | orders.create |
| parties जोड़ना | POST /v1/estamp/orders/:orderId/parties | estamp.parties.write |
| payment intent बनाना | POST /v1/payments/intents | payments.write |
| payment intent देखना | GET /v1/payments/intents/:id | payments.read |
| order, status, payment | GET /v1/orders/:id आदि | orders.read |
| documents | GET /v1/orders/:id/documents | documents.read |
यह भी याद रखें कि docs के अनुसार संवेदनशील scopes पर IP allowlist लगाया जा सकता है। अगर आपका ऐप किसी fixed server से कॉल करता है, तो यह एक अच्छी सुरक्षा परत है।
Base URL और wallet
सभी कॉल https://api-b2b.stampmitra.in पर जाती हैं। duty calculate और parties जैसे endpoint आपके "fulfilment wallet" के विरुद्ध मीटर होते हैं, यानी दस्तावेज़ में इन्हें metered कहा गया है। wallet में पैसे कम हों तो 402 PAYMENT_REQUIRED मिलता है, जिसके बारे में troubleshooting वाले हिस्से में आगे बात होगी। हर कॉल की कीमत के लिए हमेशा pricing पेज देखें, इस लेख में कोई कीमत नहीं लिखी गई।
पूरा क्रम एक नज़र में: कौन-सी कॉल कब
सबसे ज़्यादा भ्रम इसी बात पर होता है कि parties पहले जोड़ें या order पहले बनाएँ। दस्तावेज़ का उत्तर साफ़ है: parties वाला endpoint /v1/estamp/orders/:orderId/parties है, यानी उसे चलाने के लिए order पहले से मौजूद होना चाहिए। इसलिए क्रम यह है: order, फिर parties, फिर payment।
इसे GharSaathi की स्क्रीन के साथ जोड़कर देखें।
| चरण | ऐप की स्क्रीन | API कॉल | body की स्थिति |
|---|---|---|---|
| 1 | ऐप शुरू होना | GET /v1/services | response का उदाहरण documented है |
| 2 | राज्य और दस्तावेज़ का प्रकार चुनना | GET /v1/estamp/schema/:serviceCode, .../states, .../states/:stateCode/instruments | body documented नहीं |
| 3 | लागत दिखाना | POST /v1/estamp/duty/calculate | body documented नहीं |
| 4 | "आगे बढ़ें" दबाना | POST /v1/orders | request documented, details का आकार तय नहीं |
| 5 | मालिक और किरायेदार के नाम | POST /v1/estamp/orders/:orderId/parties | body documented नहीं |
| 6 | भुगतान | POST /v1/payments/intents | body documented नहीं |
| 7 | प्रतीक्षा और PDF | GET /v1/orders/:id/status, .../documents, .../documents/:documentId/download | body documented नहीं |
अब हर चरण को एक-एक करके देखते हैं।
चरण 1: मेरे पास कौन-सी e-stamp service है?
सबसे पहली कॉल आपके ऐप को बताती है कि आपकी organization किन services के लिए entitled है। e-stamp के लिए कोई अलग catalog endpoint नहीं है। docs साफ़ कहते हैं कि e-stamp के instruments इसी generic GET /v1/services में आम service entries की तरह दिखते हैं, जब तक आप उनके लिए entitled हों।
curl -X GET "https://api-b2b.stampmitra.in/v1/services" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY"दस्तावेज़ में दिया गया response का उदाहरण यह है:
{
"services": [
{ "serviceCode": "estamp.instrument.rent_agreement", "name": "Rent Agreement e-Stamp", "active": true }
]
}यहाँ serviceCode वही मान है जो आगे POST /v1/orders में जाएगा। इसे अपने कोड में hardcode मत कीजिए। ऐप शुरू होते समय (या हर कुछ घंटे में) यह सूची खींचकर active: true वाली entries से "रेंट एग्रीमेंट" बटन चालू या बंद कीजिए। अगर service सूची में नहीं है, तो समझिए आपकी key के पास उसका entitlement नहीं है, और उस हाल में ऑर्डर बनाना व्यर्थ है।
एक ही service की अलग से जानकारी चाहिए हो तो GET /v1/services/:serviceCode (वही services.read scope) है, जो entitled और active होने पर उस एक service का detail देती है।
GharSaathi में इसका उपयोग
ऐप के onboarding पन्ने पर "रेंट एग्रीमेंट e-stamp" का कार्ड तभी दिखता है जब सूची में estamp.instrument.rent_agreement active हो। इससे एक ऐसा मामला बच जाता है जहाँ किरायेदार पूरा फ़ॉर्म भर दे और आख़िर में पता चले कि आपके खाते पर यह service चालू ही नहीं है।
चरण 2: राज्य, instrument और article से फ़ॉर्म कैसे बनाएँ?
रेंट एग्रीमेंट के लिए किरायेदार को राज्य बताना होगा, और ऐप को यह भी जानना होगा कि उस राज्य में कौन-से विकल्प उपलब्ध हैं। StampMitra की API इसके लिए चार lookup देती है, सब estamp.read scope पर:
GET /v1/estamp/schema/:serviceCodeदेता है फ़ॉर्म बनाने का generic metadata। docs कहते हैं किserviceCodeसिर्फ़ आगे की अनुकूलता के लिए स्वीकार होता है, और e-stamp का एक ही schema है, चाहे मान कुछ भी हो।GET /v1/estamp/statese-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 वाली सूची के नीचे article का कोई और विभाजन नहीं है।
दूसरी और तीसरी बात का सार यह है कि instrument और article, दोनों अलग इकाइयाँ नहीं हैं। docs के शब्दों में, एक अलग instrument entity नहीं है, यह वही state-scoped article catalogue लौटाता है। इसलिए अपने डेटाबेस में इन्हें दो अलग तालिकाओं में मत बाँटिए।
यह response हमारे पास documented नहीं है
इन चारों endpoint के response bodies दस्तावेज़ में नहीं छपे हैं। इसका मतलब यह है कि मैं आपको "states की सूची में code और name होते हैं" जैसा कोई दावा नहीं दे सकता, क्योंकि यह असल में साबित नहीं है। सही तरीक़ा यह है: sandbox key से इन्हें एक बार खुद चलाइए, असली response देखिए, और तभी अपना parsing कोड लिखिए। नीचे का कोड सिर्फ़ कॉल का आकार दिखाता है।
# PLACEHOLDER: ये कॉल documented हैं, पर इनके response की बनावट documented नहीं है।
curl "https://api-b2b.stampmitra.in/v1/estamp/states" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY"
# <STATE_CODE> को ऊपर के जवाब में मिले राज्य के कोड से बदलें
curl "https://api-b2b.stampmitra.in/v1/estamp/states/<STATE_CODE>/instruments" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY"फ़ॉर्म को schema-चालित रखें
एक व्यावहारिक सलाह: GharSaathi के फ़ॉर्म में राज्यों की सूची या instrument के विकल्प अपने कोड में मत लिखिए। schema और lookup से जो मिले, उसी से dropdown बनाइए। इससे जब StampMitra की master-data सूची बदलेगी, आपके ऐप को नया release नहीं निकालना पड़ेगा।
चरण 3: duty और शुल्क कैसे निकालें, बिना ख़ुद हिसाब लगाए?
रेंट एग्रीमेंट पर कितनी स्टैंप ड्यूटी लगेगी, यह राज्य, लिखत के प्रकार और किराये की शर्तों के हिसाब से बदलता है। इस गाइड में हम कोई राशि नहीं लिखेंगे, और आपके ऐप को भी अपने कोड में कोई दर, सूत्र या slab नहीं रखना चाहिए। क़ानूनी तौर पर आपके मामले में क्या लागू होता है, इसकी पुष्टि योग्य वकील या संबंधित राज्य के स्टांप विभाग से कराइए।
API में इसके लिए POST /v1/estamp/duty/calculate है, scope estamp.duty.calculate। docs इसे "authoritative" गणना कहते हैं और यह भी लिखते हैं कि response की राशि client की तरफ़ कभी दोबारा नहीं निकाली या बदली जाती। यानी आपके ऐप का काम सिर्फ़ यह राशि दिखाना है। यह कॉल आपके fulfilment wallet से मीटर होती है, तो इसे हर कीस्ट्रोक पर मत चलाइए, सिर्फ़ तब चलाइए जब किरायेदार ने राज्य, article और ज़रूरी ब्योरा भर दिया हो।
placeholder body
इस endpoint का request body और response दस्तावेज़ में नहीं है। नीचे का body सिर्फ़ यह दिखाने के लिए है कि कॉल कैसी दिखेगी। फ़ील्ड के नाम असली नहीं हैं, उन्हें आपको schema endpoint से मिलान करके बदलना होगा।
# PLACEHOLDER BODY: फ़ील्ड के नाम काल्पनिक हैं, असली नाम schema endpoint से लीजिए।
curl -X POST "https://api-b2b.stampmitra.in/v1/estamp/duty/calculate" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"_placeholder": "असली फ़ील्ड schema से लें",
"<state-field>": "<STATE_CODE>",
"<article-field>": "<ARTICLE_FROM_LOOKUP>",
"<value-field>": "<TRANSACTION_VALUE_FROM_USER>"
}'डिज़ाइन का नियम: राशि ऐप में कभी मत गढ़ें
ब्रोकर ऐप अक्सर ग्राहक को "अनुमानित लागत" दिखाना चाहते हैं। उसका सही तरीक़ा duty calculate का जवाब दिखाना है, और राशि के पास यह वाक्य रखना है कि "अंतिम राशि राज्य के नियमों पर निर्भर है"। अपने डेटाबेस में कोई "राज्य बनाम दर" वाली तालिका बनाना ख़तरनाक है, क्योंकि नियम बदलते हैं और आपकी तालिका पुरानी पड़ जाएगी।
चरण 4: order कैसे बनाएँ और `details` में क्या डालें?
अब किरायेदार ने "आगे बढ़ें" दबा दिया है, तो ऐप POST /v1/orders बुलाता है। यह एक generic endpoint है जो किसी भी entitled service के लिए चलता है, और e-stamp इसी से बनता है। scope orders.create चाहिए।
दस्तावेज़ में ये फ़ील्ड बताए गए हैं:
| फ़ील्ड | प्रकार | ज़रूरी? | अर्थ |
|---|---|---|---|
externalOrderId | string | हाँ | आपका अपना order reference |
externalCustomerId | string | हाँ | आपका अपना ग्राहक reference |
serviceCode | string | हाँ | entitled service, जैसे e-stamp का कोड |
details | object | नहीं | free-form, service-विशिष्ट payload |
Idempotency-Key (header) | string | नहीं | वैकल्पिक idempotency key |
सबसे अहम पंक्ति details की है: docs लिखते हैं कि e-stamp के लिए अलग request/response contract अभी नहीं है, यानी state, article या parties[] जैसे पहले दर्जे के फ़ील्ड नहीं हैं, और details का आकार upstream में अभी तय नहीं हुआ। इसलिए नीचे का उदाहरण दस्तावेज़ के उदाहरण पर आधारित है, पर details को हमने जानबूझकर placeholder रखा है।
curl -X POST "https://api-b2b.stampmitra.in/v1/orders" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: gharsaathi-tenancy-8841-v1" \
-d '{
"externalOrderId": "gs_tenancy_8841",
"externalCustomerId": "gs_user_2207",
"serviceCode": "estamp.instrument.rent_agreement",
"details": { "_placeholder": "आकार अभी तय नहीं; schema/lookup के अनुसार भरें" }
}'externalOrderId और externalCustomerId आपके सिस्टम की IDs हैं (यहाँ काल्पनिक)। इन्हें ऐसा रखिए कि बाद में आपके अपने डेटाबेस से तुरंत जुड़ जाएँ। StampMitra अपनी तरफ़ से जो order id देता है (docs में इसे "B2B-assigned id" कहा गया है), वही आगे GET /v1/orders/:id और parties के path में orderId बनकर जाएगा।
response में क्या मिलेगा
इस endpoint का response body दस्तावेज़ में नहीं छपा। हमें सिर्फ़ इतना पता है कि order एक id लेकर बनता है जिससे बाद की कॉल चलती हैं। अपने कोड में पहले sandbox पर एक order बनाकर देखिए कि id किस फ़ील्ड में आती है, और उसे ही parse कीजिए। नीचे के Node.js और Python नमूनों में हमने इस फ़ील्ड का नाम ORDER_ID_FIELD जैसा placeholder रखा है, ताकि कोई मान न ले कि फ़ील्ड का नाम id ही है।
Idempotency क्यों काम आती है
मोबाइल ऐप में नेटवर्क कट जाए तो उपयोगकर्ता बटन दोबारा दबा देता है। अगर आपने हर किरायेदार-ऑर्डर के लिए एक स्थिर Idempotency-Key भेजी है, तो आप दोहरा order बनने का ख़तरा कम करते हैं। docs में header को optional कहा गया है, और यह नहीं लिखा कि सर्वर उसे कितने समय तक याद रखता है, इसलिए उस समय की कोई सीमा अपने कोड में मत मानिए।
चरण 5: मालिक, किरायेदार और गवाह की जानकारी (parties)
order बनने के बाद अगला क़दम parties का है। docs का endpoint है POST /v1/estamp/orders/:orderId/parties, scope estamp.parties.write, और यह भी fulfilment wallet के विरुद्ध मीटर होता है। इसका काम मौजूदा e-stamp order पर ग्राहक या party की जानकारी जोड़ना या सुधारना है, और products का वर्णन कहता है कि इसमें पहली पार्टी, दूसरी पार्टी और गवाह की जानकारी जुड़ सकती है।
रेंट एग्रीमेंट में आमतौर पर पहली पार्टी मकान मालिक और दूसरी पार्टी किरायेदार होती है, और कई जगह गवाह भी चाहिए होते हैं। कितने गवाह चाहिए और किसकी पहचान कैसे दर्ज हो, यह नियम राज्य और दस्तावेज़ के हिसाब से अलग हो सकता है, इसलिए इसे योग्य वकील से पक्का कीजिए।
यह क्रम क्यों मायने रखता है
path में :orderId है। इसलिए अगर आप parties पहले जोड़ने की कोशिश करेंगे, तो आपके पास कोई id ही नहीं होगी। ऐप के फ़्लो में इसका मतलब है कि "मालिक और किरायेदार के नाम" वाली स्क्रीन के बाद नहीं, बल्कि ऑर्डर बनने के बाद वाली स्क्रीन पर parties की कॉल जाए। अगर आप स्क्रीन पर पहले नाम इकट्ठा कर चुके हैं, तो उन्हें अपने सर्वर पर अस्थायी रूप से रखिए और order बनते ही भेज दीजिए।
placeholder body
parties का request body दस्तावेज़ में नहीं है। इसलिए यह उदाहरण सिर्फ़ ढाँचा दिखाता है, फ़ील्ड असली नहीं हैं।
# PLACEHOLDER BODY: फ़ील्ड काल्पनिक हैं। असली संरचना sandbox में जाँचें।
curl -X POST "https://api-b2b.stampmitra.in/v1/estamp/orders/<ORDER_ID>/parties" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"_placeholder": "असली फ़ील्ड documented नहीं",
"<first-party>": { "<name-field>": "<LANDLORD_NAME>" },
"<second-party>": { "<name-field>": "<TENANT_NAME>" },
"<witnesses>": []
}'कुल मिलाकर इस चरण में बहुत संवेदनशील व्यक्तिगत डेटा आता है। उसके रखरखाव का ज़िक्र हम सुरक्षा वाले हिस्से में करेंगे।
चरण 6: payment intent कैसे बनाएँ?
जब order और parties तैयार हों, तब भुगतान का समय आता है। POST /v1/payments/intents एक payment intent बनाती है, और docs इसे Razorpay-backed बताते हैं। scope payments.write चाहिए और यहाँ भी Idempotency-Key optional है। बनी हुई intent की मौजूदा स्थिति GET /v1/payments/intents/:id से (scope payments.read) देखी जाती है, और किसी order से जुड़ा भुगतान GET /v1/orders/:id/payment से (scope orders.read) मिलता है।
payment intent का request और response body भी दस्तावेज़ में नहीं है। मैं यह दावा नहीं करूँगा कि इसमें कौन-सा फ़ील्ड order से जोड़ता है, या checkout को खोलने के लिए आपको क्या लौटता है। यह सब sandbox में खुद जाँचना होगा। यह उदाहरण सिर्फ़ कॉल का आकार दिखाता है:
# PLACEHOLDER BODY: order को intent से जोड़ने वाले फ़ील्ड का असली नाम documented नहीं।
curl -X POST "https://api-b2b.stampmitra.in/v1/payments/intents" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: gharsaathi-pay-8841-v1" \
-d '{ "_placeholder": "order का reference यहाँ जाएगा; फ़ील्ड का नाम sandbox में पुष्ट करें" }'भुगतान की स्थिति पर भरोसा कैसे करें
ऐप में "भुगतान सफल" तब दिखाइए जब आपके सर्वर ने GET /v1/payments/intents/:id या GET /v1/orders/:id/payment से स्थिति पढ़ ली हो, सिर्फ़ ब्राउज़र या ऐप के checkout के लौटने से नहीं। client की ओर से लौटा कोई संकेत नकली भी हो सकता है, इसलिए पुष्टि हमेशा अपने बैकएंड से StampMitra से पूछकर कीजिए।
duty का भुगतान और आपका ग्राहक
एक व्यावसायिक सवाल है कि भुगतान ग्राहक सीधे करेगा या आपका ऐप, यानी आपका fulfilment wallet। दस्तावेज़ में यह नहीं बताया गया कि आपके खाते के लिए कौन-सा मॉडल लागू होता है। इस पर अपने StampMitra संपर्क या support से बात कर लीजिए, ताकि ऐप की स्क्रीन और खाते का हिसाब मेल खाएँ।
चरण 7: status देखना और e-stamp का document लेना
भुगतान के बाद order आगे बढ़ता है। इसकी स्थिति GET /v1/orders/:id/status से poll की जाती है (scope orders.read)। पूरा order विवरण GET /v1/orders/:id से मिलता है।
status के संभावित मानों की सूची दस्तावेज़ में नहीं है, इसलिए मैं नहीं बता सकता कि "completed" को कौन-सा शब्द दर्शाता है। इसलिए अपने कोड में कोई भी status string hardcode मत कीजिए, पहले sandbox में असली मान पढ़िए। polling में नरमी रखिए: हर कुछ सेकंड की बजाय धीरे-धीरे अंतराल बढ़ाइए, क्योंकि दस्तावेज़ में उदाहरण के तौर पर एक endpoint पर 60 सेकंड में 60 अनुरोध की सीमा दिखाई गई है (TOO_MANY_REQUESTS के उदाहरण में), और सटीक सीमा हर endpoint के लिए अलग हो सकती है। webhooks की स्थिति webhooks पेज पर देखिए, हम यहाँ e-stamp के लिए किसी webhook event का दावा नहीं करते।
देरी को ऐप में कैसे दिखाएँ
e-stamp का बनना हमेशा तुरंत नहीं होता, और status के कौन-से मान कितना समय लेते हैं, यह दस्तावेज़ में नहीं है। इसलिए ऐप में "प्रक्रिया चल रही है" जैसी एक ईमानदार स्थिति रखिए, और ग्राहक को कोई पक्का समय मत बताइए। एक अच्छा तरीक़ा यह है कि स्थिति पढ़ने का काम आपका बैकएंड करे, और ऐप सिर्फ़ आपके अपने सर्वर से पूछे। इससे हर फ़ोन StampMitra को अलग से poll नहीं करता, और आपकी rate limit बची रहती है।
certificate की PDF
जब order पूरा हो जाए, तब दो कॉल काम आती हैं, दोनों documents.read scope पर:
GET /v1/orders/:id/documentsउस order के बने दस्तावेज़ों की सूची देती है, जैसे e-stamp certificate की PDF।GET /v1/orders/:id/documents/:documentId/downloadकिसी एक दस्तावेज़ के लिए आम तौर पर थोड़े समय तक चलने वाला signed URL देती है।
signed URL का मतलब है कि उसे अपने डेटाबेस में हमेशा के लिए मत रखिए। जब भी ऐप को PDF दिखानी हो, तब नई download कॉल कीजिए, और फ़ाइल को अपने सुरक्षित स्टोरेज में नियमों के अनुसार रखना चाहें तो वह आपका निर्णय है। इन दोनों कॉल के response की बनावट भी documented नहीं है।
curl "https://api-b2b.stampmitra.in/v1/orders/<ORDER_ID>/documents" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY"
curl "https://api-b2b.stampmitra.in/v1/orders/<ORDER_ID>/documents/<DOCUMENT_ID>/download" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY"Node.js और Python में पूरा क्रम
अब पूरा क्रम एक जगह देखते हैं। ये दोनों नमूने सिर्फ़ ढाँचा हैं। जो हिस्से documented नहीं हैं (response के फ़ील्ड, parties और payment के body), उन्हें PLACEHOLDER टिप्पणी से चिह्नित किया गया है, और आपको sandbox में असली आकार देखकर बदलना होगा। base URL और header का आकार दस्तावेज़ के अनुसार है।
Node.js (18+, built-in fetch)
const BASE = "https://api-b2b.stampmitra.in";
const KEY = process.env.STAMPMITRA_API_KEY; // sk_test_... sandbox में
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) {
// हर error { error: { code, message, requestId } } के आकार में आता है
const e = data.error || {};
throw new Error(`${res.status} ${e.code}: ${e.message} (requestId=${e.requestId})`);
}
return data;
}
async function createRentAgreementOrder(tenancy) {
// चरण 1: service चालू है या नहीं
const { services } = await call("GET", "/v1/services");
const svc = services.find(
(s) => s.serviceCode === "estamp.instrument.rent_agreement" && s.active
);
if (!svc) throw new Error("rent agreement e-stamp आपके खाते पर चालू नहीं है");
// चरण 4: order (details का आकार तय नहीं, इसलिए PLACEHOLDER)
const order = await call(
"POST",
"/v1/orders",
{
externalOrderId: tenancy.id,
externalCustomerId: tenancy.userId,
serviceCode: svc.serviceCode,
details: { _placeholder: "schema/lookup के अनुसार भरें" },
},
{ "Idempotency-Key": `gharsaathi-order-${tenancy.id}` }
);
const orderId = order[process.env.ORDER_ID_FIELD]; // PLACEHOLDER: असली फ़ील्ड sandbox में देखें
// चरण 5: parties (PLACEHOLDER body)
await call("POST", `/v1/estamp/orders/${orderId}/parties`, {
_placeholder: "असली फ़ील्ड documented नहीं",
});
// चरण 6: payment intent (PLACEHOLDER body)
const intent = await call(
"POST",
"/v1/payments/intents",
{ _placeholder: "order reference का फ़ील्ड sandbox में पुष्ट करें" },
{ "Idempotency-Key": `gharsaathi-pay-${tenancy.id}` }
);
return { orderId, intent };
}Python (requests)
import os
import requests
BASE = "https://api-b2b.stampmitra.in"
KEY = os.environ["STAMPMITRA_API_KEY"] # sk_test_... sandbox में
def call(method, path, body=None, extra_headers=None):
headers = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}
headers.update(extra_headers or {})
res = requests.request(method, BASE + path, json=body, headers=headers, timeout=30)
data = res.json()
if not res.ok:
e = data.get("error", {})
raise RuntimeError(
f"{res.status_code} {e.get('code')}: {e.get('message')} (requestId={e.get('requestId')})"
)
return data
def fetch_certificate(order_id, document_id):
# चरण 7: documents.read scope वाली key चाहिए
docs = call("GET", f"/v1/orders/{order_id}/documents") # PLACEHOLDER: response का आकार देखें
link = call("GET", f"/v1/orders/{order_id}/documents/{document_id}/download")
return docs, linkदोनों नमूनों में एक ही आदत दिखती है: error को एक जगह पकड़ना और requestId को संदेश में रखना। यह आदत आपको बाद में बहुत समय बचाएगी, क्योंकि docs के अनुसार हर error इसी आकार में आता है।
रेंट एग्रीमेंट e-stamp API कब चुनें और कब नहीं?
हर ऐप को इसकी ज़रूरत नहीं होती। इसे चुनने का निर्णय इन सवालों से कीजिए।
| स्थिति | निर्णय | कारण |
|---|---|---|
| आपके ऐप में हर महीने कई किरायेदार आते हैं | API चुनें | हर बार हाथ से स्टांप कटवाना धीमा पड़ेगा |
| आप onboarding के अंदर ही पूरा अनुभव देना चाहते हैं | API चुनें | हर चरण ऐप की स्क्रीन से जुड़ जाता है |
| आपको सिर्फ़ एक बार एक एग्रीमेंट चाहिए | API न चुनें | इंटीग्रेशन की मेहनत बेकार जाएगी |
| आपको यह पता नहीं कि आपका राज्य और लिखत का प्रकार e-stamp में आता है या नहीं | पहले states देखें | उपलब्धता राज्य के हिसाब से बदलती है |
| आपको कानूनी राय चाहिए कि कौन-सी शर्त एग्रीमेंट में डालें | वकील से पूछें | API क़ानूनी सलाह नहीं देती |
| आप चाहते हैं कि duty की राशि आपका ऐप अपने आप तय करे | ऐसा न करें | राशि सिर्फ़ duty calculate से लें |
इसके अलावा एक और बात ध्यान देने की है: e-stamp का अपना अलग contract अभी पूरी तरह तय नहीं है, खासकर details का आकार। अगर आपकी टीम को पहले दिन से पक्की, स्थिर, पूरी तरह दस्तावेज़ी API चाहिए, तो इस हिस्से को "शुरुआती चरण" की तरह लें और अपने कोड को इस तरह लिखें कि बाद में details के बदलने पर एक ही जगह बदलना पड़े।
जब ग्राहक बीच में ऐप छोड़ दे
onboarding में लोग अक्सर बीच में रुक जाते हैं। अगर order बन चुका हो पर भुगतान न हुआ हो, तो ऐप अगली बार खुलने पर उसी externalOrderId से पुराना order दिखाए, नया न बनाए। इसके लिए अपने डेटाबेस में externalOrderId को स्थिति के साथ रखिए, और लौटने पर GET /v1/orders/:id/status से देखिए कि आगे का क़दम क्या बचा है। इस तरह ग्राहक को सारी जानकारी दोबारा नहीं भरनी पड़ती।
किसी तीसरे के लिए सौदा करने वाला ब्रोकर
कई बार ब्रोकर मकान मालिक की ओर से सब कुछ भरता है। ऐसे में ऐप को साफ़ रिकॉर्ड रखना चाहिए कि जानकारी किसने और किसकी सहमति से डाली। यह रिकॉर्ड विवाद की स्थिति में आपके काम आएगा, और इसके नियम आपके वकील से पूछने लायक़ हैं।
किरायेदार की पहचान जाँच का सवाल
कई ब्रोकर ऐप रेंट एग्रीमेंट से पहले मकान मालिक या किरायेदार का KYC भी करते हैं। StampMitra की verification APIs (PAN, GSTIN आदि) इसी काम की हैं। उदाहरण के लिए, PAN verification की गाइड देखिए। KYC कितना ज़रूरी है, यह आपके कारोबार और क़ानूनी सलाह पर निर्भर है, यह लेख इस पर कोई निर्णय नहीं देता। फ़िनटेक में KYC के बड़े उपयोग के लिए KYC API का उपयोग-मामला भी देखा जा सकता है।
अपने कोड में बदलाव की जगहें अलग रखें
चूँकि e-stamp के कई body अभी तय नहीं हैं, इसलिए अपने कोड में StampMitra से जुड़ा हिस्सा एक अलग मॉड्यूल में रखिए, जिसका नाम मान लीजिए estampClient हो। उस मॉड्यूल के बाहर किसी को भी details या parties के फ़ील्ड का नाम नहीं पता होना चाहिए। आपके ऐप के बाक़ी हिस्से सिर्फ़ अपने घरेलू ऑब्जेक्ट देखें, जैसे "tenancy" और "landlord", और यह मॉड्यूल उन्हें API के आकार में बदले। जब दस्तावेज़ में असली contract छपेगा, तब आप सिर्फ़ इसी मॉड्यूल को बदलेंगे और ऐप की स्क्रीन, डेटाबेस और टेस्ट लगभग वैसे ही रहेंगे।
इसी मॉड्यूल में एक छोटा "contract test" भी रखिए, जो sandbox पर चलकर देखे कि जिन फ़ील्ड की आप उम्मीद कर रहे हैं वे सच में लौट रहे हैं। अगर किसी दिन जवाब का आकार बदल जाए, तो आपको उपयोगकर्ता से पहले यह टेस्ट बता देगा। यह टेस्ट हर release से पहले और रात में एक बार चलाना ठीक रहता है, ताकि आपको चौंकना न पड़े।
आम गलतियाँ और troubleshooting
नीचे वे गलतियाँ हैं जो इस तरह के इंटीग्रेशन में सबसे ज़्यादा होती हैं। error के कोड और संदेश दस्तावेज़ में दिए उदाहरणों से लिए गए हैं।
| लक्षण | संभावित कारण | क्या करें |
|---|---|---|
401 UNAUTHORIZED ("Missing or invalid API key.") | header नहीं लगा, या key ग़लत है | Authorization: Bearer <key> या x-api-key जाँचें |
403 FORBIDDEN | key वैध है पर इस endpoint का scope नहीं है | dashboard में key के scope बढ़ाएँ, जैसे estamp.parties.write |
400 BAD_REQUEST | validation या entitlement की समस्या | message पढ़ें, serviceCode और details जाँचें |
402 PAYMENT_REQUIRED | fulfilment wallet में राशि कम | wallet भरें, फिर कॉल दोहराएँ |
404 NOT_FOUND | ग़लत orderId या documentId | आपके सर्वर ने जो id सहेजी है उसे जाँचें |
429 TOO_MANY_REQUESTS | बहुत तेज़ polling | अंतराल बढ़ाएँ, backoff लगाएँ |
502 INTERNAL_ERROR | पीछे की सेवा अभी पहुँच में नहीं | थोड़ी देर बाद retry, requestId सँभालकर रखें |
गलतियाँ जो कोड समीक्षा में पकड़ी जानी चाहिए
पहली गलती: parties को order से पहले भेजने की कोशिश। path में :orderId है, इसलिए यह चल ही नहीं सकती। दूसरी: duty की राशि अपने कोड में गढ़ना। तीसरी: sandbox की sk_test_ key production में रख देना या उलटा। चौथी: details को "तय contract" मान लेना और उसके फ़ील्ड कई जगह फैला देना। पाँचवीं: signed download URL को डेटाबेस में स्थायी रूप से रख लेना। छठी: एक ही scope वाली key से सब कुछ चलाने की उम्मीद करना, जबकि हर endpoint का अपना scope है। सातवीं: error का requestId लॉग में न रखना।
support को लिखते समय क्या भेजें
अगर समस्या फिर भी न सुलझे, तो support पेज से या [email protected] पर लिखिए। मेल में requestId, endpoint, समय और अपनी externalOrderId भेजिए। key, PAN, आधार या किसी भी व्यक्ति का असली डेटा कभी मेल में मत चिपकाइए।
सुरक्षा, गोपनीयता और क़ानूनी सावधानियाँ
रेंट एग्रीमेंट में नाम, पते, पहचान के दस्तावेज़ और आर्थिक ब्योरा जैसी निजी जानकारी होती है। इसे सँभालने के लिए ये सामान्य अच्छे तरीक़े अपनाइए, और याद रखिए कि यह कोई क़ानूनी सलाह नहीं है।
key की सुरक्षा
API key सिर्फ़ आपके बैकएंड सर्वर पर रहे। मोबाइल ऐप या वेब पेज के कोड में कभी नहीं, क्योंकि वहाँ से कोई भी उसे निकाल सकता है। उसे environment variable में रखिए (जैसे STAMPMITRA_API_KEY)। संवेदनशील scopes पर IP allowlist लगाइए, और हर काम के लिए सबसे कम scope वाली key बनाइए। अगर key लीक हो जाए, तो तुरंत बदलिए। विस्तार के लिए API security policy देखें।
व्यक्तिगत डेटा: सहमति और न्यूनतम संग्रह
Digital Personal Data Protection Act, 2023 व्यक्तिगत डेटा के संसाधन पर लागू होता है, और इस लेख में हम उसे सिर्फ़ नाम के स्तर पर संदर्भित करते हैं, उसकी धाराओं का हवाला नहीं देते। सामान्य अच्छा तरीक़ा यह है: किरायेदार और मकान मालिक से स्पष्ट सहमति लीजिए कि उनका डेटा किस काम के लिए जा रहा है; केवल वही जानकारी माँगिए जो एग्रीमेंट के लिए ज़रूरी है; और जब काम पूरा हो जाए, तब अनावश्यक डेटा हटाने की नीति रखिए। StampMitra की developer privacy policy और data processing addendum पढ़कर अपनी भूमिका (आप डेटा के साथ क्या करते हैं और StampMitra क्या करता है) समझ लीजिए। अपने ऐप के लिए क़ानूनी दायित्व क्या बनते हैं, यह किसी योग्य वकील से पूछिए।
डेटा कब तक रखें
रेंट एग्रीमेंट और उससे जुड़े दस्तावेज़ कितने समय तक रखने चाहिए, यह आपके कारोबार, राज्य के नियमों और क़ानूनी सलाह पर निर्भर है। StampMitra का अपना अवधारण और हटाने का कार्यक्रम developer data retention schedule में बताया गया है, पर आपके ऐप में रखे डेटा की अवधि आप तय करते हैं। सामान्य सिद्धांत यह है कि जिस काम के लिए डेटा लिया गया, उसके पूरे होने के बाद उसे बेवजह मत रखिए, और जो रखें उसे एन्क्रिप्टेड और सीमित पहुँच के साथ रखें।
लॉग में क्या न रखें
अपने लॉग में पूरे request body मत छापिए, क्योंकि उनमें नाम और पहचान की जानकारी हो सकती है। requestId, externalOrderId, endpoint और status code रखना काफ़ी है। acceptable use policy में भी देख लीजिए कि API का उपयोग किन शर्तों पर है।
क्या StampMitra क़ानूनी सलाह देता है?
नहीं। StampMitra, Bani Global Industries LLP (LLPIN ACI-6373) द्वारा चलाया जाने वाला एक निजी LegalTech प्लेटफ़ॉर्म है। यह कोई सरकारी एजेंसी या लॉ फ़र्म नहीं है, और API का जवाब क़ानूनी राय या किसी स्वीकृति की गारंटी नहीं है। रेंट एग्रीमेंट की शर्तें, रजिस्ट्रेशन की ज़रूरत और स्टांप के नियम राज्य के हिसाब से अलग हैं, और इन सबके लिए योग्य वकील से पूछना सही रहेगा।
sandbox में टेस्ट कैसे करें और production में कैसे जाएँ?
sandbox में आपको अपने ऐप का हर चरण असली जैसा चलाकर देखना चाहिए। नीचे की जाँच-सूची GharSaathi जैसे ऐप के लिए काम की है।
sandbox की जाँच-सूची
GET /v1/servicesसे देखें कि e-stamp की serviceactiveहै।- schema, states और instruments के असली response छापकर देखें और उन्हीं के अनुसार parsing लिखें (क्योंकि ये bodies documented नहीं हैं)।
- duty calculate को चलाकर देखें कि जवाब आपके UI में कैसे दिखता है, और कोई राशि अपने कोड में न रखें।
- एक order बनाइए और देखिए कि id किस फ़ील्ड में आती है।
- parties जोड़िए, फिर जानबूझकर ग़लत
orderIdभेजकर404का रास्ता देखिए। - scope हटाकर
403का रास्ता जाँचिए। - एक ही
Idempotency-Keyसे order दो बार भेजकर देखिए कि आपका ऐप दोहरा order तो नहीं बनाता। - polling में
429आने पर आपका backoff काम करता है या नहीं, यह परखिए।
ध्यान रहे कि sandbox sandbox डेटा पर चलता है, इसलिए वहाँ मिले दस्तावेज़ को असली e-stamp की तरह उपयोग मत कीजिए।
production में जाना
production के लिए sk_live_... key और e-stamp का estamp entitlement चाहिए, और वह आपकी organization पर चालू होना चाहिए। जाने से पहले ये बातें देख लें: key सिर्फ़ सर्वर पर है, scopes न्यूनतम हैं, wallet में पर्याप्त राशि और अलर्ट है, लॉग में निजी डेटा नहीं छपता, और आपकी privacy सूचना में बताया है कि रेंट एग्रीमेंट के लिए किसका डेटा कहाँ जाता है। developer onboarding की शर्तें developer onboarding verification policy में हैं। शुरुआत के चरणों के लिए quickstart भी उपयोगी है, और error संभालने के और तरीक़े API errors की गाइड में हैं।
धीरे-धीरे खोलना
पहले हफ़्ते में रेंट एग्रीमेंट का बटन सिर्फ़ कुछ चुनिंदा उपयोगकर्ताओं या अपनी टीम के लिए चालू कीजिए। हर order का externalOrderId और requestId लॉग कीजिए, ताकि कुछ गड़बड़ हो तो जल्दी पता चले।
StampMitra आपकी कैसे मदद करता है
StampMitra एक B2B API देता है जिसके ज़रिए आपका ऐप e-stamp का पूरा क्रम चला सकता है। आज दस्तावेज़ में दर्ज चीज़ें ये हैं: entitled services की सूची, e-stamp का schema, state, instrument और article lookup, authoritative duty calculation, POST /v1/orders से order बनाना, उसी order पर parties जोड़ना, Razorpay-backed payment intent, order का status और पूरा order विवरण, और पूरा हो जाने पर certificate document की सूची व download URL। हर कॉल Bearer या x-api-key से प्रमाणित होती है और हर endpoint का अपना scope है, जिससे आप key को सीमित रख सकते हैं।
हम यह भी साफ़ बताना चाहते हैं कि अभी क्या पूरा नहीं है। e-stamp के लिए अलग first-class contract नहीं है, और POST /v1/orders में details का आकार तय नहीं हुआ है। कई endpoint के request और response bodies अभी सार्वजनिक दस्तावेज़ में नहीं हैं। इसी वजह से इस गाइड में placeholder का उपयोग हुआ है और हम आपको sandbox में असली response देखकर कोड लिखने को कहते हैं। StampMitra न तो सरकारी एजेंसी है, न लॉ फ़र्म, और हम किसी दस्तावेज़ की मंज़ूरी की गारंटी नहीं देते। क़ानूनी सवालों के लिए योग्य वकील से मिलिए।
आगे की योजनाओं के रूप में हम दस्तावेज़ीकरण को और स्पष्ट करना चाहते हैं, ख़ासकर e-stamp के request और response bodies, और details का आकार तय होने पर उसका प्रकाशन। ये योजनाएँ हैं, वादे या तारीख़ें नहीं। SDKs, MCP और Postman जैसे आगे के रास्तों की मौजूदा स्थिति आप SDKs, MCP और Postman पेज पर देख सकते हैं। मुफ़्त sandbox key के लिए साइन-अप करें, एक-एक endpoint का विवरण e-stamp docs में देखें, और उत्पाद-स्तर की जानकारी products पेज पर है। सवाल हों तो [email protected] पर लिखिए, और हमारी e-stamp सेवा के बाकी पेज e-stamp orders, parties, payment और documents पर हैं।
API reference एक नज़र में
POST /v1/ordersRequest parameters
| Field | Type | Description |
|---|---|---|
Authorizationrequired | header | Bearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted. |
Idempotency-Key | header | Optional idempotency key. |
externalOrderIdrequired | string | Your own reference for this order. |
externalCustomerIdrequired | string | Your own reference for the customer. |
serviceCoderequired | string | The entitled service to order (e.g. an estamp.* code). |
details | object | Free-form service-specific payload (e-Stamp field shape is not finalized). |
POST /v1/orders{
"externalOrderId": "ord_ext_123",
"createdAt": "2026-10-15T09:41:07.000Z",
"serviceCode": "estamp.instrument.rent_agreement"
}POST /v1/orderse-Stamp Order Creation: ₹5 API fee per successful call, pay-as-you-go (lower on Growth and Scale).
POST /v1/estamp/duty/calculateRequest parameters
| Field | Type | Description |
|---|---|---|
Authorizationrequired | header | Bearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted. |
stateCoderequired | string | State code, e.g. MH. |
articleCoderequired | string | Stamp article code from the articles lookup. |
stampDutyAmountrequired | number | Stamp duty amount to calculate charges for; must be positive. |
districtCode | string | District code, where the state needs one. |
sroValue | string | Sub-registrar office value, where the state needs one. |
doorstepDelivery | boolean | Whether doorstep delivery is requested. |
couponCode | string | Coupon code to apply. |
masterDataVersion | integer | Master-data version the caller last read. |
POST /v1/estamp/duty/calculateDuty / Value Calculation: ₹5 API fee per successful call, pay-as-you-go (lower on Growth and Scale).
अक्सर पूछे जाने वाले सवाल
रेंट एग्रीमेंट e-stamp API में सही क्रम क्या है?
दस्तावेज़ का क्रम है: पहले POST /v1/orders से order बनाएँ, फिर उसके orderId के साथ parties जोड़ें, फिर payment intent बनाएँ, और अंत में status देखकर documents लें। parties का path orderId माँगता है, इसलिए order पहले आता है।
e-stamp के लिए कौन-से scopes चाहिए?
services.read, estamp.read, estamp.duty.calculate, orders.create, estamp.parties.write, payments.write, orders.read और documents.read। हर endpoint का अपना scope है, और scope कम होने पर API 403 FORBIDDEN लौटाती है।
क्या API मुझे स्टांप ड्यूटी की राशि बताती है?
हाँ, POST /v1/estamp/duty/calculate authoritative गणना चलाता है और जवाब की राशि client की तरफ़ दोबारा नहीं निकाली जाती। राशि राज्य के हिसाब से बदलती है, इसलिए अपने ऐप में कोई दर न रखें और वकील से पुष्टि करें।
POST /v1/orders में e-stamp का details कैसा होता है?
दस्तावेज़ के अनुसार details एक free-form object है और e-stamp के लिए उसका आकार अभी तय नहीं हुआ है। state, article या parties[] जैसे पहले दर्जे के फ़ील्ड नहीं हैं, इसलिए sandbox में असली आकार देखकर कोड लिखें।
क्या schema, states और parties के request और response bodies documented हैं?
नहीं, इन endpoint के bodies अभी सार्वजनिक दस्तावेज़ में नहीं हैं। इस गाइड में दिखे bodies placeholder हैं। असली संरचना जानने के लिए sandbox key से कॉल चलाकर देखें और उसी के अनुसार parsing लिखें।
sandbox और production key में क्या फ़र्क़ है?
sandbox key sk_test_ से शुरू होती है और sandbox डेटा पर चलती है, जबकि production key sk_live_ से शुरू होती है। production में e-stamp के लिए आपकी organization के पास estamp entitlement होना चाहिए।
भुगतान कैसे होता है?
POST /v1/payments/intents एक Razorpay-backed payment intent बनाती है, जिसके लिए payments.write scope चाहिए। उसकी स्थिति GET /v1/payments/intents/:id या GET /v1/orders/:id/payment से पढ़ी जा सकती है। body documented नहीं है।
e-stamp certificate की PDF कैसे मिलती है?
order पूरा होने पर GET /v1/orders/:id/documents दस्तावेज़ों की सूची देती है और GET /v1/orders/:id/documents/:documentId/download आम तौर पर थोड़े समय के signed URL देती है। दोनों के लिए documents.read scope चाहिए।
दोहरा order बनने से कैसे बचें?
POST /v1/orders और POST /v1/payments/intents, दोनों पर वैकल्पिक Idempotency-Key header है। हर tenancy के लिए एक स्थिर key भेजें और अपने डेटाबेस में externalOrderId रखें, ताकि दोबारा दबाने पर पुराना order ही मिले।
क्या StampMitra क़ानूनी सलाह या सरकारी मंज़ूरी देता है?
नहीं। StampMitra, Bani Global Industries LLP द्वारा चलाया जाने वाला निजी LegalTech प्लेटफ़ॉर्म है, सरकारी एजेंसी या लॉ फ़र्म नहीं। रेंट एग्रीमेंट और स्टांप के नियम राज्य के हिसाब से बदलते हैं, इसलिए योग्य वकील से पूछें।
स्रोत
- StampMitra Developers, API उत्पाद डेटा (e-stamp, services, orders, payments, auth):
src/data/api-products.ts, 2026-10-16 को पढ़ा गया। - API key authentication, e-stamp docs, pricing, quickstart: StampMitra Developers साइट, 2026-10-16।
- API security policy, developer privacy policy, data processing addendum: StampMitra Developers साइट, 2026-10-16।
- Digital Personal Data Protection Act, 2023: सिर्फ़ नाम के स्तर पर संदर्भित। आधिकारिक पाठ इस सत्र में खोला नहीं जा सका, इसलिए किसी धारा का हवाला नहीं दिया गया है।
- राज्यवार स्टांप ड्यूटी और रजिस्ट्रेशन के नियम: कोई आँकड़ा उद्धृत नहीं है। संबंधित राज्य का स्टांप और रजिस्ट्रेशन विभाग या योग्य वकील अंतिम स्रोत है।