Getting started
The end-to-end Esign flow — upload a PDF, initialize a session, track signers, and download the signed document.
A complete Esign flow has four steps:
- Upload the PDF to be signed.
- Initialize an Esign session with one or more signers and their signature positions.
- Track signer status until the session completes.
- Download the final signed PDF.
All examples below use the sandbox base URL
https://esign-api-v2.surepass.app and require the
Authorization: Bearer YOUR_ACCESS_TOKEN header.
1. Upload the PDF
Upload the document (max 50MB) with Upload PDF:
curl --location 'https://esign-api-v2.surepass.app/api/v1/files/upload-pdf' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--form 'file=@"/path/to/your/file.pdf"'Success response:
{
"data": {
"user_id": "user_xxx",
"client_id": "file_xxx",
"name": "Form_26.pdf",
"mime": "application/pdf"
},
"status_code": 200,
"message": "Success",
"success": true
}The client_id (e.g. file_xxx) is the file_id you pass when
initializing the Esign.
Error responses:
| Message Code | Description |
|---|---|
file_empty | No file uploaded or file is empty. |
file_too_large | Uploaded file exceeds maximum size (50MB). |
invalid_pdf | File is not a valid PDF. |
2. Initialize the Esign session
Start the session with
Initialize Esign. Each signer gets
one or more elements — the fields placed on the document:
{
"sign_type": "aadhaar",
"auth_mode": 1,
"file_id": "file_onwEUoMxnWhewUzodZeW",
"folder": "lehddsun",
"expiry_seconds": 7200,
"email_template_overrides": {
"company_name": "Acme Corp",
"legal_name": "Acme Corporation Pvt Ltd.",
"support_email": "support@acme.com"
},
"signers": [
{
"full_name": "Test1",
"email": "test1@example.com",
"reason": "Test1 Sign",
"verify_email": false,
"verify_mobile": false,
"name_match": true,
"face_ref_file_id": "file_faceReferenceImage",
"face_match_threshold": 80,
"face_max_attempts": 5,
"notification": {
"invite": true,
"completion": true,
"whatsapp": true
},
"elements": [
{
"x": 100,
"y": 10,
"page": 0,
"type": "signature",
"allow_wet_signature": false
}
]
},
{
"full_name": "Test2",
"email": "test2@example.com",
"mobile": "2222222222",
"reason": "Test2 Sign",
"verify_email": true,
"verify_mobile": false,
"notification": {
"invite": false,
"completion": true,
"whatsapp": false
},
"elements": [
{
"x": 100,
"y": 10,
"page": 0,
"type": "signature"
}
]
}
]
}Success response:
{
"data": {
"client_id": "esign_lpHGXloMQwkNPPXvBHCH",
"status": "pending",
"file_id": "file_onwEUoMxnWhewUzodZeW",
"signers": [ "..." ]
},
"status_code": 200,
"message": "Success",
"success": true
}Each signer in the response includes an invite_url the signer opens to
complete signing. Signers are also notified by email/SMS unless disabled
via notification.
Notes
pageis zero-indexed: use0for the first page,1for the second, and so on.expiry_seconds: min = 3600 (1 hour), max = 2592000 (30 days).sign_type:"aadhaar"(OTP-based) or"suresign"(auto-signing by Surepass).- Multiple elements can be added per signer on different pages.
signers[].name_match: optional boolean for Aadhaar signers. Iftrue, the backend compares signerfull_namewith the Aadhaar certificate name and returns a fuzzyscorefrom0to100. Ignored for non-Aadhaar signers.signers[].face_ref_file_id: optional reference image file ID. Providing it enables face verification for that signer. Upload the JPEG or PNG reference image through Upload asset before initialization and pass the returnedclient_id.signers[].face_match_threshold: minimum face-match score from50to100; defaults to80.signers[].face_max_attempts: maximum face-verification attempts from1to10; defaults to5. Both are only enforced whenface_ref_file_idis provided.allow_wet_signature: persignatureelement flag, defaults tofalse. When false, any signaturevalueasset ID is stripped during request parsing. Set it totrueonly for signature fields that intentionally allow a wet-signature image.
Email template overrides
| Field | Type | Required | Description |
|---|---|---|---|
company_name | string | No | Custom company name shown in email. |
legal_name | string | No | Legal entity name shown in footer (default: "Surepass Technologies Pvt Ltd.") |
support_email | string | No | Support email shown in footer (default: "techsupport@surepass.io") |
When company_name is provided, the default Surepass logo and branding
are hidden, allowing white-label emails.
Notification
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
invite | boolean | No | true | Send signer invite communication by email/SMS. |
completion | boolean | No | true | Send completed-document communication after the Esign finishes successfully. |
whatsapp | boolean | No | false | Also deliver the invite and the completed signed document over WhatsApp. Requires the signer to have a mobile; silently ignored otherwise. |
Set invite/completion to false to skip that communication for that
signer. whatsapp is opt-in and only sends when invite/completion
(respectively) are also enabled. Omit notification entirely to keep
invite/completion enabled and whatsapp disabled.
Field types supported in signers.elements
| Type | Description |
|---|---|
signature | Signature input box |
image | Preloaded image (uploaded as asset) |
text | Text field |
date | Date field with formatting support |
initials | Initials block |
Error responses:
| Message Code | Description |
|---|---|
missing_fields | Required fields are missing in the request. |
invalid_file_id | The provided file ID is invalid or does not exist. |
invalid_sign_type | Must be either "aadhaar" or "suresign". |
unauthorized | Invalid or expired access token. |
3. Track signer status
Poll Get signer details with the
Esign client_id from step 2:
curl --location --globoff 'https://esign-api-v2.surepass.app/api/v1/esign/details?client_id=esign_xxx' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Success response:
{
"data": {
"user_id": "user_kmJytYATMawoorDzWrUQ",
"client_id": "esign_PsLIyRDIHAqyFWhZqhDT",
"created_at": "2025-05-13T12:06:01.344000",
"sign_type": "aadhaar",
"file_id": "file_ugSBmcbzETuPjUqQLyts",
"allow_download": true,
"expiry_seconds": 7200,
"status": "completed",
"signers": [
{
"signer_id": "signer_vxgTyyOxYDhkhsIKQtda",
"full_name": "Test1",
"email": "test1@example.com",
"status": "completed",
"aadhaar_cert_details": {
"name": "Test Signer",
"country": "IN",
"state": "Delhi",
"pin_code": "110001",
"aadhaar": "0000",
"year_of_birth": "1990",
"gender": "M"
},
"name_match": {
"enforce": true,
"prefill_name": "Test1",
"signer_name": "Test Signer",
"score": 31.25,
"status": "completed"
},
"face_match": {
"enforce": true,
"ref_file_id": "file_faceReferenceImage",
"live_file_id": "file_faceLiveImage",
"match_threshold": 80,
"max_attempts": 5,
"liveness_score": 0.93,
"match_score": 87
},
"positions": {
"1": [{ "x": 100, "y": 200 }]
}
}
],
"signer_idx": 1
},
"status_code": 200,
"message": "Success",
"success": true
}Session lifecycle
A session starts as pending, moves through each signer in order
(signer_idx tracks whose turn it is), and becomes completed once every
signer has signed — or expired if expiry_seconds elapse first. The
signed PDF can be downloaded only after the status is completed.
Response notes
signers[].aadhaar_cert_details: present for Aadhaar signers after Aadhaar signing completes. It isnullfor non-Aadhaar signers and pending Aadhaar signers.signers[].name_match.status:pendingwhen requested and waiting for Aadhaar cert details,completedwhen the score is calculated, andskippedwhen not requested.signers[].face_match.enforce:truewhen initialization suppliedface_ref_file_id.signers[].face_match.ref_file_id/live_file_id: reference image and successfully verified live image file IDs.signers[].face_match.liveness_score/match_score: scores from the successful verification; each remainsnulluntil face verification succeeds.
Error response:
{
"data": null,
"status_code": 404,
"message": "Esign client with client_id 'esign_xxx' not found.",
"success": false
}4. Download the signed PDF
Once the session status is completed, fetch the document with
Download signed PDF:
curl --location --globoff 'https://esign-api-v2.surepass.app/api/v1/esign/download-pdf?client_id=esign_xxx' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Success response:
{
"data": {
"url": "https://test-esign-bucket.s3.amazonaws.com/..."
},
"status_code": 200,
"message": "Success",
"success": true
}The url is a time-limited download link for the signed PDF.
Error response (session not finished yet):
{
"data": null,
"status_code": 404,
"message": "Esign not completed.",
"success": false
}