Skip to main content
Documenso sends webhook notifications for key document lifecycle events. Each webhook includes a consistent payload structure with event-specific data.

Event types

All event names use the format DOCUMENT_* or RECIPIENT_* in the API, but are displayed in lowercase with dots (e.g., document.created) in webhook payloads.

Document events

Triggered when a new document is created in Documenso.Event name: DOCUMENT_CREATEDWhen triggered:
  • User uploads a new document
  • Document is created from a template
  • Document is duplicated
Payload example:
{
  "event": "DOCUMENT_CREATED",
  "payload": {
    "id": 10,
    "externalId": null,
    "title": "documenso.pdf",
    "status": "DRAFT",
    "userId": 1,
    "teamId": null,
    "templateId": null,
    "createdAt": "2024-03-15T10:30:00.000Z",
    "updatedAt": "2024-03-15T10:30:00.000Z",
    "completedAt": null,
    "visibility": "EVERYONE",
    "source": "DOCUMENT",
    "documentMeta": {
      "id": "doc_meta_123",
      "subject": "Please sign this document",
      "message": "Hello, please review and sign this document.",
      "timezone": "UTC",
      "dateFormat": "MM/DD/YYYY",
      "redirectUrl": null,
      "signingOrder": "PARALLEL",
      "language": "en",
      "distributionMethod": "EMAIL"
    },
    "recipients": []
  },
  "createdAt": "2024-03-15T10:30:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}
Triggered when a document is sent to recipients.Event name: DOCUMENT_SENTWhen triggered:
  • User clicks “Send” on a document
  • Document is sent via API
  • Template generates and sends a document
Payload example:
{
  "event": "DOCUMENT_SENT",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "PENDING",
    "recipients": [
      {
        "id": 52,
        "documentId": 10,
        "email": "signer@documenso.com",
        "name": "John Doe",
        "role": "SIGNER",
        "sendStatus": "SENT",
        "signingStatus": "NOT_SIGNED",
        "readStatus": "NOT_OPENED",
        "signingOrder": 1
      }
    ]
  },
  "createdAt": "2024-03-15T10:35:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}
Triggered when a recipient opens a document for the first time.Event name: DOCUMENT_OPENEDWhen triggered:
  • Recipient clicks the signing link
  • First view of the document by any recipient
Payload example:
{
  "event": "DOCUMENT_OPENED",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "PENDING",
    "recipients": [
      {
        "id": 52,
        "email": "signer@documenso.com",
        "name": "John Doe",
        "role": "SIGNER",
        "readStatus": "OPENED",
        "signingStatus": "NOT_SIGNED",
        "sendStatus": "SENT"
      }
    ]
  },
  "createdAt": "2024-03-15T10:40:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}
Triggered when a recipient signs a document.Event name: DOCUMENT_SIGNEDWhen triggered:
  • Any recipient completes their signing action
  • Individual signature is added (not when all signatures are complete)
This event fires for each individual signature. For final completion, use document.completed.
Payload example:
{
  "event": "DOCUMENT_SIGNED",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "PENDING",
    "recipients": [
      {
        "id": 52,
        "email": "signer@documenso.com",
        "name": "John Doe",
        "role": "SIGNER",
        "signedAt": "2024-03-15T10:45:00.000Z",
        "signingStatus": "SIGNED",
        "readStatus": "OPENED",
        "sendStatus": "SENT"
      }
    ]
  },
  "createdAt": "2024-03-15T10:45:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}
Triggered when all required recipients have signed the document.Event name: DOCUMENT_COMPLETEDWhen triggered:
  • Last required signature is added
  • All recipients have completed their actions
  • Document reaches final state
Payload example:
{
  "event": "DOCUMENT_COMPLETED",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "COMPLETED",
    "completedAt": "2024-03-15T11:00:00.000Z",
    "recipients": [
      {
        "id": 50,
        "email": "signer1@documenso.com",
        "name": "Signer 1",
        "role": "SIGNER",
        "signedAt": "2024-03-15T10:45:00.000Z",
        "signingStatus": "SIGNED",
        "signingOrder": 1
      },
      {
        "id": 51,
        "email": "signer2@documenso.com",
        "name": "Signer 2",
        "role": "SIGNER",
        "signedAt": "2024-03-15T11:00:00.000Z",
        "signingStatus": "SIGNED",
        "signingOrder": 2
      }
    ]
  },
  "createdAt": "2024-03-15T11:00:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}
Triggered when a recipient rejects a document.Event name: DOCUMENT_REJECTEDWhen triggered:
  • Recipient clicks “Reject” or “Decline”
  • Recipient provides a rejection reason
Payload example:
{
  "event": "DOCUMENT_REJECTED",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "PENDING",
    "recipients": [
      {
        "id": 52,
        "email": "signer@documenso.com",
        "name": "John Doe",
        "role": "SIGNER",
        "signingStatus": "REJECTED",
        "rejectionReason": "I do not agree with the terms",
        "signedAt": "2024-03-15T10:50:00.000Z"
      }
    ]
  },
  "createdAt": "2024-03-15T10:50:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}
Triggered when a document is cancelled by the owner.Event name: DOCUMENT_CANCELLEDWhen triggered:
  • Document owner cancels/deletes the document
  • Document is deleted before completion
Payload example:
{
  "event": "DOCUMENT_CANCELLED",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "PENDING",
    "deletedAt": null,
    "recipients": [
      {
        "id": 7,
        "email": "signer@documenso.com",
        "name": "Signer",
        "role": "SIGNER",
        "signingStatus": "NOT_SIGNED"
      }
    ]
  },
  "createdAt": "2024-03-15T11:15:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}

Recipient events

Triggered when a recipient’s signing link expires.Event name: RECIPIENT_EXPIREDWhen triggered:
  • Recipient expiration date passes
  • Signing link becomes invalid due to timeout
Payload example:
{
  "event": "RECIPIENT_EXPIRED",
  "payload": {
    "id": 10,
    "title": "documenso.pdf",
    "status": "PENDING",
    "recipients": [
      {
        "id": 52,
        "email": "signer@documenso.com",
        "name": "John Doe",
        "role": "SIGNER",
        "expiresAt": "2024-03-14T10:30:00.000Z",
        "expirationNotifiedAt": "2024-03-15T10:30:00.000Z",
        "signingStatus": "NOT_SIGNED"
      }
    ]
  },
  "createdAt": "2024-03-15T10:30:00.000Z",
  "webhookEndpoint": "https://your-app.com/webhooks"
}

Payload structure

All webhook events share a common top-level structure:
interface WebhookPayload {
  event: string;              // Event type (e.g., "DOCUMENT_COMPLETED")
  payload: Document;          // Document data with recipients
  createdAt: string;          // ISO 8601 timestamp
  webhookEndpoint: string;    // Your webhook URL
}

Document object

The payload field contains a document object:
interface Document {
  id: number;
  externalId: string | null;
  userId: number;
  teamId: number | null;
  templateId: number | null;
  title: string;
  status: DocumentStatus;      // DRAFT, PENDING, COMPLETED
  createdAt: string;
  updatedAt: string;
  completedAt: string | null;
  deletedAt: string | null;
  visibility: string;          // EVERYONE, MANAGER_AND_ABOVE, etc.
  source: string;              // DOCUMENT, TEMPLATE
  documentMeta: DocumentMeta | null;
  recipients: Recipient[];     // Array of recipients
  Recipient: Recipient[];      // Legacy field (same as recipients)
}

DocumentMeta object

interface DocumentMeta {
  id: string;
  subject: string | null;
  message: string | null;
  timezone: string;
  dateFormat: string;
  redirectUrl: string | null;
  signingOrder: "PARALLEL" | "SEQUENTIAL";
  allowDictateNextSigner: boolean;
  typedSignatureEnabled: boolean;
  uploadSignatureEnabled: boolean;
  drawSignatureEnabled: boolean;
  language: string;
  distributionMethod: "EMAIL" | "NONE";
  emailSettings: object | null;
}

Recipient object

interface Recipient {
  id: number;
  documentId: number | null;
  templateId: number | null;
  email: string;
  name: string;
  token: string;                // Signing token
  role: RecipientRole;          // SIGNER, VIEWER, APPROVER, CC
  sendStatus: SendStatus;       // NOT_SENT, SENT
  signingStatus: SigningStatus; // NOT_SIGNED, SIGNED, REJECTED
  readStatus: ReadStatus;       // NOT_OPENED, OPENED
  signedAt: string | null;
  expiresAt: string | null;
  expirationNotifiedAt: string | null;
  documentDeletedAt: string | null;
  signingOrder: number | null;
  rejectionReason: string | null;
  authOptions: object | null;
}

Enumeration values

DocumentStatus

  • DRAFT - Document is being prepared
  • PENDING - Document is sent and awaiting signatures
  • COMPLETED - All recipients have signed

RecipientRole

  • SIGNER - Must sign the document
  • VIEWER - Can view but not sign
  • APPROVER - Must approve the document
  • CC - Receives a copy when complete

SendStatus

  • NOT_SENT - Email not yet sent
  • SENT - Email delivered to recipient

SigningStatus

  • NOT_SIGNED - Recipient has not signed
  • SIGNED - Recipient has signed
  • REJECTED - Recipient rejected the document

ReadStatus

  • NOT_OPENED - Document not viewed
  • OPENED - Document has been opened

Filtering events

You can subscribe to specific events when creating a webhook. Only selected events will trigger notifications:
// Subscribe to completion events only
const webhook = await createWebhook({
  webhookUrl: 'https://your-app.com/webhooks',
  eventTriggers: [
    'DOCUMENT_COMPLETED',
    'DOCUMENT_REJECTED'
  ]
});

Working with payloads

app.post('/webhooks/documenso', async (req, res) => {
  const { event, payload } = req.body;
  
  // Access document data
  console.log(`Document ID: ${payload.id}`);
  console.log(`Document title: ${payload.title}`);
  console.log(`Status: ${payload.status}`);
  
  // Process recipients
  payload.recipients.forEach(recipient => {
    console.log(`${recipient.name} (${recipient.email}): ${recipient.signingStatus}`);
    
    if (recipient.signedAt) {
      console.log(`  Signed at: ${recipient.signedAt}`);
    }
  });
  
  res.status(200).json({ received: true });
});

Testing with sample data

Use the webhook test feature to send sample payloads for each event type. This helps you:
  • Verify endpoint connectivity
  • Test event processing logic
  • Inspect payload structure
  • Debug webhook handlers
Sample payloads include realistic data but use placeholder IDs and emails. Production webhooks will contain actual document data.

Next steps

Setup webhooks

Configure your webhook endpoints

Security

Implement signature verification