StampMitraDevelopers
आधिकारिक SDK

Python SDK

StampMitra Developer API का आधिकारिक Python क्लाइंट: sync और async क्लाइंट, typed pydantic models और signed-webhook helpers के साथ identity verification और e-Stamp।

Pre-release 0.1.0 - package registry पर प्रकाशन जारी है

Package
stampmitra
संस्करण
0.1.0
आवश्यकता
Python 3.9 या उससे नया। Runtime dependencies: httpx और pydantic 2। Sync और async क्लाइंट, typed (py.typed, mypy --strict पास)।
लाइसेंस
MIT
Changelog
CHANGELOG.md
इंस्टॉल

Package इंस्टॉल करें

pip
pip install stampmitra

प्रकाशित होने के बाद उपलब्ध। अभी PyPI पर प्रकाशित नहीं हुआ है। यह कमांड package के रिलीज़ होने के बाद काम करेगा; तब तक रिलीज़ के लिए GitHub repository देखते रहें।

pip (from GitHub)
pip install "git+https://github.com/Bani-Global-Industries-LLP/stampmitra-developer-python.git"

तब तक GitHub से इंस्टॉल करें: यह repository एक मानक pyproject (hatchling, src layout) है, इसलिए pip इसे सीधे Git से build कर सकता है।

Quickstart

पाँच पंक्तियों में PAN verify करें

बनाते समय sandbox key (sk_test_...) इस्तेमाल करें। यह मुफ़्त है, आपके वॉलेट से कुछ नहीं कटता और sandbox डेटा पर चलती है।

Quickstart
from stampmitra import StampMitra

client = StampMitra()  # reads STAMPMITRA_API_KEY
result = client.verify.pan("ABCDE1234F", name="Rahul Kumar")
print(result.valid, result.registered_name, result.reference_id)
Authentication

API keys और environments

Sandbox

Sandbox keys sk_test_ से शुरू होती हैं। ये मुफ़्त हैं और sandbox डेटा लौटाती हैं।

Live

Live keys sk_live_ से शुरू होती हैं। इनके लिए स्वीकृत production access request चाहिए और हर सफल कॉल पर शुल्क लगता है।

api_key="sk_test_..." दें या STAMPMITRA_API_KEY environment variable सेट करें। client.environment का मान "test" या "live" होता है। जो key ^sk_(test|live)_[A-Za-z0-9_-]{8,}$ से मेल नहीं खाती वह अस्वीकार होती है, जब तक आप allow_custom_key=True न दें।

सिर्फ़ server-side। sk_ keys को कभी browser या mobile ऐप में न डालें और न ही किसी repository में commit करें। इन्हें environment variables या secrets manager में रखें। Authentication
Client options
from stampmitra import StampMitra, RequestOptions

client = StampMitra(
    api_key="sk_test_...",
    base_url="https://api-b2b.stampmitra.in",
    timeout=30,
    max_retries=2,
    default_headers={},
    app_info={"name": "my-app", "version": "1.0.0", "url": "https://example.com"},
    debug=False,
    validate_input=True,
    allow_custom_key=False,
)

# Every method also takes per-request options:
client.verify.pan(
    "ABCDE1234F",
    options=RequestOptions(timeout=10, max_retries=1, idempotency_key="...", headers={}),
)
Resources

हर resource एक जगह

JSON के field नाम camelCase और model attributes snake_case (registered_name) में होते हैं। अज्ञात fields सुरक्षित रहते हैं (model.model_extra, model.to_dict())। e-Stamp और ऑर्डर की request bodies सादे dicts हैं, ठीक वैसे जैसे API में दिए हैं। हर लौटाए गए model में status_code, headers, request_id और content वाला .response होता है। जिन endpoints का आकार spec में तय नहीं, वे ApiObject लौटाते हैं।

All resources
# verify (every call is billed, including negative results; HTTP 200 with valid=False)
client.verify.pan("ABCDE1234F", name="Rahul Kumar")
client.verify.gstin("07AAAAA1111A1Z1", business_name="Acme")
client.verify.rc("MH12AB1234")
client.verify.voter_id("ABC1234567")
client.verify.driving_license("MH1420110012345", "1990-01-01")  # IP-allowlisted key
client.verify.passport("PA1079341954215", "1990-01-01")  # IP-allowlisted key
client.verify.cin("U74999DL2015PTC284009")
client.verify.udyam("UDYAM-MH-12-1234567")
client.verify.pan_to_gstin("ABCDE1234F")
client.verify.pan_to_udyam("ABCDE1234F")
client.verify.bank_account("000123456789", "ICIC0001234", name="Jane Doe")

# services and e-Stamp
client.services.list()
client.services.get("estamp.instrument.rent_agreement")
client.estamp.get_schema(code)
client.estamp.list_states()
client.estamp.list_instruments("MH")
client.estamp.list_articles(instrument_code)
client.estamp.calculate_duty({...})
client.estamp.add_parties(order_id, {...})

# orders and payments
order = client.orders.create({"externalOrderId": "o1", "externalCustomerId": "c1", "serviceCode": code, "details": {}})
client.orders.get(id)
client.orders.get_status(id)
client.orders.get_payment(id)
client.orders.list_documents(id)
client.orders.get_document_download(id, document_id)
client.payments.intents.create({...})
client.payments.intents.get(intent_id)

# usage, logs, webhook events
client.usage.summary()
client.logs.list(from_="2026-10-01", to="2026-10-16", service="pan.verify", status="200", limit=50)
client.webhooks.events.list(limit=20)
client.webhooks.events.replay(event_id)
Pagination

Pagination

client.webhooks.events.iter_all() भी इसी तरह काम करता है (यह /v1/logs की तरह items / nextCursor आकार मानकर चलता है)।

Pagination
for entry in client.logs.iter_all(service="pan.verify", limit=100):  # follows nextCursor
    print(entry.id)

async for entry in async_client.logs.iter_all(limit=100):
    ...
Errors

Error classes

हर error StampMitraError से बना है (status, code, message, request_id, body)। ValidationError में .field और RateLimitError में .retry_after (सेकंड) होता है। Non-JSON error body भी status से map होती है। API की error body {"error": {"code", "message", "requestId", "field?"}} है।

HTTP statusClassटिप्पणी
400 / 422ValidationErrorगलत इनपुट। Validation helpers इसे request भेजने से पहले local रूप से भी उठाते हैं।
401AuthenticationErrorAPI key न मिली, गलत है या रद्द हो चुकी है।
402PaymentRequiredErrorवॉलेट में बैलेंस या क्रेडिट कम है।
403PermissionDeniedErrorसर्वर का संदेश जस का तस दिया जाता है, जैसे Passport और Driving Licence के लिए IP-allowlisted key चाहिए।
404NotFoundErrorऑर्डर, सेवा या इवेंट की id मौजूद नहीं है।
409ConflictErrorIdempotency-Key किसी दूसरी body के साथ दोबारा इस्तेमाल हुई, या state में टकराव है।
429RateLimitErrorरुककर दोबारा कोशिश करें; सर्वर Retry-After भेजे तो वह मान उपलब्ध रहता है।
5xxUpstreamErrorसर्वर या upstream की ओर की विफलता। 502, 503 और 504 पर अपने आप retry होता है।
network / timeoutAPIConnectionError / APITimeoutErrorकोई उपयोगी response नहीं मिला: कनेक्शन विफल, timeout या cancel।
Python
from stampmitra import StampMitraError, ValidationError, RateLimitError, PermissionDeniedError

try:
    client.verify.pan("ABCDE1234F")
except ValidationError as e:  # 400 (or local validation, e.status is None)
    print(e.field, e.message)
except RateLimitError as e:  # 429
    print(e.retry_after)
except StampMitraError as e:  # base class
    print(e.status, e.code, e.request_id)
Retries और idempotency

Retries और idempotency

Validation

क्लाइंट-साइड validation

भेजने से पहले इनपुट normalise (trim, upper-case) होकर बैकएंड जैसे ही patterns से जाँचे जाते हैं। विफल होने पर ValidationError local रूप से उठता है, बिना network call और बिना शुल्क के। इसे StampMitra(validate_input=False) से बंद करें।

Webhooks

Webhook signatures जाँचें

हर डिलीवरी में X-Webhook-Signature, X-Webhook-Timestamp (Unix सेकंड) और X-Webhook-Event-Id होते हैं। Signature, timestamp, एक बिंदु और raw body का hex HMAC-SHA256 है, जो आपके endpoint secret से बनता है। जाँच हमेशा raw body पर करें, दोबारा serialise किए गए JSON पर नहीं।

webhooks module signature को constant-time में जाँचता है और उन timestamps को अस्वीकार करता है जो अभी से tolerance_seconds (डिफ़ॉल्ट 300) से ज़्यादा दूर हों। यही helpers क्लाइंट पर client.webhooks.verify_signature और construct_event के रूप में भी हैं।

Python
from stampmitra import webhooks, WebhookSignatureError

event = webhooks.construct_event(
    raw_body,
    headers["X-Webhook-Timestamp"],
    headers["X-Webhook-Signature"],
    secret,
)
# webhooks.verify_signature(...) returns True or raises WebhookSignatureError

WebhookSignatureError में एक code होता है: signature_mismatch, timestamp_outside_tolerance, invalid_timestamp या missing_secret।

Framework के उदाहरण

Framework के उदाहरण
import os

from flask import Flask, request

from stampmitra import WebhookSignatureError, webhooks

app = Flask(__name__)
SECRET = os.environ["STAMPMITRA_WEBHOOK_SECRET"]


@app.post("/webhooks/stampmitra")
def receive() -> "tuple[str, int]":
    try:
        event = webhooks.construct_event(
            request.get_data(),  # the RAW body, not request.json
            request.headers.get(webhooks.TIMESTAMP_HEADER, ""),
            request.headers.get(webhooks.SIGNATURE_HEADER, ""),
            SECRET,
        )
    except WebhookSignatureError as err:
        return str(err), 400
    print("event", event.core_order_id, event.core_event_type, event.occurred_at)
    return "ok", 200

Webhooks: इवेंट के प्रकार, payload और retry नीति Webhooks पेज पर हैं।

सुरक्षित logging

सुरक्षित logging

डिफ़ॉल्ट रूप से बंद। StampMitra(debug=True) stampmitra logger में log करता है (या logger= दें)। Log की गई bodies में Authorization और x-api-key redact रहते हैं और PAN, GSTIN, account numbers व नाम masked रहते हैं।

SDKs

इंटीग्रेट करने के दूसरे तरीके

REST API किसी भी भाषा से चलती है, और बाकी SDKs भी उसी contract पर बने हैं।

API कॉल करने के लिए तैयार हैं?

मुफ़्त sandbox key लें और ऊपर का quickstart लगभग 5 मिनट में चलाएँ।