Template Management API
7 endpoints · Core API
The Template Management API allows users to create, retrieve, preview, and manage document templates dynamically. It enables reusable document structures with variable data placeholders, helping organizations automate document generation workflows, such as contracts, onboarding forms, or agreements.
Benefits
- Reusable TemplatesDefine once, use many times for standardized documents.
- Dynamic ContentSupports variable insertion into templates for personalized documents.
- Preview SupportGenerate real-time previews before sending or signing.
- Streamlined Document GenerationReduces manual effort in document creation.
What you can do
- Create or upload new document templates
- Preview filled templates with dynamic data
- Fetch existing templates for document generation
- Render a template to a PDF from field values alone
Two flows share these templates
Template render you just need the file. POST /template/render takes a template id and its field values and returns the filled PDF as base64. No signers are accepted, no document is created and no signing workflow starts. Charged as a Template API call, the same rate as /template/request. A validation error, an unknown template or an insufficient balance is not charged.
Template + Signer the document has to be signed. POST /template/preview renders it with the signer list so you can check it first, then POST /template/request creates the document and sends it for signature. Use these two together whenever a signature is the point.
Three flows share these templates. Pick the one that matches your use case.
A template is a reusable Word document with named placeholders. You send the values, SignCare fills them in. What differs is whether a signature is involved.
- Template + Signer flow — the filled document has to be signed. Preview it, then send it for signature.
- Template + eStamp + Signer flow — the document has to carry a SHCIL e-stamp and be signed. One request buys the stamp, creates the signing document and invites the signers.
- Template render — you just need the file. No signers, no signing workflow, nothing created on the SignCare side.
Choosing an endpoint
| Endpoint | Flow | What you get back | Signers | Creates a document |
|---|---|---|---|---|
POST /api/v1/Template/render | Template render | The filled PDF, as base64 | Not accepted | No |
POST /api/v1/Template/preview | Template + Signer | The filled PDF, as base64 | Part of the request | No |
POST /api/v1/Template/request | Template + Signer | A document id + signing details | Required | Yes — invites are sent |
POST /api/v1/Template/request with shcilStampInfo | Template + eStamp + Signer | The stamp and signing details in the same response (up to about 40 seconds), otherwise a 202 and the result from the status API | Required | Yes — the stamp is bought, then invites are sent |
POST /api/v1/Template/request/status | Template + eStamp + Signer | The result of an earlier request | Not accepted | No |
Template render — when the document is the deliverable
Statements, receipts, certificates, sanction letters, filled-in forms — anything you are going to store, email or hand to a customer yourself. You send a template id and field values, you get a PDF back, and that is the whole interaction. No signer information is accepted and none is needed.
Template + Signer — when the document has to be signed
preview renders the document so you (or your user) can check it before committing. request then fills the same template, creates a document in your SignCare account, attaches the signers you name, and starts the signing workflow. Use these two together whenever a signature — Aadhaar, DSC or electronic — is the point.
Not sending the document for signature? Use /Template/render.
preview belongs to the signing flow: its request body carries the signer list you are about to send to, and it exists so you can check the document before request goes out.
If no signature is involved, render is the endpoint built for that — it takes template id and fields only, validates the values you send, and is not limited to templates created by the same user as the API key you are calling with.
Template + eStamp + Signer — when the document needs a SHCIL stamp
Some agreements must carry a SHCIL e-stamp before they are signed. Send the same POST /api/v1/Template/request you already use, and add a shcilStampInfo block. SignCare then buys the stamp, places it in the document, creates the signing document and invites the signers — in one request.
The call waits up to about 40 seconds for the stamp and the signing document:
- Ready in time: the result comes back in the same response (
200 OK). - Not ready in time: you get
202 Acceptedand collect the result from the status API. - Webhook (optional): if you give a
responseUrl, or one is configured for your account, the result is also delivered there.
Request
{
"referenceId": "AGREEMENT-2026-0001",
"templateId": "8f14e45f-ceea-467a-9f0a-1c2b3d4e5f60",
"documentName": "Service Agreement",
"signers": [
{
"userId": "d45cdb43-36d9-425f-8755-cd8432ca0968",
"name": "Rahul Patel",
"emailId": "rahul@example.com",
"mobileNo": "9876543210",
"signType": "Aadhaar",
"order": 1
},
{
"userId": "51456781-ec6f-4c11-ae59-3160f64beac6",
"name": "Meera Shah",
"emailId": "meera@example.com",
"signType": "Electronic",
"order": 2
}
],
"fields": [
{ "displayName": "Party Name", "required": false, "type": "Text", "fieldName": "{{var_PartyName}}", "fieldValue": "Rahul Patel" }
],
"shcilStampInfo": {
"firstPartyName": "Rahul Patel",
"firstPartyMobile": "9876543210",
"firstPartyPan": "ABCDE1234F",
"secondPartyName": "Meera Shah",
"secondPartyMobile": "9876543211",
"stateCode": "AS",
"articleCode": 42,
"stampDutyAmount": 100,
"stampDutyPaidBy": "Rahul Patel",
"documentDescription": "Service Agreement"
},
"responseUrl": "https://your-server.example.com/signcare/callback"
}referenceId — your own id for this request, 1 to 64 letters, digits, hyphens or underscores. It can be used once. A request that failed before a stamp was issued can be sent again with the same id.
signers[].userId — the signer position in the template, as returned by GET /api/v1/Template/get. Each position can be used only once.
responseUrl — optional. If you give one (or a webhook URL is configured for your account), the result is also delivered there. Without a webhook, use the response of this call or the status API.
shcilStampInfo field | Required | Rules |
|---|---|---|
stateCode | Yes | The stateCode of the article you chose, from the Master Details API (see below). |
articleCode | Yes | The articleCode of a row in pdfArticles in the Master Details response. Rows in templateArticles do not work with this flow. |
stampDutyAmount | Yes | Whole rupees, at least the article's minimum duty. |
stampDutyPaidBy | Yes | Must be exactly the first party's or second party's name. |
firstPartyName, secondPartyName | At least one | English letters and spaces only, up to 200 characters. |
firstPartyMobile, secondPartyMobile | For the party that pays | Exactly 10 digits. |
firstPartyPan, secondPartyPan | When the duty is above ₹2,00,000 | Valid PAN, for example ABCDE1234F. |
considerationPrice | No | Not negative. |
documentDescription | No | Up to 100 characters: letters, numbers and spaces only. |
Choosing the state and the article
Take both values from the SHCIL Master Details API, GET /api/v1/StockHoldingEStamp/master-details. Its response has three lists:
| List | What it is for | Use it here? |
|---|---|---|
states | The states SHCIL stamping is available in. | Yes — stateCode must be one of these. |
pdfArticles | Articles stamped onto your own PDF. Every row has articleType set to CUSTOM. | Yes — this is the only list to use. |
templateArticles | Articles where SHCIL generates the document from fields. Every row has articleType set to SYSTEM. | No. This flow sends your rendered template as a PDF. A request that uses one of these articles is rejected. |
- Call the Master Details API.
- Choose the state from
states. - In
pdfArticles, find the rows whosestateCodeis that state and choose the article you need. - Send that row's
stateCodeandarticleCodeinshcilStampInfo, exactly as listed. Another code that belongs to the same article, but is not listed inpdfArticles, is not accepted.
The same row tells you the rules for the rest of the request:
Field in the pdfArticles row | What it means for your request |
|---|---|
minDuty, maxDuty | stampDutyAmount must be within this range. |
bothPartyRequired | When true, send the name and mobile number of both parties (firstPartyName, firstPartyMobile, secondPartyName, secondPartyMobile). |
stampDutyType | When CONSIDERATION_PRICE, the duty depends on the transaction value: send considerationPrice. minConsiderationPrice and maxConsiderationPrice, when present, show the accepted range. |
articleName | The article's name, for display. |
{
"stateCode": "AS",
"articleCode": 42,
"articleName": "Agreement or Memorandum of an agreement - Agreements other than applicable under 5(a) and 5(b)",
"minDuty": "100.0",
"articleType": "CUSTOM",
"bothPartyRequired": true
}The Master Details API needs the SHCIL eStamp API to be enabled for your account. If it is not, the call is refused and you cannot look up articles.
Everything is checked before a stamp is bought
A request that fails any of these checks is rejected immediately with an error, and nothing is charged and no stamp is bought.
| Area | What is checked |
|---|---|
| Template | The template id is valid and the template exists. |
| Reference id | Valid format, and not used before. |
| Document name | Present, valid characters, under 50 characters. |
| Signers | At least one signer. Each signer position belongs to the template and is used once. Name is valid. At least one of email or mobile number. Signature type, Aadhaar details and signing order are valid. |
| eSign access | The eSign API is enabled for your account and subscribed, and your eSign wallet balance covers each signature type. |
| SHCIL details | The article is listed under pdfArticles (articleType CUSTOM) for that state. The duty is within the article's range. Both parties are given when the article requires it. PAN and mobile rules are met, and stampDutyPaidBy matches a party. |
| Names and description | Party names and the document description contain no special characters. |
| SHCIL wallet | The balance covers this stamp plus all of your earlier stamps that are still in progress. |
The response
How the call ends depends on how long the stamp takes:
| Outcome | HTTP status | Body |
|---|---|---|
| Ready within about 40 seconds | 200 OK | The result, as shown under The result below |
| Failed within that time | The error's own status, for example 400, 402 or 500 | The failure, as shown under When it failed below |
| Takes longer | 202 Accepted | The accepted response shown next |
The 202 Accepted response:
{
"data": {
"documentReferenceId": "AGREEMENT-2026-0001",
"reconMappingId": "SCABCDEFGHIJKLMNOPQR",
"status": "ACCEPTED"
},
"success": true,
"statusCode": 202,
"message": "Accepted. eStamp generation is taking longer than usual — fetch the stamped document and eSign links from the Template request status API using this referenceId. Do not retry this referenceId."
}Keep documentReferenceId and reconMappingId; either one identifies this request later. Sending the same referenceId again while it is in progress waits for that same request and returns its result, or this same 202. It does not create a second stamp.
The result
The result body is the same in all three places: the 200 response, the status API and the webhook.
A webhook is an HTTP POST, and the x-signcare-event header tells you which result it is:
x-signcare-event | Meaning |
|---|---|
TEMPLATE_ESTAMP_ESIGN_CREATED | The stamp was issued and the signing document was created. |
TEMPLATE_ESTAMP_ESIGN_FAILED | The request failed after it was accepted. |
When it succeeded
{
"data": {
"documentId": "01a13924-c53e-7730-a227-e04af1adfa17",
"documentReferenceId": "AGREEMENT-2026-0001",
"responseTimeStamp": "14-10-2026 06:41:13",
"userInfo": [
{
"userRefId": "d45cdb43-36d9-425f-8755-cd8432ca0968",
"userId": "fa6f7481-e512-44a5-a969-81392925de96",
"docSignerId": "d0e36467-ee3c-4766-982d-df654591851f",
"esignLink": "https://sign.example.com/sign/d0e36467-ee3c-4766-982d-df654591851f/rahul@example.com"
},
{
"userRefId": "51456781-ec6f-4c11-ae59-3160f64beac6",
"userId": "e21be59a-19c0-44de-b841-92fe48e3283d",
"docSignerId": "892e587c-f847-4e04-984c-d2a493782459",
"esignLink": "https://sign.example.com/sign/892e587c-f847-4e04-984c-d2a493782459/meera@example.com"
}
],
"uiModeURL": "",
"stampDetails": {
"eStampId": "943cdb8f-7ae2-4005-99c5-282de8cb7282",
"reconMappingId": "SCABCDEFGHIJKLMNOPQR",
"userDocumentId": 120886,
"certId": "IN-AS00363558894070Y",
"urn": "AS1004DIGID2026287376478ASAC",
"certificateNo": "IN-AS00363558894070Y",
"certificateIssuedDate": "14-Oct-2026 12:11 PM"
}
},
"success": true,
"statusCode": 200
}The signers also receive their signing link by email or SMS. Later signing updates for the same document (signed, rejected, expired) are delivered through the usual eSign webhook.
When it failed
{
"data": {
"documentReferenceId": "AGREEMENT-2026-0001",
"reconMappingId": "SCABCDEFGHIJKLMNOPQR",
"status": "FAILED"
},
"success": false,
"statusCode": 400,
"message": "Insufficient StockHolding wallet balance. The stamp was not generated and nothing was charged. Recharge the wallet and submit the request again."
}message gives the reason. If the stamp had already been issued before the failure, data.stampDetails is included — quote it to support so the stamp can be recovered. Otherwise nothing was charged, and you can send the request again with the same referenceId. Once a stamp has been issued, that referenceId cannot be reused.
Checking a result — POST /api/v1/Template/request/status
Use this API when the call returned 202, or when you do not use a webhook. It returns the same body that the 200 response carries, or that would be sent to your responseUrl.
- It answers
200for a finished request, including a failed one. ReadsuccessandstatusCodein the body. - Suggested schedule after a
202: after 30 seconds, 1 minute and 5 minutes, then every 15 minutes. - It is free, and it only shows requests made with your own account.
{
"documentReferenceId": "AGREEMENT-2026-0001"
}Send documentReferenceId, reconMappingId, or both. If you send both they must belong to the same request.
| HTTP status | Meaning | What you receive |
|---|---|---|
202 | The request is still in progress. | The same slim body as the original 202. Check again shortly. |
200 | The request has finished. | The success body, or the failure body — read success, statusCode and message, exactly as in the webhook. |
400 | Neither id was sent, an id is invalid, or the two ids belong to different requests. | An error message. |
401 | The API key is missing or invalid. | An error message. |
402 | The Template API is not available to your account. | An error message. |
404 | No such request for your account. | An error message. |
A request that has been found always answers with a successful lookup. For a request that failed, the failure code and the reason are in the response body, not in the HTTP status.
The documentId in a successful response is the id you need for the other eSign APIs, such as POST /api/v1/esign/status.
If the result has not arrived after a few minutes, check the status. A suggested schedule is after 30 seconds, 1 minute and 5 minutes, then every 15 minutes.
Billing and wallets
| Item | When it is charged |
|---|---|
| Stamp duty and any service charge | Debited from your SHCIL stamp wallet when the stamp is issued. Nothing is debited if the request is rejected or fails before the stamp is issued. |
| Template API call | Billed as a Template API call when the signing document is created. |
| eSign | Billed as for any eSign request, according to your eSign pricing. |
Keep enough balance for the stamp and for any earlier stamps still in progress. A request is rejected if the wallet cannot cover them.
Things to know
- A stamp that SHCIL has not completed yet keeps the request in progress. The signing document is created automatically when SHCIL completes the stamp, and the result is then delivered.
- Do not submit the same
referenceIdagain while a request is in progress. Wait for the result, or check the status. - Party names accept English letters and spaces only, because SHCIL does not accept special characters.
Rendering a document
{
"templateId": "8f14e45f-ceea-467a-9f0a-1c2b3d4e5f60",
"documentName": "Sanction Letter - Rahul Patel",
"fields": [
{ "displayName": "Borrower Name", "fieldName": "borrower_name", "type": "text", "fieldValue": "Rahul Patel" },
{ "displayName": "Sanction Amount", "fieldName": "sanction_amount", "type": "number", "fieldValue": "450000" },
{ "displayName": "Sanction Date", "fieldName": "sanction_date", "type": "date", "fieldValue": "2026-08-26" }
]
}data in the response is the finished PDF, base64-encoded. Decode it and write it to a file — there is nothing further to poll or fetch.
templateId — required. The template id (GUID) from GET /api/v1/Template/get, which also returns each template's field definitions so you know what to send.
documentName — optional. Names the generated PDF; defaults to the template's own name.
fields — required, with at least one entry, when the template declares fields. Copy each field's displayName, fieldName and type exactly as returned by GET /api/v1/Template/get, and add fieldValue. All three are required on every entry; a request that leaves one out is rejected with a 400. The value is placed in the document by fieldName; the required-field and type checks use displayName. Matching is case-insensitive. You may leave out optional fields. (request is stricter — it expects one entry for every field the template declares.)
Send fieldValue as a string. Date values must parse as a date (for example 2026-08-26) and number values as a number (for example 450000).
Field values are validated
A field declared as date must parse as a date, a field declared as number must parse as a number, and a field marked required must carry a non-empty value. If any of these fail you get a 400 naming the field, and the call is not charged.
Billing
render is charged as a Template API call — the same rate as /Template/request. Rendering a PDF and creating a full signature request cost the same. Budget accordingly if you are generating documents in volume.
You are charged only when a PDF is actually produced. None of these cost anything:
- a validation error on your field values (
400) - a template id that does not exist (
404) - an insufficient wallet balance (
402)
Limits
render is rate limited to 50 requests per minute per API key + IP. Large templates take longer to render than small ones; a request is answered when the PDF is complete, so allow a generous client-side timeout for long documents.
Lists the templates created by the user that owns your API key, with their signers and field definitions.
Takes no parameters. Use the templateId, signer userId values and field
fieldName, displayName and type values from this response when calling
render, preview and 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
- dataarray<object>optionalNo description.nullable
Each item: 4 fields
- templateIdstringoptionalNo description.nullable
- templatenNamestringoptionalNo description.nullable
- signersarray<object>optionalNo description.nullable
Each item: 9 fields
- userIdstringrequiredRequired. Signer id from the template, as returned by GET /api/v1/Template/get. Must be a GUID that belongs to the template.nullable
- namestringrequiredRequired. Full name of the signer: letters, digits, spaces and , @ _ . ' - ( ) [ ].nullable
- emailIdstringconditionalConditional: required when mobileNo is not sent. Email address of the signer. At least one of emailId / mobileNo must be present per signer; the signature-create handler enforces that, and rejects a malformed address.nullable
- mobileNostringconditionalConditional: required when emailId is not sent. 10-digit mobile number of the signer, digits only, used instead of emailId when the signer has no email address — the invitation and the sign OTP then go by SMS. At least one of emailId / mobileNo must be present per signer.nullable
- signTypestringrequiredRequired. Signature method: Electronic, Aadhaar or Digital (case-sensitive).nullable
- orderinteger (int32)optionalOptional. Signing order position, starting at 1. Defaults to 0. Signing order is not currently enforced.
- electronicOptionsobjectoptionalNo description.
5 fields
- canDrawbooleanoptionalNo description.
- canTypebooleanoptionalNo description.
- canUploadbooleanoptionalNo description.
- captureGPSLocationbooleanoptionalNo description.
- capturePhotobooleanoptionalNo description.
- aadhaarInfoobjectoptionalNo description.
3 fields
- birthYearstringoptionalNo description.nullable
- lastFourDigitOfAadhaarstringoptionalNo description.nullable
- genderstringoptionalNo description.nullable
- signatorySealInfoobjectoptionalNo description.
2 fields
- namestringoptionalOptional. Organization name printed in the seal text, for example ABC Pvt Ltd.nullable
- sealTypeinteger (int32)optionalOptional. Label shown below the signature: 1 = Authorised Signatory, 2 = Director, 3 = Company Seal. Any other value is rejected.nullable
- templateFieldsarray<object>optionalNo description.nullable
Each item: 22 fields
- displayNamestringrequiredRequired. Field label, exactly as returned by GET /api/v1/Template/get. Used for the required-field and type checks (case-insensitive).nullable
- requiredbooleanoptionalOptional. Whether the field is mandatory. The template's own setting is what is enforced; defaults to false.
- typestringrequiredRequired. Field type, exactly as returned by GET /api/v1/Template/get (for example text, date, number, image).nullable
- fieldNamestringrequiredRequired. Placeholder name in the template document, exactly as returned by GET /api/v1/Template/get. The value is placed by this name (case-insensitive).nullable
- fieldValuestringconditionalConditional: required when the template marks the field as required. Value to fill in, as a string. Date values must parse as a date and number values as a number.nullable
- imageWidthnumber (float)optionalNo description.nullable
- imageHeightnumber (float)optionalNo description.nullable
- imageBorderbooleanoptionalNo description.nullable
- boxCountinteger (int32)optionalBoxed fields only: how many character boxes the template reserves. Left null the renderer derives it from the table row the marker sits in, which is the usual case — the form itself is the source of truth for how many boxes exist.nullable
- uppercasebooleanoptionalForce the value to upper case. Forms that say "BLOCK LETTERS" want this.nullable
- spacePolicystringoptional"blank" (a space occupies a box) or "skip" (spaces are dropped).nullable
- overflowPolicystringoptional"reject" (default) or "truncate" when the value needs more boxes than exist.nullable
- dateFormatstringoptionalDate fields: .NET format string applied to the parsed value, e.g. "dd/MM/yyyy".nullable
- decimalPlacesinteger (int32)optionalNo description.nullable
- thousandSeparatorbooleanoptionalNo description.nullable
- optionsarray<string>optionalCheckbox: the options in the group — one marker is authored per option, and the field's value selects which of them is ticked.nullable
- checkedMarkstringoptionalGlyph written into a ticked box. Defaults to a check mark "✓".nullable
- checkedMarkFontstringoptionalFont for the tick. Null inherits the surrounding text's font, which may not carry the check-mark glyph — set a font with symbol coverage if a tick renders as a hollow box.nullable
- multiSelectbooleanoptionalCheckbox groups: allow more than one option to be ticked.nullable
- displayTagstringoptionalLayout types: the single character the editor shows at the field's anchor so the author can see it is there. Author-chosen, defaults to "▫". Stripped before the value is placed, so it never appears in the rendered document.nullable
- maxLengthinteger (int32)optionalValue types: reject a value longer than this before the document is created.nullable
- patternstringoptionalValue types: regular expression the value must match (PAN, IFSC, Aadhaar...).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
Renders a template with your field values and returns the PDF as base64, without creating a document.
Part of the Template + Signer flow. The request must include a signers array, but signers
do not change the PDF. Only templates created by the user that owns the API key can be previewed.
Required fields and field types are not checked here; they are checked by 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- templateIdstringrequiredRequired. Identifier (GUID) of the template to preview, as returned by GET /api/v1/Template/get. Only templates created by the user that owns the API key can be previewed.nullable
- documentNamestringrequiredRequired. Name of the document for the preview. The preview PDF is named after the template; this value is not used for the file.nullable
- signersarray<object>requiredRequired. Array of signers; it must be present but may be empty. Signers do not change the preview PDF. Each signer needs userId, name and signType.nullable
Each item: 9 fields
- userIdstringrequiredRequired. Signer id from the template, as returned by GET /api/v1/Template/get. Must be a GUID that belongs to the template.nullable
- namestringrequiredRequired. Full name of the signer: letters, digits, spaces and , @ _ . ' - ( ) [ ].nullable
- emailIdstringconditionalConditional: required when mobileNo is not sent. Email address of the signer. At least one of emailId / mobileNo must be present per signer; the signature-create handler enforces that, and rejects a malformed address.nullable
- mobileNostringconditionalConditional: required when emailId is not sent. 10-digit mobile number of the signer, digits only, used instead of emailId when the signer has no email address — the invitation and the sign OTP then go by SMS. At least one of emailId / mobileNo must be present per signer.nullable
- signTypestringrequiredRequired. Signature method: Electronic, Aadhaar or Digital (case-sensitive).nullable
- orderinteger (int32)optionalOptional. Signing order position, starting at 1. Defaults to 0. Signing order is not currently enforced.
- electronicOptionsobjectoptionalNo description.
5 fields
- canDrawbooleanoptionalNo description.
- canTypebooleanoptionalNo description.
- canUploadbooleanoptionalNo description.
- captureGPSLocationbooleanoptionalNo description.
- capturePhotobooleanoptionalNo description.
- aadhaarInfoobjectoptionalNo description.
3 fields
- birthYearstringoptionalNo description.nullable
- lastFourDigitOfAadhaarstringoptionalNo description.nullable
- genderstringoptionalNo description.nullable
- signatorySealInfoobjectoptionalNo description.
2 fields
- namestringoptionalOptional. Organization name printed in the seal text, for example ABC Pvt Ltd.nullable
- sealTypeinteger (int32)optionalOptional. Label shown below the signature: 1 = Authorised Signatory, 2 = Director, 3 = Company Seal. Any other value is rejected.nullable
- fieldsarray<object>requiredRequired. Field values to fill in. Each entry needs displayName, fieldName and type exactly as returned by GET /api/v1/Template/get, plus fieldValue. Values are placed by fieldName. Preview does not check required fields or value types.nullable
Each item: 22 fields
- displayNamestringrequiredRequired. Field label, exactly as returned by GET /api/v1/Template/get. Used for the required-field and type checks (case-insensitive).nullable
- requiredbooleanoptionalOptional. Whether the field is mandatory. The template's own setting is what is enforced; defaults to false.
- typestringrequiredRequired. Field type, exactly as returned by GET /api/v1/Template/get (for example text, date, number, image).nullable
- fieldNamestringrequiredRequired. Placeholder name in the template document, exactly as returned by GET /api/v1/Template/get. The value is placed by this name (case-insensitive).nullable
- fieldValuestringconditionalConditional: required when the template marks the field as required. Value to fill in, as a string. Date values must parse as a date and number values as a number.nullable
- imageWidthnumber (float)optionalNo description.nullable
- imageHeightnumber (float)optionalNo description.nullable
- imageBorderbooleanoptionalNo description.nullable
- boxCountinteger (int32)optionalBoxed fields only: how many character boxes the template reserves. Left null the renderer derives it from the table row the marker sits in, which is the usual case — the form itself is the source of truth for how many boxes exist.nullable
- uppercasebooleanoptionalForce the value to upper case. Forms that say "BLOCK LETTERS" want this.nullable
- spacePolicystringoptional"blank" (a space occupies a box) or "skip" (spaces are dropped).nullable
- overflowPolicystringoptional"reject" (default) or "truncate" when the value needs more boxes than exist.nullable
- dateFormatstringoptionalDate fields: .NET format string applied to the parsed value, e.g. "dd/MM/yyyy".nullable
- decimalPlacesinteger (int32)optionalNo description.nullable
- thousandSeparatorbooleanoptionalNo description.nullable
- optionsarray<string>optionalCheckbox: the options in the group — one marker is authored per option, and the field's value selects which of them is ticked.nullable
- checkedMarkstringoptionalGlyph written into a ticked box. Defaults to a check mark "✓".nullable
- checkedMarkFontstringoptionalFont for the tick. Null inherits the surrounding text's font, which may not carry the check-mark glyph — set a font with symbol coverage if a tick renders as a hollow box.nullable
- multiSelectbooleanoptionalCheckbox groups: allow more than one option to be ticked.nullable
- displayTagstringoptionalLayout types: the single character the editor shows at the field's anchor so the author can see it is there. Author-chosen, defaults to "▫". Stripped before the value is placed, so it never appears in the rendered document.nullable
- maxLengthinteger (int32)optionalValue types: reject a value longer than this before the document is created.nullable
- patternstringoptionalValue types: regular expression the value must match (PAN, IFSC, Aadhaar...).nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- 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 Requestsame body as 200
401Unauthorizedsame body as 200
500Internal Server Errorsame body as 200
Code samplescurl · Node.js · Python
Renders a template to a PDF from field values alone and returns it as base64. This is the template-render flow: document generation with no signer association at all. No signers are accepted, no document is created and no signing workflow starts. The Template + Signer flow is separate and unchanged — `/preview` renders a document together with its signer list so it can be checked, and `/request` then creates it and sends it for signature. Billed as a Template API call, the same as `/request`: it checks the wallet and debits on success. A validation error, an unknown template or an empty wallet costs nothing. Rate limited on the client+IP bucket (50/min) rather than the 1-per-5-minutes default: that default exists to throttle per-call provider cost, and rendering calls no provider.
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- templateIdstringrequiredRequired. Identifier (GUID) of the template to render, as returned by GET /api/v1/Template/get.nullable
- documentNamestringoptionalOptional. Name of the generated PDF. Defaults to the template's own name.nullable
- fieldsarray<object>conditionalConditional: required, with at least one entry, when the template declares fields. Field values to fill in. Each entry needs displayName, fieldName and type exactly as returned by GET /api/v1/Template/get, plus fieldValue. Values are placed by fieldName; required and type (date, number) checks use displayName. You may leave out optional fields.nullable
Each item: 22 fields
- displayNamestringrequiredRequired. Field label, exactly as returned by GET /api/v1/Template/get. Used for the required-field and type checks (case-insensitive).nullable
- requiredbooleanoptionalOptional. Whether the field is mandatory. The template's own setting is what is enforced; defaults to false.
- typestringrequiredRequired. Field type, exactly as returned by GET /api/v1/Template/get (for example text, date, number, image).nullable
- fieldNamestringrequiredRequired. Placeholder name in the template document, exactly as returned by GET /api/v1/Template/get. The value is placed by this name (case-insensitive).nullable
- fieldValuestringconditionalConditional: required when the template marks the field as required. Value to fill in, as a string. Date values must parse as a date and number values as a number.nullable
- imageWidthnumber (float)optionalNo description.nullable
- imageHeightnumber (float)optionalNo description.nullable
- imageBorderbooleanoptionalNo description.nullable
- boxCountinteger (int32)optionalBoxed fields only: how many character boxes the template reserves. Left null the renderer derives it from the table row the marker sits in, which is the usual case — the form itself is the source of truth for how many boxes exist.nullable
- uppercasebooleanoptionalForce the value to upper case. Forms that say "BLOCK LETTERS" want this.nullable
- spacePolicystringoptional"blank" (a space occupies a box) or "skip" (spaces are dropped).nullable
- overflowPolicystringoptional"reject" (default) or "truncate" when the value needs more boxes than exist.nullable
- dateFormatstringoptionalDate fields: .NET format string applied to the parsed value, e.g. "dd/MM/yyyy".nullable
- decimalPlacesinteger (int32)optionalNo description.nullable
- thousandSeparatorbooleanoptionalNo description.nullable
- optionsarray<string>optionalCheckbox: the options in the group — one marker is authored per option, and the field's value selects which of them is ticked.nullable
- checkedMarkstringoptionalGlyph written into a ticked box. Defaults to a check mark "✓".nullable
- checkedMarkFontstringoptionalFont for the tick. Null inherits the surrounding text's font, which may not carry the check-mark glyph — set a font with symbol coverage if a tick renders as a hollow box.nullable
- multiSelectbooleanoptionalCheckbox groups: allow more than one option to be ticked.nullable
- displayTagstringoptionalLayout types: the single character the editor shows at the field's anchor so the author can see it is there. Author-chosen, defaults to "▫". Stripped before the value is placed, so it never appears in the rendered document.nullable
- maxLengthinteger (int32)optionalValue types: reject a value longer than this before the document is created.nullable
- patternstringoptionalValue types: regular expression the value must match (PAN, IFSC, Aadhaar...).nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- 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
Creates or updates a template — the authoring counterpart to the endpoints above, which only consume templates that already exist. Rate limited on the client+IP bucket (50/min), not the default 1-per-5-minutes used for verification calls: this is a person clicking Save in a designer, and the provider-cost reasoning behind the tight default does not apply.
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- templateIdstring (uuid)optionalOptional. Omit to create a new template; send an existing template id (GUID) to update that template in place.nullable
- namestringrequiredRequired. Template name. It must be unique among your templates (not case-sensitive); a duplicate returns 400.nullable
- documentobjectoptionalNo description.
5 fields
- fileNamestringrequiredRequired. File name of the document, for example offer-letter.docx.nullable
- extensionstringoptionalOptional. File extension including the dot. Defaults to `.docx`.nullable
- datastringrequiredRequired. Base64 of the file, WITHOUT a data-URL prefix.nullable
- fileLocationstringoptionalOptional. Ignored; the storage location is set by the server.nullable
- fileSizeinteger (int32)optionalOptional. File size in bytes. Not used.
- usersarray<object>optionalOptional. Signers, in signing order, each carrying their signature positions.nullable
Each item: 5 fields
- orderNointeger (int32)optionalOptional. Position of the signer in the signing order, starting at 1. Defaults to 0.
- userIdstring (uuid)requiredRequired. Id (GUID) that identifies this signer within the template. Use this same id as signers[].userId when creating a document from the template.
- namestringrequiredRequired. Name of the signer role or person.nullable
- signTypestringoptionalOptional. SignType as a string: 1 Electronic, 2 Aadhaar, 3 Digital (DSC).nullable
- pDFPagesarray<object>optionalNo description.nullable
Each item: 4 fields
- pageNumberinteger (int32)optionalNo description.
- pageSizenumber (float)optionalPage HEIGHT in points. The name is historical.
- pageWidthnumber (float)optionalNo description.
- pdfCoordinatesarray<object>optionalNo description.nullable
Each item: 4 fields
- x1number (float)optionalNo description.
- x2number (float)optionalNo description.
- y1number (float)optionalNo description.
- y2number (float)optionalNo description.
- fieldsstringoptionalOptional. The field definitions, as a JSON ARRAY IN A STRING — not an object. Each entry needs a unique fieldName; duplicate fieldName values return 400. SignCare stores this blob verbatim, which is what lets a caller keep its own metadata (e.g. which workflow step fills a field) alongside the fields themselves.nullable
- departmentIdstringoptionalOptional. Department the template belongs to.nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- 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
Loads a template for editing: the .docx as base64, plus the field and signer definitions exactly as they were saved.
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
- templateIdstringrequiredRequired. Identifier (GUID) of the template to load, in the URL path.
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalEverything needed to reopen a template in an editor.
5 fields
- wordContentstringoptionalNo description.nullable
- namestringoptionalNo description.nullable
- signerInfostringoptionalJSON array in a string — the signers and their signature positions.nullable
- documentFieldsstringoptionalJSON array in a string — the field definitions, exactly as saved.nullable
- stampInfostringoptionalNo 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
Create a document from a template and send it for signing, optionally with a SHCIL eStamp.
Creates a document from a template and sends it to your signers. When SHCIL eStamp details are included, a stamp is purchased first and placed in the document. The request waits up to about 40 seconds for this to finish and returns the result in the same response; if it takes longer, it is accepted and you collect the result afterwards.
How the two options work
| Without eStamp details | With SHCIL eStamp details | |
|---|---|---|
| Processing | Immediate | The request waits up to about 40 seconds for the stamp and the signing document. |
| Successful response | 200 OK with the document and each signer's signing link | 200 OK with the signing links and stamp details when ready within the wait. Otherwise 202 Accepted with the status ACCEPTED. |
| Webhook (response URL) | Optional | Optional. If you provide one (or one is configured for your account) the result is also delivered there. |
| If the result is not in the response | Not applicable | Call the Template request status API with your reference id. It returns the same result at any time. |
| If something goes wrong | An error response straight away | A request that is invalid is rejected straight away and nothing is charged. A failure after the request is accepted is returned in the response when it happens within the wait, otherwise it is available from the status API (and your webhook, if any). |
Checked before any stamp is purchased
When eStamp details are included, the following are verified first. A request that fails any check is rejected immediately and nothing is charged.
| Area | What is checked |
|---|---|
| Template | The template id is valid and the template exists. The template has signer positions. |
| Reference id | 1 to 64 letters, digits, hyphens or underscores, and not used before. |
| Document | A document name is given, uses valid characters and is under 50 characters. |
| Signers | At least one signer. Each signer position belongs to the template and is used only once. Name, email or mobile number (at least one), signature type, Electronic options, Aadhaar details and signing order are valid. |
| eSign access | The eSign API is enabled and subscribed, and the wallet balance covers each signature type. |
| SHCIL details | The article is listed under pdfArticles (articleType CUSTOM) in the Master Details API for that state. Minimum stamp duty (whole rupees), PAN and mobile number rules, and the payer matches one of the parties. |
| Party names | Letters and spaces only, up to 200 characters. |
| Document description | Up to 100 characters: letters, numbers and spaces only. |
| SHCIL wallet | The balance covers this stamp and all of your earlier stamps that are still in progress. |
Response when the result is ready (200)
The body is the same as the response of the Template request status API: the eSign document with each signer's signing link, and the stamp details.
Response when the request is accepted but not ready yet (202)
| Field | Description |
|---|---|
| data: documentReferenceId | Your reference id. |
| data: reconMappingId | The SignCare reconciliation id of the request. |
| data: status | ACCEPTED. |
Do not submit the same reference id again. Submitting it while the request is in progress waits for the same request and returns its result, or the same 202.
Getting the result later
Call the Template request status API with your reference id or the reconciliation id to get the result at any time. A webhook is optional: if you provide a response URL, or one is configured for your account, the same result is also sent there, and the type of result is given in the x-signcare-event header of the notification.
A failure after acceptance
If the stamp or the signing document cannot be completed and this happens within the wait, the response carries the failure with its HTTP status (for example 400, 402 or 500) and the reason in the message. Later failures are available from the status API.
Responses
| HTTP status | Meaning |
|---|---|
| 200 OK | The document was created. With eStamp details this means the stamp and the signing document are both ready. |
| 202 Accepted | The request was accepted but is not ready within the wait. Get the result from the Template request status API (or your webhook). |
| 400 Bad Request | A validation failed. The message states which one. |
| 401 Unauthorized | The API key is missing or invalid. |
| 402 Payment Required | The eSign API is not enabled, or the wallet balance is not sufficient. |
| 403 Forbidden | Your account is not subscribed to the eSign API. |
| 404 Not Found | The template does not exist. |
| 500 Internal Server Error | An unexpected error occurred. |
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- referenceIdstringrequiredRequired. Your own unique reference for the document: 1 to 64 letters, digits, hyphens or underscores. A reference that already exists is rejected.nullable
- templateIdstringrequiredRequired. Identifier (GUID) of the template, as returned by GET /api/v1/Template/get.nullable
- documentNamestringrequiredRequired. Name of the document, up to 50 characters: letters, digits, spaces and , @ _ . ' - ( ) [ ].nullable
- sequentialSigningbooleanoptionalOptional. Accepted but currently ignored: signers are not forced to sign in order. Defaults to false.
- skipVerificationCodebooleanoptionalOptional. Set to true to skip the verification code step for signers. Defaults to false.
- signersarray<object>requiredRequired. Signers for the document, at least one. Each userId must be a signer id from the template (see GET /api/v1/Template/get).nullable
Each item: 9 fields
- userIdstringrequiredRequired. Signer id from the template, as returned by GET /api/v1/Template/get. Must be a GUID that belongs to the template.nullable
- namestringrequiredRequired. Full name of the signer: letters, digits, spaces and , @ _ . ' - ( ) [ ].nullable
- emailIdstringconditionalConditional: required when mobileNo is not sent. Email address of the signer. At least one of emailId / mobileNo must be present per signer; the signature-create handler enforces that, and rejects a malformed address.nullable
- mobileNostringconditionalConditional: required when emailId is not sent. 10-digit mobile number of the signer, digits only, used instead of emailId when the signer has no email address — the invitation and the sign OTP then go by SMS. At least one of emailId / mobileNo must be present per signer.nullable
- signTypestringrequiredRequired. Signature method: Electronic, Aadhaar or Digital (case-sensitive).nullable
- orderinteger (int32)optionalOptional. Signing order position, starting at 1. Defaults to 0. Signing order is not currently enforced.
- electronicOptionsobjectoptionalNo description.
5 fields
- canDrawbooleanoptionalNo description.
- canTypebooleanoptionalNo description.
- canUploadbooleanoptionalNo description.
- captureGPSLocationbooleanoptionalNo description.
- capturePhotobooleanoptionalNo description.
- aadhaarInfoobjectoptionalNo description.
3 fields
- birthYearstringoptionalNo description.nullable
- lastFourDigitOfAadhaarstringoptionalNo description.nullable
- genderstringoptionalNo description.nullable
- signatorySealInfoobjectoptionalNo description.
2 fields
- namestringoptionalOptional. Organization name printed in the seal text, for example ABC Pvt Ltd.nullable
- sealTypeinteger (int32)optionalOptional. Label shown below the signature: 1 = Authorised Signatory, 2 = Director, 3 = Company Seal. Any other value is rejected.nullable
- fieldsarray<object>requiredRequired. Field values to fill in. Send exactly one entry for every field the template declares (the counts must match). Each entry needs displayName, fieldName and type exactly as returned by GET /api/v1/Template/get, plus fieldValue. Required fields must have a non-empty value; date and number fields must parse as a date or number.nullable
Each item: 22 fields
- displayNamestringrequiredRequired. Field label, exactly as returned by GET /api/v1/Template/get. Used for the required-field and type checks (case-insensitive).nullable
- requiredbooleanoptionalOptional. Whether the field is mandatory. The template's own setting is what is enforced; defaults to false.
- typestringrequiredRequired. Field type, exactly as returned by GET /api/v1/Template/get (for example text, date, number, image).nullable
- fieldNamestringrequiredRequired. Placeholder name in the template document, exactly as returned by GET /api/v1/Template/get. The value is placed by this name (case-insensitive).nullable
- fieldValuestringconditionalConditional: required when the template marks the field as required. Value to fill in, as a string. Date values must parse as a date and number values as a number.nullable
- imageWidthnumber (float)optionalNo description.nullable
- imageHeightnumber (float)optionalNo description.nullable
- imageBorderbooleanoptionalNo description.nullable
- boxCountinteger (int32)optionalBoxed fields only: how many character boxes the template reserves. Left null the renderer derives it from the table row the marker sits in, which is the usual case — the form itself is the source of truth for how many boxes exist.nullable
- uppercasebooleanoptionalForce the value to upper case. Forms that say "BLOCK LETTERS" want this.nullable
- spacePolicystringoptional"blank" (a space occupies a box) or "skip" (spaces are dropped).nullable
- overflowPolicystringoptional"reject" (default) or "truncate" when the value needs more boxes than exist.nullable
- dateFormatstringoptionalDate fields: .NET format string applied to the parsed value, e.g. "dd/MM/yyyy".nullable
- decimalPlacesinteger (int32)optionalNo description.nullable
- thousandSeparatorbooleanoptionalNo description.nullable
- optionsarray<string>optionalCheckbox: the options in the group — one marker is authored per option, and the field's value selects which of them is ticked.nullable
- checkedMarkstringoptionalGlyph written into a ticked box. Defaults to a check mark "✓".nullable
- checkedMarkFontstringoptionalFont for the tick. Null inherits the surrounding text's font, which may not carry the check-mark glyph — set a font with symbol coverage if a tick renders as a hollow box.nullable
- multiSelectbooleanoptionalCheckbox groups: allow more than one option to be ticked.nullable
- displayTagstringoptionalLayout types: the single character the editor shows at the field's anchor so the author can see it is there. Author-chosen, defaults to "▫". Stripped before the value is placed, so it never appears in the rendered document.nullable
- maxLengthinteger (int32)optionalValue types: reject a value longer than this before the document is created.nullable
- patternstringoptionalValue types: regular expression the value must match (PAN, IFSC, Aadhaar...).nullable
- stampInfoobjectoptionalRepresents e-stamp information required for stamped documents.
9 fields
- firstPartyNamestringconditionalConditional: required when stampInfo is sent. Name of the first party in the agreement.nullable
- secondPartyNamestringconditionalConditional: required when stampInfo is sent. Name of the second party in the agreement.nullable
- stampDutyPaidBystringconditionalConditional: required when stampInfo is sent. Party that pays the stamp duty.nullable
- purposeOfStampDutystringconditionalConditional: required when stampInfo is sent. Purpose of the stamp duty.nullable
- considerationPricestringconditionalConditional: required when stampInfo is sent. Consideration price or transaction value, as a string.nullable
- stampDutyValuestringconditionalConditional: required when stampInfo is sent. Stamp duty amount, as a string.nullable
- articleIdstringconditionalConditional: required when stampInfo is sent. Article identifier for the stamp duty category.nullable
- branchIdstringconditionalConditional: required when stampInfo is sent. Branch identifier for e-stamp processing.nullable
- statestringconditionalConditional: required when stampInfo is sent. State in which the e-stamp is issued.nullable
- shcilStampInfoobjectoptionalSHCIL eStamp details for Template + SHCIL combined flow.
12 fields
- firstPartyNamestringoptionalFirst party name. English letters and spaces only (max 200) — SHCIL does not accept special characters or digits.nullable
- firstPartyPanstringoptionalFirst party PAN (e.g. ABCDE1234F). Required when the first party pays more than ₹2,00,000.nullable
- firstPartyMobilestringoptionalFirst party mobile, exactly 10 digits. Required when the first party pays the stamp duty.nullable
- secondPartyNamestringoptionalSecond party name. English letters and spaces only (max 200).nullable
- secondPartyPanstringoptionalSecond party PAN. Required when the second party pays more than ₹2,00,000.nullable
- secondPartyMobilestringoptionalSecond party mobile, exactly 10 digits. Required when the second party pays the stamp duty.nullable
- stateCodestringoptionalTwo-letter state code of the chosen article, from the Master Details API (states and pdfArticles), for example AS. Not case-sensitive.nullable
- articleCodeinteger (int32)optionalArticle code of a row in pdfArticles (articleType CUSTOM) in the Master Details API response, used exactly as listed. Articles listed under templateArticles are rejected by this API.
- stampDutyAmountnumber (double)optionalStamp duty in whole rupees, within the minDuty and maxDuty of the chosen pdfArticles row.
- stampDutyPaidBystringoptionalMust equal the first or second party name (letters and spaces only, max 200).nullable
- considerationPricenumber (double)optionalNo description.nullable
- documentDescriptionstringoptionalOptional, max 100 characters: letters, numbers and spaces only — no special characters.nullable
- responseUrlstringoptionalOptional. Response URL that receives document status updates. When omitted, the webhook URL configured for your account is used.nullable
- descriptionForInviteestringoptionalOptional. Message shown to signers on the signing page.nullable
- finalCopyRecipientsEmailIdstringoptionalOptional. Email address that receives a copy of the final signed document.nullable
- returnUrlstringoptionalOptional. Absolute https URL the signer's browser is sent to after signing.nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
6 fields
- documentIdstringoptionalNo description.nullable
- documentReferenceIdstringoptionalNo description.nullable
- responseTimeStampstringoptionalNo description.nullable
- userInfoarray<object>optionalNo description.nullable
Each item: 3 fields
- userRefIdstringoptionalNo description.nullable
- userIdstringoptionalNo description.nullable
- esignLinkstringoptionalNo description.nullable
- uiModeURLstringoptionalNo description.nullable
- stampDetailsobjectoptionalSHCIL eStamp certificate details returned in the Template+SHCIL response.
7 fields
- eStampIdstring (uuid)optionalNo description.nullable
- reconMappingIdstringoptionalNo description.nullable
- userDocumentIdinteger (int64)optionalNo description.nullable
- certIdstringoptionalNo description.nullable
- urnstringoptionalNo description.nullable
- certificateNostringoptionalNo description.nullable
- certificateIssuedDatestringoptionalNo 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.
202Accepted
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalSlim 202 body for Template+SHCIL+eSign: the request passed validation and was accepted; the final result (stamp + eSign links) is delivered to the caller's responseUrl.
3 fields
- documentReferenceIdstringoptionalNo description.nullable
- reconMappingIdstringoptionalNo description.nullable
- statusstringoptionalNo 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
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- 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.
401Unauthorizedsame body as 400
402Payment Requiredsame body as 400
404Not Foundsame body as 400
500Internal Server Errorsame body as 400
Code samplescurl · Node.js · Python
Check the result of a Template and SHCIL eStamp request.
Use this API to find out what happened to a document request that was submitted with SHCIL eStamp details, for example when the result notification (webhook) did not reach your system. It returns the same information that is sent to your response URL, so you can handle both in the same way. There is no charge for this call.
Request
Send your own reference id, the SignCare reconciliation id, or both. If you send both, they must belong to the same request.
| Field | Type | Required | Description |
|---|---|---|---|
| documentReferenceId | string | Either one | The reference id you used when you created the request. 1 to 64 letters, digits, hyphens or underscores. |
| reconMappingId | string | Either one | The reconciliation id returned when the request was accepted. Letters and digits only. |
Result of the lookup
| HTTP status | Request state | Success | What you receive |
|---|---|---|---|
| 202 Accepted | In progress: queued, being stamped, or waiting for SHCIL | true | The reference id, the reconciliation id and the status ACCEPTED. Check again shortly. |
| 200 OK | Completed successfully | true | The document, the signer links and the stamp details. |
| 200 OK | Completed with a failure | false | The reason for the failure, the reference ids, the status FAILED, and the stamp details if a stamp had already been issued. |
Whenever the request is found, the lookup itself succeeds. For a request that failed, the failure code and the reason are in the response body, exactly as in the webhook.
Details of a completed request
| Field | Type | Description |
|---|---|---|
| documentId | string | Identifier of the signing document. Use it with the other eSign APIs. |
| documentReferenceId | string | Your reference id. |
| responseTimeStamp | string | Date and time the signing document was created. |
| userInfo | list | One entry per signer, in the order you submitted them. |
| userInfo: userRefId | string | The signer slot identifier you submitted. |
| userInfo: userId | string | SignCare identifier of the signer. |
| userInfo: docSignerId | string | Identifier of the signer on the document. |
| userInfo: esignLink | string | The signing link sent to the signer. Not provided for a signer who is waiting for an earlier signer. |
| stampDetails: eStampId | string | Unique identifier of the eStamp. |
| stampDetails: reconMappingId | string | The reconciliation id of the request. |
| stampDetails: userDocumentId | number | SHCIL document number. |
| stampDetails: certId | string | Certificate id issued by SHCIL. |
| stampDetails: urn | string | Unique reference number of the stamp. |
| stampDetails: certificateNo | string | Certificate number. |
| stampDetails: certificateIssuedDate | string | Date and time the certificate was issued. |
Details of a failed request
| Field | Type | Description |
|---|---|---|
| message | string | The reason the request failed. |
| documentReferenceId | string | Your reference id. |
| reconMappingId | string | The reconciliation id of the request. |
| status | string | FAILED. |
| stampDetails | object | Provided only when a stamp had already been issued before the failure. Same fields as above. Share them with support so the stamp can be recovered. |
A request that failed can be submitted again with the same reference id.
Error responses
| HTTP status | Situation | Message |
|---|---|---|
| 400 Bad Request | Neither id was sent | Validation Error: Provide 'documentReferenceId' or 'reconMappingId'. |
| 400 Bad Request | An id contains characters that are not allowed | Validation Error: The 'documentReferenceId' passed in the request is invalid. (or the same for 'reconMappingId') |
| 400 Bad Request | Both ids were sent but belong to different requests | Validation Error: 'documentReferenceId' and 'reconMappingId' do not belong to the same request. |
| 401 Unauthorized | The API key is missing or invalid | Missing or invalid X-API-KEY header. |
| 404 Not Found | No such request exists for your account | No Template + SHCIL eStamp request was found for the given documentReferenceId / reconMappingId. |
Guidance
| Topic | Guidance |
|---|---|
| Your data only | You can look up only the requests made with your own account. An id that does not exist, or that belongs to another account, returns the same Not Found response. |
| When to use it | The result normally reaches your response URL within seconds, and failed deliveries are retried automatically over several hours. If you have not received it after a few minutes, check here. Suggested schedule: after 30 seconds, 1 minute and 5 minutes, then every 15 minutes. |
| Stamp waiting for SHCIL | The response stays In progress. The signing document is created automatically once SHCIL completes the stamp. |
| Long-running requests | If a request stays In progress for much longer than usual, contact support and quote its reference id. |
| Signing links | These are the same links that were sent to the signers by email or SMS. |
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- documentReferenceIdstringoptionalThe reference id you used when you created the request. 1 to 64 letters, digits, hyphens or underscores.nullable
- reconMappingIdstringoptionalThe reconciliation id returned when the request was accepted. Letters and digits only.nullable
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalNo description.
6 fields
- documentIdstringoptionalNo description.nullable
- documentReferenceIdstringoptionalNo description.nullable
- responseTimeStampstringoptionalNo description.nullable
- userInfoarray<object>optionalNo description.nullable
Each item: 3 fields
- userRefIdstringoptionalNo description.nullable
- userIdstringoptionalNo description.nullable
- esignLinkstringoptionalNo description.nullable
- uiModeURLstringoptionalNo description.nullable
- stampDetailsobjectoptionalSHCIL eStamp certificate details returned in the Template+SHCIL response.
7 fields
- eStampIdstring (uuid)optionalNo description.nullable
- reconMappingIdstringoptionalNo description.nullable
- userDocumentIdinteger (int64)optionalNo description.nullable
- certIdstringoptionalNo description.nullable
- urnstringoptionalNo description.nullable
- certificateNostringoptionalNo description.nullable
- certificateIssuedDatestringoptionalNo 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.
202Accepted
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalSlim 202 body for Template+SHCIL+eSign: the request passed validation and was accepted; the final result (stamp + eSign links) is delivered to the caller's responseUrl.
3 fields
- documentReferenceIdstringoptionalNo description.nullable
- reconMappingIdstringoptionalNo description.nullable
- statusstringoptionalNo 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
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- 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.