Skip to main content
The DocsAutomator eSign API enables programmatic management of signing sessions, retrieval of signing links, progress tracking, and audit trail access.

Authentication

All API endpoints require bearer token authentication:
Authorization: Bearer YOUR_API_KEY

Base URL

https://api.docsautomator.co/esign

Session Management

List Signing Sessions

GET
/esign/sessions
Retrieve all signing sessions with optional filtering.
Query Parameters:
ParameterTypeRequiredDescription
statusstringNoFilter by status
pagenumberNoPage number (default: 1)
limitnumberNoResults per page (default: 20, max: 100)
emailstringNoSearch by signer email
Valid Status Values: pending, in_progress, completed, expired, cancelled, declined
curl -X GET "https://api.docsautomator.co/esign/sessions?status=pending&page=1&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response:
{
  "sessions": [
    {
      "id": "66f1a2b3c4d5e6f7a8b9c0d1",
      "documentName": "Invoice #123",
      "status": "in_progress",
      "signingOrder": "sequential",
      "signers": [
        { "index": 1, "email": "alice@example.com", "name": "Alice", "status": "signed" },
        { "index": 2, "email": "bob@example.com", "name": "Bob", "status": "invited" }
      ],
      "expiresAt": "2026-05-20T10:00:00.000Z",
      "completedAt": null,
      "createdAt": "2026-04-20T10:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 47,
    "pages": 3
  }
}

Get Session Details

GET
/esign/sessions/:sessionId
Returns comprehensive session information including signer statuses, document hashes, e-sign fields with positions, and completion timestamps.
Per-signer fields include declinedAt and declineReason for any signer who declined. When the session status is declined, the response additionally includes top-level declinedAt, declinedBy (email, name, signerIndex), and declineReason so you can read refusal details without inspecting the signers array. Response:
{
  "id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "documentName": "Invoice #123",
  "status": "completed",
  "signingOrder": "sequential",
  "deliveryMethod": "email",
  "currentSignerIndex": 2,
  "originalPdfUrl": "https://files.docsautomator.co/f/...",
  "signedPdfUrl": "https://files.docsautomator.co/f/...",
  "originalDocumentHash": "sha256:...",
  "signedDocumentHash": "sha256:...",
  "esignFields": [
    {
      "fieldId": "signature_1",
      "type": "signature",
      "tagName": "{{esign.signature_1}}",
      "signerIndex": 1,
      "role": "buyer",
      "value": "data:image/png;base64,...",
      "signedAt": "2026-04-22T14:02:11.000Z",
      "signedBy": "alice@example.com"
    }
  ],
  "signers": [
    {
      "index": 1,
      "email": "alice@example.com",
      "name": "Alice",
      "role": "buyer",
      "status": "signed",
      "accessToken": "a1b2c3...",
      "invitedAt": "2026-04-20T10:00:00.000Z",
      "openedAt": "2026-04-22T13:55:04.000Z",
      "signedAt": "2026-04-22T14:02:11.000Z",
      "declinedAt": null,
      "declineReason": null,
      "ipAddress": "203.0.113.42",
      "consentGivenAt": "2026-04-22T13:55:30.000Z",
      "timezone": "America/New_York",
      "geoLocation": { "country": "US", "region": "NY", "city": "New York" },
      "signingDurationSeconds": 427
    }
  ],
  "reminderEnabled": true,
  "reminderDays": 3,
  "reminderCount": 0,
  "lastReminderSent": null,
  "expiresAt": "2026-05-20T10:00:00.000Z",
  "completedAt": "2026-04-22T14:02:45.000Z",
  "createdAt": "2026-04-20T10:00:00.000Z"
}
When status is declined, the response also includes:
{
  "declinedAt": "2026-04-22T14:10:00.000Z",
  "declinedBy": {
    "email": "bob@example.com",
    "name": "Bob",
    "signerIndex": 2
  },
  "declineReason": "Terms need to be revised"
}

GET
/esign/sessions/:sessionId/links
Retrieves signing links for all signers when using manual delivery mode.
Returns expiration dates and signer status for each link. Response:
{
  "success": true,
  "sessionId": "66f1a2b3c4d5e6f7a8b9c0d1",
  "documentName": "Invoice #123",
  "deliveryMethod": "manual",
  "status": "pending",
  "signers": [
    {
      "signerIndex": 1,
      "email": "alice@example.com",
      "name": "Alice",
      "signingLink": "https://app.docsautomator.co/sign/a1b2c3d4e5f6g7h8",
      "expiresAt": "2026-05-20T10:00:00.000Z",
      "status": "pending"
    }
  ]
}

Get Audit Trail

GET
/esign/sessions/:sessionId/audit
Returns chronological event log for the signing session.
Event Types:
EventDescription
session_createdSigning session initiated
invite_sentEmail invitation dispatched
invite_resentInvitation re-sent to signer
link_openedSigner accessed signing link
document_viewedSigner viewed PDF
consent_givenE-consent provided
field_signedField value entered
field_clearedField value cleared
signer_completedAll fields finished
signer_declinedSigner declined to sign
session_completedAll signers done, PDF generated
session_cancelledSession cancelled
session_expiredSession expired
session_voidedSession voided by admin
reminder_sentReminder email sent
Response:
{
  "sessionId": "66f1a2b3c4d5e6f7a8b9c0d1",
  "events": [
    {
      "id": "66f1a2b3c4d5e6f7a8b9c0e5",
      "eventType": "session_created",
      "actorType": "system",
      "actorEmail": null,
      "actorSignerIndex": null,
      "fieldId": null,
      "fieldType": null,
      "metadata": {
        "documentName": "Invoice #123",
        "signerCount": 2,
        "signingOrder": "sequential"
      },
      "ipAddress": null,
      "userAgent": null,
      "timestamp": "2026-04-20T10:00:00.000Z",
      "timezone": null,
      "geoLocation": null
    },
    {
      "id": "66f1a2b3c4d5e6f7a8b9c0e6",
      "eventType": "field_signed",
      "actorType": "signer",
      "actorEmail": "alice@example.com",
      "actorSignerIndex": 1,
      "fieldId": "signature_1",
      "fieldType": "signature",
      "metadata": {},
      "ipAddress": "203.0.113.42",
      "userAgent": "Mozilla/5.0 ...",
      "timestamp": "2026-04-22T14:02:11.000Z",
      "timezone": "America/New_York",
      "geoLocation": { "country": "US", "region": "NY", "city": "New York" }
    }
  ],
  "reconstructed": false
}
reconstructed: true indicates that some events were inferred from the session document because the original audit events were missing (e.g., pruned from an older session).

Cancel Session

POST
/esign/sessions/:sessionId/cancel
Cancel an active signing session.
Request body:
{
  "reason": "Optional cancellation reason"
}
Response:
{
  "success": true,
  "message": "Signing session has been cancelled"
}
Cannot cancel completed sessions.

Resend Invitation

POST
/esign/sessions/:sessionId/resend/:signerIndex
Resends invitation email to a specific signer (indexed 1, 2, 3, etc.).
Response:
{
  "success": true,
  "message": "Invitation resent to alice@example.com"
}

Webhook Events

EventWhen it fires
(no event field)All signers completed — signed PDF ready
esign.session_createdSession created with deliveryMethod: "manual"
esign.signer_signedAn individual signer completed all their fields
esign.session_declinedA signer declined to sign
esign.session_expiredSession expired before all signers completed
See eSign overview — Webhook Integration for the full payload of each event.

Session Created (Manual Delivery)

Triggered when signing session created with deliveryMethod: "manual". Use to retrieve and distribute signing links manually.

Signing Completed

Triggered when all signers complete signing and final PDF is generated. Payload:
{
  "signedPdfUrl": "https://...",
  "sessionId": "unique-identifier",
  "documentName": "Document name",
  "status": "completed",
  "completedAt": "ISO date string",
  "signers": [
    {
      "email": "signer@example.com",
      "name": "Signer Name",
      "signedAt": "ISO date string"
    }
  ],
  "fieldValues": { },
  "googleDriveFileId": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ",
  "googleDriveUrl": "https://drive.google.com/file/d/1aBcDeFgHiJkLmNoPqRsTuVwXyZ/view",
  "googleDriveFolderId": "0BxAbCdEfGhIjKlMnOpQrStUvWx",
  "sourceData": { },
  "additionalParams": { }
}
The googleDriveFileId, googleDriveUrl, and googleDriveFolderId fields are only present when “Save to Google Drive” is enabled in the Signed PDF Delivery settings.

Signer Signed

Fires once per signer as they complete, including the final signer. Use to track progress for multi-party documents.
{
  "event": "esign.signer_signed",
  "sessionId": "unique-identifier",
  "documentName": "Document name",
  "status": "in_progress",
  "signer": {
    "email": "signer@example.com",
    "name": "Signer Name",
    "signerIndex": 1,
    "role": "buyer",
    "signedAt": "ISO date string"
  },
  "progress": {
    "completed": 1,
    "total": 2,
    "allSigned": false
  },
  "sourceData": { },
  "additionalParams": { }
}
For the final signer, progress.allSigned is true but the session status is still in_progress. The separate Signing Completed webhook fires afterwards, once the signed PDF is ready.

Session Expired

Fires when a signing session expires before all signers complete. An expiration email is also sent to workspace notification recipients.
{
  "event": "esign.session_expired",
  "sessionId": "unique-identifier",
  "documentName": "Document name",
  "status": "expired",
  "expiredAt": "ISO date string",
  "expiresAt": "ISO date string",
  "pendingSigners": [
    {
      "email": "signer@example.com",
      "name": "Signer Name",
      "signerIndex": 2,
      "status": "invited"
    }
  ],
  "sourceData": { },
  "additionalParams": { }
}
If a session is already declined, cancelled, or completed before its expiration time, this webhook does not fire.

Passing Additional Parameters

Include webhookParams in document creation requests to receive custom data in webhook notifications:
{
  "docId": "your-automation-id",
  "data": { ... },
  "webhookParams": {
    "orderId": "ORD-12345",
    "customerId": "CUST-789"
  }
}
Parameters are returned in all webhook notifications as additionalParams.

Status Reference

Session Statuses

StatusDescription
pendingAwaiting signer action
in_progressAt least one signer started
completedAll signers finished
expiredExpired before completion
cancelledCancelled by admin
declinedSigner declined

Signer Statuses

StatusDescription
pendingInvitation not sent
invitedEmail sent
openedLink opened
signedAll fields completed
declinedDeclined to sign

Error Responses

{
  "error": true,
  "message": "Description"
}
CodeDescription
400Bad request — invalid parameters
401Unauthorized — invalid/missing API key
404Not found — session doesn’t exist
429Rate limited
500Server error

Rate Limits

Rate limits apply to the public signing page routes (not the authenticated admin API endpoints):
RouteLimit
Signing page access100 requests per 15 minutes per IP
Field submissions30 requests per minute per IP

Code Examples

Node.js — List and Monitor Sessions

const axios = require('axios');

const API_KEY = 'your_api_key';
const BASE_URL = 'https://api.docsautomator.co/esign';

async function listPendingSessions() {
  const response = await axios.get(`${BASE_URL}/sessions`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
    params: { status: 'pending', limit: 50 }
  });
  return response.data.sessions;
}

async function getSessionWithAudit(sessionId) {
  const [session, audit] = await Promise.all([
    axios.get(`${BASE_URL}/sessions/${sessionId}`, {
      headers: { Authorization: `Bearer ${API_KEY}` }
    }),
    axios.get(`${BASE_URL}/sessions/${sessionId}/audit`, {
      headers: { Authorization: `Bearer ${API_KEY}` }
    })
  ]);

  return {
    ...session.data,
    auditTrail: audit.data.events
  };
}

Python — Webhook Handler

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/webhook/esign', methods=['POST'])
def handle_esign_webhook():
    payload = request.json

    if payload.get('event') == 'esign.session_created':
        for signer in payload.get('signingLinks', []):
            send_custom_email(
                to=signer['email'],
                signing_link=signer['signingLink']
            )

    elif payload.get('status') == 'completed':
        signed_pdf_url = payload['signedPdfUrl']
        order_id = payload.get('additionalParams', {}).get('orderId')
        drive_url = payload.get('googleDriveUrl')  # Present if Save to Drive is enabled
        process_signed_document(signed_pdf_url, order_id, drive_url=drive_url)

    return jsonify({'received': True})
Last modified on April 23, 2026