Physical eStamp API
8 endpoints · Core API
The Physical eStamp API enables secure and automated handling of physical stamp paper procurement and document tagging workflows. Through this service, authorized branches can retrieve stamp article details, request physical stamp papers, and update delivery or usage statuses via webhooks. This helps organizations comply with legal stamping requirements where eStamping is not available digitally.
Benefits
- Regulatory ComplianceEnsures physical stamp paper usage complies with legal mandates in non-eStamp-enabled regions.
- Branch-Level IntegrationSupports per-branch stamp procurement and inventory tracking.
- Workflow AutomationEnables webhook updates and real-time status tracking.
- Audit-ReadyMaintains digital logs and validations for physical stamp activities.
What you can do
- Fetch available stamp articles by branch
- Initiate physical stamp requests
- View branches supporting physical eStamp
- Receive usage or delivery status via webhooks
Retrieves the list of branches (one per state) supported for physical e-stamp orders.
Use this API to discover the valid branches. This API takes no request parameters.
--- INTEGRATION FLOW ---
Q. Why do I need to call this API first?
Different states have different article support. Each branch has a branch_code, which is the two-letter state code (for example GJ or MH). Use the branch_code as the {branch} path value in /articles/{branch}, and as the stateCode in /create-single-order and /create-bulk-stamp-request.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
1 field
- branchesarray<object>optionalNo description.nullable
Each item: 3 fields
- branch_idinteger (int32)optionalNo description.
- branch_namestringoptionalNo description.nullable
- branch_codestringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Retrieves the list of available legal articles (document types) for a state.
An article defines the legal purpose of the stamp (e.g., Affidavit, Loan Agreement, Power of Attorney).
Q. What is the branch parameter?
Required path parameter. It is the two-letter state code, in uppercase, taken from the branch_code field of the /branches API (for example GJ or MH). Matching is case-sensitive, and a code that is not in the list returns an empty article list.
Q. What information does this return?
It returns a list of articles, each with a numeric id, an article_code and an article_name. Send the numeric id as articleId in the stamping requests.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
Path parameters
- branchstringrequiredNo description.
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
1 field
- articlesarray<object>optionalNo description.nullable
Each item: 5 fields
- idinteger (int32)optionalNo description.
- article_codestringoptionalNo description.nullable
- article_namestringoptionalNo description.nullable
- state_codestringoptionalNo description.nullable
- amountarray<number>optionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Initiates a single Physical e-Stamping order (series/multi-article supported).
This API creates a physical e-stamp order for one or more articles in a single call using the series array.
Q. What is the 'series' array and why is it used?
The series property is the core of this API. It allows you to list multiple stamp requirements. For example, if a single business deal requires three different stamps of ₹100, ₹500, and ₹1000, you can pass all three in this array instead of calling the API three times.
Q. What are the Mandatory fields at the Root level?
-
stateCode [Required]: The 2-letter code of the Indian state, in uppercase (e.g., "MH" for Maharashtra). Use the branch_code from the /branches API.
-
firstPartyName [Required]: The primary entity name printed on all stamps in this series.
-
secondPartyName [Required]: The secondary entity name printed on all stamps in this series.
-
stampDutyPaidBy [Required]: "FIRST_PARTY" or "SECOND_PARTY" (letter case is ignored). "first_party_name", "second_party_name", or the exact first or second party name are also accepted.
-
series [Required]: At least one item (see below).
Q. What are the Mandatory fields inside the 'series' objects?
-
stampDutyAmount [Required]: The value in INR for that individual stamp paper. Send a value greater than zero. The total of all series items is checked against your wallet balance.
-
articleId [Required]: The numeric id of the document type from the /articles/{branch} API (e.g., 1342 for Gujarat "Deposit of Title Deeds").
-
purpose [Required]: Reason the stamp duty is paid, printed on the certificate (e.g., "Loan Agreement"). Must not be empty.
-
considerationPrice [Required]: The transaction value in INR associated with this specific article, as a number.
-
articleDescription [Optional]: Not used; any value sent is ignored.
Q. What are 'tags' used for?
tags [Optional] is an array of strings that allows you to label this order for easier filtering in your dashboard or reports (e.g., ["HomeLoan", "Q1-Project"]).
Q. What does 'isLive' control?
isLive [Optional, default: true] determines whether the system attempts to allocate a certificate from pre-procured inventory:
-
true (or omitted): The system searches the pre-procured inventory for a matching certificate (same state, article, denomination, and parties). If a match is found, the stamp is allocated immediately and the order is fulfilled at once. If no match is found, the order is created with status
AwaitingInventoryand fulfilled when the administrator uploads matching inventory. -
false: The inventory check is skipped entirely. The order is always created with status
AwaitingInventoryregardless of available stock, and will be fulfilled once the administrator uploads matching inventory.
Q. How do I get the results?
Provide a webhookUrl (optional; if omitted, the webhook URL configured for your account is used). Once the stamp is allocated or matching inventory is uploaded, our system will send a response containing the certificate details and download link.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- stateCodestringrequiredRequired. Two-letter state code where the stamp is used, in uppercase (e.g., MH, KA, GJ). Use the branchCode returned by the branches API. Must match the code used when the stamp inventory was ordered.minLength 1default GJ
- firstPartyNamestringrequiredRequired. Full name of the first party, printed on the certificate (e.g. the lender).minLength 1default First Party Name
- secondPartyNamestringrequiredRequired. Full name of the second party, printed on the certificate (e.g. the borrower).minLength 1default Second Party Name
- stampDutyPaidBystringrequiredRequired. Party that pays the stamp duty: "FIRST_PARTY" or "SECOND_PARTY" (letter case is ignored). The values "first_party_name" and "second_party_name", or the exact first or second party name, are also accepted.minLength 1default FIRST_PARTY
- webhookUrlstringoptionalOptional. URL that receives a callback when the stamp is allocated. If omitted, the webhook URL configured for your account is used.nullabledefault https://example.com/webhooks/physica…
- tagsarray<string>optionalOptional. Free-text labels stored with the order for your own tracking and filtering, e.g. ["HomeLoan", "Q1-Project"].nullable
- seriesarray<object>requiredRequired. One entry per stamp certificate to order, at least one. Each entry is a separate certificate with its own article, duty amount, purpose and consideration price.nullable
Each item: 5 fields
- stampDutyAmountnumber (double)requiredRequired. Stamp duty amount in INR for this certificate (the denomination). Send a value greater than zero. The total across all series items is checked against your wallet balance.default 300
- articleIdinteger (int32)requiredRequired. Numeric article ID (the `id` field) for the document type, from the articles API for the same state.default 1342
- purposestringrequiredRequired. Reason the stamp duty is paid, printed on the certificate (e.g. "Loan Agreement"). Must not be empty.minLength 1default Demo
- considerationPricenumber (double)requiredRequired. Consideration (transaction) value in INR for this article, as a number.default 50000
- articleDescriptionstringoptionalOptional. Not used. The article description is set from articleId; any value sent here is ignored.nullable
- isLivebooleanoptionalOptional. Controls whether the order tries to match pre-procured inventory. Default: true. <b>true</b> (or omitted) — check pre-procured inventory for a matching certificate (same state, article, denomination, parties) and allocate it immediately if available. If no match is found, the order waits for matching inventory. <b>false</b> — skip the inventory match; the order always waits for matching inventory (status `AwaitingInventory`).nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
1 field
- orderIdstringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Retrieves the current status and full history of a physical stamp order.
Use this API to track where your stamp is in the procurement lifecycle.
Q. What is the orderId?
Required path parameter. This is the unique identifier (orderId) returned by the /create-single-order API. It is required to fetch the final certificate details and delivery status.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
Path parameters
- orderIdstringrequiredNo description.
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
2 fields
- orderIdstringoptionalNo description.nullable
- eStampsarray<object>optionalNo description.nullable
Each item: 17 fields
- eStampIdstringoptionalNo description.nullable
- firstPartyNamestringoptionalNo description.nullable
- secondPartyNamestringoptionalNo description.nullable
- stampDutyPaidBystringoptionalNo description.nullable
- stampDutyValueinteger (int32)optionalNo description.nullable
- articleIdinteger (int32)optionalNo description.nullable
- considerationPriceinteger (int32)optionalNo description.nullable
- branchIdinteger (int32)optionalNo description.nullable
- purposeOfStampDutystringoptionalNo description.nullable
- statusstringoptionalNo description.nullable
- documentIdstringoptionalNo description.nullable
- orderTypestringoptionalNo description.nullable
- createdOnstring (date-time)optionalNo description.
- stateCodestringoptionalNo description.nullable
- stampPaperNumberstringoptionalNo description.nullable
- tagsarray<string>optionalNo description.nullable
- datastringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Fetches the list of your procured stamps for a state.
Returns your procured stamps (certificates issued and not yet applied to a document) for the given state, oldest first.
Q. What is the stateCode parameter?
Required path parameter. The two-letter state code, in uppercase (e.g., DL for Delhi, MH for Maharashtra). Matching is case-sensitive.
Q. What do I get back in /details-by-statecode?
An eStamps list. Each entry has an eStampId (GUID), the parties, article, duty amount, consideration price, status, stamp paper number and the stamp certificate as Base64 in data. Use the eStampId as stampId in /apply-stamps.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
Path parameters
- stateCodestringrequiredNo description.
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
2 fields
- stateCodestringoptionalNo description.nullable
- eStampsarray<object>optionalNo description.nullable
Each item: 17 fields
- eStampIdstringoptionalNo description.nullable
- firstPartyNamestringoptionalNo description.nullable
- secondPartyNamestringoptionalNo description.nullable
- stampDutyPaidBystringoptionalNo description.nullable
- stampDutyValueinteger (int32)optionalNo description.nullable
- articleIdinteger (int32)optionalNo description.nullable
- considerationPriceinteger (int32)optionalNo description.nullable
- branchIdinteger (int32)optionalNo description.nullable
- purposeOfStampDutystringoptionalNo description.nullable
- statusstringoptionalNo description.nullable
- documentIdstringoptionalNo description.nullable
- orderTypestringoptionalNo description.nullable
- createdOnstring (date-time)optionalNo description.
- stateCodestringoptionalNo description.nullable
- stampPaperNumberstringoptionalNo description.nullable
- tagsarray<string>optionalNo description.nullable
- datastringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Applies/Overlays procured e-Stamps onto a PDF document.
This API is the final step of the e-Stamping process. It takes your base PDF and "stitched" the government-issued stamp certificates onto specific pages.
Q. Where do I get the 'stampId'?
The stampId is the unique identifier generated after a successful procurement.
If you do not have the ID stored, you must first call:
GET/api/v1/PhysicalEStamp/details-by-statecode/{stateCode}
This will return a list of all procured stamps for that state. Copy the eStampId (Guid) from that response and send it as stampId in this mapping.
Q. How does the 'stamps' mapping work?
This is a list of instructions telling the system where to place each certificate.
-
stampId [Required]: The Guid retrieved from the Details by StateCode API.
-
pageNumber [Required]: The specific page in your PDF (1-based index) where this stamp certificate should be inserted.
-
externalEStampId [Optional]: Not used; any value sent is ignored.
Stamps that are not found, do not belong to your account, or are not in PROCURED status are skipped. The request fails with an error if no stamp can be applied.
Q. What is the purpose of documentInfo?
documentInfo [Required] carries the target document that needs to be stamped.
-
name [Required]: The filename (e.g., "Loan_Agreement.pdf").
-
content [Required]: The raw PDF file converted to a Base64 string. Must be a valid PDF that is not already signed.
Q. What is referenceId?
referenceId [Required] is your unique identifier for this request. 1 to 64 characters: letters, digits, hyphen (-) and underscore (_) only. A reference that was already used is rejected.
Q. Why use this API instead of just downloading the certificate?
Legally, the stamp paper and the agreement must be part of a single combined file. This API automates the merging of PDFs, ensuring the stamp is correctly positioned before the document is sent for digital signing.
Integration Tip: If you procured multiple stamps (e.g., using the Series API), you should provide multiple objects in the stamps array, mapping each stampId to its respective pageNumber.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- documentInfoobjectrequiredNo description.
2 fields
- namestringrequiredRequired. File name of the document (e.g. "Loan_Agreement.pdf"). Used for reference only.minLength 1
- contentstringrequiredRequired. Base64-encoded content of the PDF to stamp. Must be a valid PDF that is not already signed.minLength 1
- stampsarray<object>requiredRequired. At least one mapping of a procured stamp to a page. Stamps that are not found, not yours, or not in PROCURED status are skipped; the request fails if none can be applied.
Each item: 3 fields
- stampIdstring (uuid)requiredRequired. ID of the procured stamp (GUID). Use the `eStampId` returned by the details-by-statecode API.
- pageNumberinteger (int32)requiredRequired. 1-based page number of your PDF where the stamp certificate is inserted.
- externalEStampIdstringoptionalOptional. Not used when applying the stamp; any value sent here is ignored.nullable
- referenceIdstringrequiredRequired. Your unique reference for this request. 1 to 64 characters: letters, digits, hyphen (-) and underscore (_) only. A reference that was already used is rejected.minLength 1
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
5 fields
- documentIdstring (uuid)optionalNo description.nullable
- stampedFileBase64stringoptionalNo description.nullable
- stampsAppliedinteger (int32)optionalNo description.nullable
- appliedStampIdsarray<string>optionalNo description.nullable
- messagestringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Place a bulk physical e-stamp certificate request.
Place a bulk order for multiple physical e-stamp certificates in a single API call. Each item in the series array defines an independent stamp specification — article type, denomination, quantity, and purpose. A unique batchId is returned to track the entire order.
Key Benefits:
→ Pre-order multiple stamp certificates across different article types and denominations in one request.
→ Group all stamp specifications under a single batchId for easy tracking and reference.
→ Receive an automated webhook notification when all certificates in the batch are ready for use.
→ Pre-procured certificates are allocated instantly to matching stamp orders — no real-time government portal delays.
Use Cases:
→ Financial institutions pre-ordering stamp inventory for high-volume loan disbursement workflows.
→ Legal and compliance teams securing stamp certificates in advance for large-scale documentation.
→ Enterprises managing stamp requirements across multiple agreements with the same parties.
→ Automated document generation pipelines that need guaranteed stamp availability before processing.
Request Body Parameters:
→ stateCode (required): 2-letter Indian state code where the stamps will be used (e.g. GJ, MH, DL). Letter case is ignored. Use the branch_code values from GET /branches; any other code is rejected.
→ firstPartyName (required): Full legal name of the primary party to the agreement (e.g. lender, issuer). Printed on the certificate as "First Party".
→ secondPartyName (required): Full legal name of the secondary party (e.g. borrower, buyer). Printed on the certificate as "Second Party".
→ stampDutyPaidBy (required): Party responsible for paying the stamp duty. Accepted values: FIRST_PARTY or SECOND_PARTY (letter case is ignored). Printed on the certificate.
→ webhookUrl (optional): Publicly reachable HTTPS URL to receive a POST callback when all certificates are ready. If omitted, no notification is sent.
→ series (required): Array of one or more stamp specifications. Each item supports the following fields:
→ → articleId (required): Numeric article ID (the id field) for the document type, state-specific, greater than zero. Retrieve from GET /articles/{branch}.
→ → stampDutyAmount (required): Face value of each certificate in Indian Rupees, greater than zero. This is the denomination printed on the certificate, not the total order cost.
→ → noOfStamps (required): Number of individual certificates needed for this article and denomination. Each certificate carries a unique government-issued certificate number. Minimum: 5. Maximum: 10000. Requests outside this range will be rejected.
→ → considerationPrice (required): Value of the underlying transaction in Indian Rupees (loan amount, property value, contract value). Must not be negative. Printed on the certificate for legal validity.
→ → purpose (required): Reason the stamp duty is being paid. Printed on the certificate (e.g. Loan Agreement, Lease Deed, Power of Attorney). Must not be empty.
→ → articleDescription (optional): Human-readable article name, stored with the order.
Wallet check: the request is rejected if your available wallet balance, after pending bulk requests, is lower than the sum of stampDutyAmount × noOfStamps across all series items.
Response Details:
→ batchId: Unique UUID identifying the entire bulk order. Store this value — it is used to track the order status and reference the certificates when placing individual stamp orders.
→ totalSeries: Number of distinct stamp specifications registered, equal to the count of items in the series array.
→ totalStamps: Total number of individual certificates ordered across all series items (sum of all noOfStamps values).
→ stampStatus: Current batch lifecycle status. PENDING — certificates are being prepared. UPLOADED — all certificates are ready and available for use.
Note: This call only reserves/pre-orders the certificates — it does not issue a usable stamp. Once stampStatus is UPLOADED (or a series is individually marked UPLOADED), procure the actual certificate by calling POST /create-single-order with the same stateCode, firstPartyName, secondPartyName, stampDutyPaidBy, and per-series details (articleId, stampDutyAmount, considerationPrice, purpose) used in this bulk request.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- stateCodestringrequiredRequired. Two-letter state code where the stamps will be used (e.g. GJ, MH, DL). Letter case is ignored. Use the branchCode returned by the branches API; any other code is rejected.minLength 1default GJ
- firstPartyNamestringrequiredRequired. Full legal name of the first party (e.g. lender), printed on the certificate.minLength 1default First Party Name
- secondPartyNamestringrequiredRequired. Full legal name of the second party (e.g. borrower), printed on the certificate.minLength 1default Second Party Name
- stampDutyPaidBystringrequiredRequired. Party that pays the stamp duty. Allowed values: "FIRST_PARTY" or "SECOND_PARTY" (letter case is ignored).minLength 1default FIRST_PARTY
- webhookUrlstringoptionalOptional. URL that receives a callback when all certificates in the batch are ready. If omitted, no notification is sent.nullabledefault https://example.com/webhooks/physica…
- seriesarray<object>requiredRequired. One or more stamp specifications, at least one. Each item is ordered independently.
Each item: 6 fields
- stampDutyAmountnumber (double)requiredRequired. Face value of each certificate in INR (the denomination printed on the certificate). Must be greater than zero.default 300
- articleIdinteger (int32)requiredRequired. Numeric article ID (the `id` field) for the document type, from the articles API for the same state. Must be greater than zero.default 1342
- purposestringrequiredRequired. Reason the stamp duty is paid, printed on the certificate (e.g. "Loan Agreement"). Must not be empty.minLength 1default Loan Agreement
- considerationPricenumber (double)requiredRequired. Value of the underlying transaction in INR. Must not be negative.default 50000
- articleDescriptionstringoptionalOptional. Human-readable article name, stored with the order.nullable
- noOfStampsinteger (int32)requiredRequired. Number of certificates to order for this article and denomination. Whole number from 5 to 10000.min 5max 10000default 100
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
4 fields
- batchIdstringoptionalNo description.nullable
- totalSeriesinteger (int32)optionalNo description.
- totalStampsinteger (int32)optionalNo description.
- stampStatusstringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Get an aggregated stamp inventory summary for the calling company.
Returns a single aggregated summary object — not a list. Pass any combination of filters to narrow the scope. Omit all filters to get the full company-wide summary.
Filter Parameters (all optional, sent in the JSON request body):
→ stateCode: Exact 2-letter Indian state code in uppercase (e.g. GJ, MH). Case-sensitive.
→ firstPartyName: Partial match on the primary party name (case-sensitive).
→ secondPartyName: Partial match on the secondary party name (case-sensitive).
→ stampDutyPaidBy: Exact match — FIRST_PARTY or SECOND_PARTY in uppercase.
→ stampDutyAmount: Filter by specific stamp denomination (e.g. 300).
→ articleId: Filter by specific numeric article ID.
Response Details:
Requested stamps (from your bulk stamp requests): → totalRequestedStamps: Total number of stamps you have requested across all matching bulk orders.
→ uploadedStamps: Number of requested stamps that have been fulfilled and are ready (status UPLOADED).
→ pendingStamps: Number of requested stamps still being prepared (not yet UPLOADED).
Actual inventory (physical certificates in the vault): → available: Certificates ready to be used — not yet assigned to any order.
→ allocated: Certificates bound to an order but not yet applied to a document.
→ consumed: Certificates already applied to a document (terminal state).
→ cancelled: Certificates that have been voided or cancelled.
→ pendingUpload: Placeholder slots where the certificate has not yet been uploaded by the administrator.
→ totalInventory: Total count of all inventory rows matching the filter (sum of all statuses above).
Note:totalInventory may differ from totalRequestedStamps — inventory counts include certificates from single orders and prior batches that share the same stamp criteria.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- stateCodestringoptionalOptional. Exact two-letter state code, in uppercase (e.g. GJ, MH). Matching is case-sensitive.nullable
- firstPartyNamestringoptionalOptional. Part of the first party name. Matches any name that contains this text (case-sensitive).nullable
- secondPartyNamestringoptionalOptional. Part of the second party name. Matches any name that contains this text (case-sensitive).nullable
- stampDutyPaidBystringoptionalOptional. Exact payer value: "FIRST_PARTY" or "SECOND_PARTY" in uppercase. Matching is case-sensitive.nullable
- stampDutyAmountnumber (double)optionalOptional. Stamp denomination in INR to filter by (e.g. 300).nullable
- articleIdinteger (int32)optionalOptional. Numeric article ID to filter by.nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
9 fields
- totalRequestedStampsinteger (int32)optionalNo description.
- uploadedStampsinteger (int32)optionalNo description.
- pendingStampsinteger (int32)optionalNo description.
- availableinteger (int32)optionalNo description.
- allocatedinteger (int32)optionalNo description.
- consumedinteger (int32)optionalNo description.
- cancelledinteger (int32)optionalNo description.
- pendingUploadinteger (int32)optionalNo description.
- totalInventoryinteger (int32)optionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500