Surepass

Getting started

The end-to-end Esign flow — upload a PDF, initialize a session, track signers, and download the signed document.

View as Markdown

A complete Esign flow has four steps:

  1. Upload the PDF to be signed.
  2. Initialize an Esign session with one or more signers and their signature positions.
  3. Track signer status until the session completes.
  4. 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 CodeDescription
file_emptyNo file uploaded or file is empty.
file_too_largeUploaded file exceeds maximum size (50MB).
invalid_pdfFile 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:

POST /api/v1/esign/initialize-esign
{
  "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

  • page is zero-indexed: use 0 for the first page, 1 for 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. If true, the backend compares signer full_name with the Aadhaar certificate name and returns a fuzzy score from 0 to 100. 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 returned client_id.
  • signers[].face_match_threshold: minimum face-match score from 50 to 100; defaults to 80. signers[].face_max_attempts: maximum face-verification attempts from 1 to 10; defaults to 5. Both are only enforced when face_ref_file_id is provided.
  • allow_wet_signature: per signature element flag, defaults to false. When false, any signature value asset ID is stripped during request parsing. Set it to true only for signature fields that intentionally allow a wet-signature image.

Email template overrides

FieldTypeRequiredDescription
company_namestringNoCustom company name shown in email.
legal_namestringNoLegal entity name shown in footer (default: "Surepass Technologies Pvt Ltd.")
support_emailstringNoSupport 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

FieldTypeRequiredDefaultDescription
invitebooleanNotrueSend signer invite communication by email/SMS.
completionbooleanNotrueSend completed-document communication after the Esign finishes successfully.
whatsappbooleanNofalseAlso 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

TypeDescription
signatureSignature input box
imagePreloaded image (uploaded as asset)
textText field
dateDate field with formatting support
initialsInitials block

Error responses:

Message CodeDescription
missing_fieldsRequired fields are missing in the request.
invalid_file_idThe provided file ID is invalid or does not exist.
invalid_sign_typeMust be either "aadhaar" or "suresign".
unauthorizedInvalid 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 is null for non-Aadhaar signers and pending Aadhaar signers.
  • signers[].name_match.status: pending when requested and waiting for Aadhaar cert details, completed when the score is calculated, and skipped when not requested.
  • signers[].face_match.enforce: true when initialization supplied face_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 remains null until 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
}

On this page