--- title: Webhook Events description: Reference for all webhook event types and payloads. --- import { Step, Steps } from 'fumadocs-ui/components/steps'; ## Event Payload Structure All webhook events share a common structure: ```json { "event": "DOCUMENT_COMPLETED", "payload": { // Document or template data with recipients }, "createdAt": "2024-04-22T11:52:18.277Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### Top-Level Fields | Field | Type | Description | | ----------------- | -------- | ------------------------------------------------ | | `event` | string | Event type identifier (e.g., `DOCUMENT_CREATED`) | | `payload` | object | Document object with metadata and recipients | | `createdAt` | datetime | When the webhook event was created | | `webhookEndpoint` | string | The URL receiving this webhook | ### Payload Fields | Field | Type | Description | | ---------------- | --------- | ------------------------------------------------------ | | `id` | number | Legacy numeric v1 document or template ID | | `envelopeId` | string | Canonical v2 identifier (`envelope_` + 16 characters) | | `externalId` | string? | External identifier for integration | | `userId` | number | Owner's user ID | | `authOptions` | object? | Document-level authentication options | | `formValues` | object? | PDF form values associated with the document | | `title` | string | Document or template title | | `status` | string | Current status: `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED`, `CANCELLED` | | `visibility` | string | Document visibility setting | | `createdAt` | datetime | Document creation timestamp | | `updatedAt` | datetime | Last modification timestamp | | `completedAt` | datetime? | Completion timestamp (when all recipients have signed) | | `deletedAt` | datetime? | Deletion timestamp | | `teamId` | number? | Team ID if document belongs to a team | | `templateId` | number? | Template ID if created from a template | | `source` | string | Source: `DOCUMENT`, `TEMPLATE`, or `TEMPLATE_DIRECT_LINK` | | `documentMeta` | object? | Nullable document metadata (subject, message, signing options) | | `recipients` | array | List of recipient objects | | `Recipient` | array | List of recipient objects (legacy, same as recipients) | ### Document Metadata Fields | Field | Type | Description | | -------------------------- | ------- | --------------------------------------- | | `id` | string | Metadata record identifier | | `subject` | string? | Email subject line | | `message` | string? | Email message body | | `timezone` | string | Timezone for date display | | `dateFormat` | string | Date format string | | `redirectUrl` | string? | URL to redirect after signing | | `signingOrder` | string | `PARALLEL` or `SEQUENTIAL` | | `allowDictateNextSigner` | boolean | Whether signers can choose the next signer | | `typedSignatureEnabled` | boolean | Whether typed signatures are allowed | | `uploadSignatureEnabled` | boolean | Whether uploaded signatures are allowed | | `drawSignatureEnabled` | boolean | Whether drawn signatures are allowed | | `language` | string | Document language code | | `distributionMethod` | string | How document is distributed | | `emailSettings` | object? | Custom email settings for this document | ### Recipient Fields | Field | Type | Description | | ---------------------- | --------- | ------------------------------------------ | | `id` | number | Recipient ID | | `envelopeId` | string | Canonical parent envelope ID | | `documentId` | number? | Legacy parent document ID; null for templates | | `templateId` | number? | Legacy parent template ID; null for documents | | `email` | string | Recipient email address | | `name` | string | Recipient name | | `token` | string | Unique signing token | | `documentDeletedAt` | datetime? | When the recipient hid the document | | `expiresAt` | datetime? | When the recipient's signing link expires | | `expirationNotifiedAt` | datetime? | When the expiration notification was sent | | `signedAt` | datetime? | When recipient signed | | `authOptions` | object? | Per-recipient authentication options | | `role` | string | Role: `SIGNER`, `VIEWER`, `APPROVER`, `ASSISTANT`, `CC` | | `signingOrder` | number? | Position in signing sequence | | `readStatus` | string | `NOT_OPENED` or `OPENED` | | `signingStatus` | string | `NOT_SIGNED`, `SIGNED`, or `REJECTED` | | `sendStatus` | string | `NOT_SENT` or `SENT` | | `rejectionReason` | string? | Reason if recipient rejected | Use `recipient.envelopeId` as the reliable parent link. The legacy `documentId` and `templateId` fields depend on the parent envelope type, so one of them is always null. --- ## Document Lifecycle Events These events track the document through its lifecycle. ### `document.created` Triggered when a new document is created. **Event name:** `DOCUMENT_CREATED` ```json { "event": "DOCUMENT_CREATED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "externalId": null, "userId": 1, "authOptions": null, "formValues": null, "visibility": "EVERYONE", "title": "contract.pdf", "status": "DRAFT", "createdAt": "2024-04-22T11:44:43.341Z", "updatedAt": "2024-04-22T11:44:43.341Z", "completedAt": null, "deletedAt": null, "teamId": null, "templateId": null, "source": "DOCUMENT", "documentMeta": { "id": "doc_meta_123", "subject": "Please sign this document", "message": "Hello, please review and sign this document.", "timezone": "Etc/UTC", "dateFormat": "yyyy-MM-dd hh:mm a", "redirectUrl": null, "signingOrder": "PARALLEL", "allowDictateNextSigner": false, "typedSignatureEnabled": true, "uploadSignatureEnabled": true, "drawSignatureEnabled": true, "language": "en", "distributionMethod": "EMAIL", "emailSettings": null }, "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "vbT8hi3jKQmrFP_LN1WcS", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": null, "authOptions": null, "signingOrder": 1, "rejectionReason": null, "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "NOT_SENT" } ], "Recipient": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "vbT8hi3jKQmrFP_LN1WcS", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": null, "authOptions": null, "signingOrder": 1, "rejectionReason": null, "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "NOT_SENT" } ] }, "createdAt": "2024-04-22T11:44:44.779Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.sent` Triggered when a document is sent to recipients for signing. **Event name:** `DOCUMENT_SENT` The document status changes to `PENDING` and recipients have `sendStatus: "SENT"`. ```json { "event": "DOCUMENT_SENT", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "externalId": null, "userId": 1, "authOptions": null, "formValues": null, "visibility": "EVERYONE", "title": "contract.pdf", "status": "PENDING", "createdAt": "2024-04-22T11:44:43.341Z", "updatedAt": "2024-04-22T11:48:07.569Z", "completedAt": null, "deletedAt": null, "teamId": null, "templateId": null, "source": "DOCUMENT", "documentMeta": { "id": "doc_meta_123", "subject": "Please sign this document", "message": "Hello, please review and sign this document.", "timezone": "Etc/UTC", "dateFormat": "yyyy-MM-dd hh:mm a", "redirectUrl": null, "signingOrder": "PARALLEL", "allowDictateNextSigner": false, "typedSignatureEnabled": true, "uploadSignatureEnabled": true, "drawSignatureEnabled": true, "language": "en", "distributionMethod": "EMAIL", "emailSettings": null }, "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "vbT8hi3jKQmrFP_LN1WcS", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": null, "authOptions": null, "signingOrder": 1, "rejectionReason": null, "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ], "Recipient": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "vbT8hi3jKQmrFP_LN1WcS", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": null, "authOptions": null, "signingOrder": 1, "rejectionReason": null, "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:48:07.945Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.opened` Triggered when a recipient opens the document for the first time. **Event name:** `DOCUMENT_OPENED` The recipient's `readStatus` changes to `OPENED`. ```json { "event": "DOCUMENT_OPENED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "status": "PENDING", "title": "contract.pdf", "source": "DOCUMENT", "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "email": "signer@example.com", "name": "John Doe", "role": "SIGNER", "readStatus": "OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:50:26.174Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.signed` Triggered when a recipient signs the document. This fires for each individual signature, not just when the document is fully completed. **Event name:** `DOCUMENT_SIGNED` The recipient's `signingStatus` changes to `SIGNED` and `signedAt` is populated. ```json { "event": "DOCUMENT_SIGNED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "status": "COMPLETED", "title": "contract.pdf", "source": "DOCUMENT", "completedAt": "2024-04-22T11:52:05.707Z", "recipients": [ { "id": 51, "envelopeId": "envelope_abcdefhiklmnorst", "email": "signer@example.com", "name": "John Doe", "role": "SIGNER", "signedAt": "2024-04-22T11:52:05.688Z", "readStatus": "OPENED", "signingStatus": "SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:52:18.577Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.recipient.completed` Triggered when an individual recipient completes their required action (signing, approving, or viewing). This is useful for tracking per-recipient progress in documents with multiple recipients. **Event name:** `DOCUMENT_RECIPIENT_COMPLETED` ```json { "event": "DOCUMENT_RECIPIENT_COMPLETED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "status": "PENDING", "title": "contract.pdf", "source": "DOCUMENT", "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "email": "signer@example.com", "name": "John Doe", "role": "SIGNER", "signedAt": "2024-04-22T11:52:05.688Z", "readStatus": "OPENED", "signingStatus": "SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:52:06.000Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.completed` Triggered when all recipients have completed their required actions. **Event name:** `DOCUMENT_COMPLETED` The document status changes to `COMPLETED` and `completedAt` is set. ```json { "event": "DOCUMENT_COMPLETED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "externalId": null, "userId": 1, "authOptions": null, "formValues": null, "visibility": "EVERYONE", "title": "contract.pdf", "status": "COMPLETED", "createdAt": "2024-04-22T11:44:43.341Z", "updatedAt": "2024-04-22T11:52:05.708Z", "completedAt": "2024-04-22T11:52:05.707Z", "deletedAt": null, "teamId": null, "templateId": null, "source": "DOCUMENT", "documentMeta": { "id": "doc_meta_123", "subject": "Please sign this document", "message": "Hello, please review and sign this document.", "timezone": "Etc/UTC", "dateFormat": "yyyy-MM-dd hh:mm a", "redirectUrl": null, "signingOrder": "PARALLEL", "allowDictateNextSigner": false, "typedSignatureEnabled": true, "uploadSignatureEnabled": true, "drawSignatureEnabled": true, "language": "en", "distributionMethod": "EMAIL", "emailSettings": null }, "recipients": [ { "id": 50, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "reviewer@example.com", "name": "Jane Smith", "token": "vbT8hi3jKQmrFP_LN1WcS", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": "2024-04-22T11:51:10.055Z", "authOptions": { "accessAuth": null, "actionAuth": null }, "signingOrder": 1, "rejectionReason": null, "role": "VIEWER", "readStatus": "OPENED", "signingStatus": "SIGNED", "sendStatus": "SENT" }, { "id": 51, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "HkrptwS42ZBXdRKj1TyUo", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": "2024-04-22T11:52:05.688Z", "authOptions": { "accessAuth": null, "actionAuth": null }, "signingOrder": 2, "rejectionReason": null, "role": "SIGNER", "readStatus": "OPENED", "signingStatus": "SIGNED", "sendStatus": "SENT" } ], "Recipient": [ { "id": 50, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "reviewer@example.com", "name": "Jane Smith", "token": "vbT8hi3jKQmrFP_LN1WcS", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": "2024-04-22T11:51:10.055Z", "authOptions": { "accessAuth": null, "actionAuth": null }, "signingOrder": 1, "rejectionReason": null, "role": "VIEWER", "readStatus": "OPENED", "signingStatus": "SIGNED", "sendStatus": "SENT" }, { "id": 51, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "HkrptwS42ZBXdRKj1TyUo", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": "2024-04-22T11:52:05.688Z", "authOptions": { "accessAuth": null, "actionAuth": null }, "signingOrder": 2, "rejectionReason": null, "role": "SIGNER", "readStatus": "OPENED", "signingStatus": "SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:52:18.277Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.rejected` Triggered when a recipient rejects the document. **Event name:** `DOCUMENT_REJECTED` The recipient's `signingStatus` changes to `REJECTED` and `rejectionReason` contains their reason. ```json { "event": "DOCUMENT_REJECTED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "status": "PENDING", "title": "contract.pdf", "source": "DOCUMENT", "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "email": "signer@example.com", "name": "John Doe", "role": "SIGNER", "signedAt": "2024-04-22T11:48:07.569Z", "rejectionReason": "I do not agree with the terms", "readStatus": "OPENED", "signingStatus": "REJECTED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:48:07.945Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.cancelled` Triggered when a pending document is explicitly cancelled with `POST /envelope/cancel`, or when a document owner or team member deletes a document. Deleting a draft or pending document hard-deletes it, while deleting a completed document soft-deletes it. This event is **not** triggered when a recipient hides a document from their inbox. **Event name:** `DOCUMENT_CANCELLED` ```json { "event": "DOCUMENT_CANCELLED", "payload": { "id": 7, "envelopeId": "envelope_abcdefhiklmnorst", "externalId": null, "userId": 3, "authOptions": null, "formValues": null, "visibility": "EVERYONE", "title": "contract.pdf", "status": "PENDING", "createdAt": "2025-01-27T11:02:14.393Z", "updatedAt": "2025-01-27T11:03:16.387Z", "completedAt": null, "deletedAt": null, "teamId": null, "templateId": null, "source": "DOCUMENT", "documentMeta": { "id": "cm6exvn96006ji02rqvzjvwoy", "subject": "", "message": "", "timezone": "Etc/UTC", "dateFormat": "yyyy-MM-dd hh:mm a", "redirectUrl": "", "signingOrder": "PARALLEL", "allowDictateNextSigner": false, "typedSignatureEnabled": true, "uploadSignatureEnabled": true, "drawSignatureEnabled": true, "language": "en", "distributionMethod": "EMAIL", "emailSettings": null }, "recipients": [ { "id": 7, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 7, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "XkKx1HCs6Znm2UBJA2j6o", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": null, "authOptions": { "accessAuth": null, "actionAuth": null }, "signingOrder": 1, "rejectionReason": null, "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ], "Recipient": [ { "id": 7, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 7, "templateId": null, "email": "signer@example.com", "name": "John Doe", "token": "XkKx1HCs6Znm2UBJA2j6o", "documentDeletedAt": null, "expiresAt": null, "expirationNotifiedAt": null, "signedAt": null, "authOptions": { "accessAuth": null, "actionAuth": null }, "signingOrder": 1, "rejectionReason": null, "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2025-01-27T11:03:27.730Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `recipient.expired` Triggered when a recipient's signing deadline passes on a pending document before they sign or reject it. **Event name:** `RECIPIENT_EXPIRED` The recipient's `expiresAt` contains the signing deadline, and `expirationNotifiedAt` is set when the expiration is processed. ```json { "event": "RECIPIENT_EXPIRED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "status": "PENDING", "title": "contract.pdf", "source": "DOCUMENT", "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "documentId": 10, "templateId": null, "email": "signer@example.com", "name": "John Doe", "role": "SIGNER", "expiresAt": "2024-04-22T11:51:00.000Z", "expirationNotifiedAt": "2024-04-22T11:52:00.000Z", "readStatus": "OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-22T11:52:00.000Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `document.reminder.sent` Triggered when a reminder email is sent to a recipient who has not yet completed their action. **Event name:** `DOCUMENT_REMINDER_SENT` ```json { "event": "DOCUMENT_REMINDER_SENT", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "status": "PENDING", "title": "contract.pdf", "source": "DOCUMENT", "recipients": [ { "id": 52, "envelopeId": "envelope_abcdefhiklmnorst", "email": "signer@example.com", "name": "John Doe", "role": "SIGNER", "readStatus": "NOT_OPENED", "signingStatus": "NOT_SIGNED", "sendStatus": "SENT" } ] }, "createdAt": "2024-04-23T09:00:00.000Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` --- ## Template Events Template events track changes to reusable document templates. Template payloads use the same structure as document payloads. For `TEMPLATE_CREATED`, `TEMPLATE_UPDATED`, and `TEMPLATE_DELETED` the template's own legacy numeric ID is in `id` and `templateId` is `null`. Only `TEMPLATE_USED` — whose payload describes the new document envelope created from the template — carries the originating template's legacy ID in `templateId`, with `source` set to `TEMPLATE`. ### `template.created` Triggered when a new template is created. **Event name:** `TEMPLATE_CREATED` ```json { "event": "TEMPLATE_CREATED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "title": "My Template", "status": "DRAFT", "templateId": null, "source": "TEMPLATE", "recipients": [] }, "createdAt": "2024-04-22T11:44:44.779Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `template.updated` Triggered when a template's settings, recipients, or fields are modified. **Event name:** `TEMPLATE_UPDATED` ```json { "event": "TEMPLATE_UPDATED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "title": "My Updated Template", "status": "DRAFT", "templateId": null, "source": "TEMPLATE", "recipients": [] }, "createdAt": "2024-04-22T12:00:00.000Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `template.deleted` Triggered when a template is deleted. **Event name:** `TEMPLATE_DELETED` ```json { "event": "TEMPLATE_DELETED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "title": "Deleted Template", "status": "DRAFT", "templateId": null, "source": "TEMPLATE", "recipients": [] }, "createdAt": "2024-04-22T13:00:00.000Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` ### `template.used` Triggered when a document is created from a template. This event fires alongside `document.created`, giving you a way to specifically track template usage. **Event name:** `TEMPLATE_USED` ```json { "event": "TEMPLATE_USED", "payload": { "id": 10, "envelopeId": "envelope_abcdefhiklmnorst", "title": "Document from Template", "status": "DRAFT", "templateId": 10, "source": "TEMPLATE", "recipients": [] }, "createdAt": "2024-04-22T14:00:00.000Z", "webhookEndpoint": "https://your-endpoint.com/webhook" } ``` --- ## Event Summary ### Document Events | Event | Trigger | Key Changes | | ---------------------------- | ------------------------------------------- | ------------------------------------------------------------ | | `DOCUMENT_CREATED` | Document uploaded or created from template | `status: "DRAFT"` | | `DOCUMENT_SENT` | Document sent to recipients | `status: "PENDING"`, recipients `sendStatus: "SENT"` | | `DOCUMENT_OPENED` | Recipient opens document for the first time | Recipient `readStatus: "OPENED"` | | `DOCUMENT_SIGNED` | Recipient signs document | Recipient `signingStatus: "SIGNED"`, `signedAt` set | | `DOCUMENT_RECIPIENT_COMPLETED` | Recipient completes their action | Recipient `signingStatus: "SIGNED"`, `signedAt` set | | `DOCUMENT_COMPLETED` | All recipients complete actions | `status: "COMPLETED"`, `completedAt` set | | `DOCUMENT_REJECTED` | Recipient rejects document | Recipient `signingStatus: "REJECTED"`, `rejectionReason` set | | `DOCUMENT_CANCELLED` | Pending document explicitly cancelled, or document deleted | `status: "CANCELLED"` after explicit cancellation; deletion may remove or soft-delete the document | | `RECIPIENT_EXPIRED` | Recipient signing deadline passes | Recipient `expiresAt` passed, `expirationNotifiedAt` set | | `DOCUMENT_REMINDER_SENT` | Reminder email sent to recipient | No status changes | ### Template Events | Event | Trigger | Key Changes | | ------------------ | ------------------------------------ | ------------------------- | | `TEMPLATE_CREATED` | New template created | `source: "TEMPLATE"` | | `TEMPLATE_UPDATED` | Template settings or fields modified | `source: "TEMPLATE"` | | `TEMPLATE_DELETED` | Template deleted | `source: "TEMPLATE"` | | `TEMPLATE_USED` | Document created from template | `source: "TEMPLATE"` | --- ## Handling Events When processing webhook events: {/* prettier-ignore */} **Verify the signature** — Check the `X-Documenso-Secret` header matches your configured secret **Check event type** — Use the `event` field to determine the action **Process idempotently** — Webhooks may be retried, so handle duplicate events **Respond quickly** — Return a `2xx` status code within 10 seconds ```typescript app.post('/webhook', (req, res) => { const secret = req.headers['x-documenso-secret']; if (secret !== process.env.WEBHOOK_SECRET) { return res.status(401).send('Unauthorized'); } const { event, payload } = req.body; switch (event) { case 'DOCUMENT_COMPLETED': console.log(`Document ${payload.id} completed`); break; case 'DOCUMENT_RECIPIENT_COMPLETED': const signer = payload.recipients.find((r) => r.signingStatus === 'SIGNED'); console.log(`${signer?.name} completed their action on document ${payload.id}`); break; case 'DOCUMENT_SIGNED': console.log(`Signature added to document ${payload.id}`); break; case 'DOCUMENT_REJECTED': const rejecter = payload.recipients.find((r) => r.signingStatus === 'REJECTED'); console.log(`${rejecter?.name} rejected: ${rejecter?.rejectionReason}`); break; case 'TEMPLATE_USED': console.log(`Template ${payload.templateId} used to create document ${payload.id}`); break; } res.status(200).send('OK'); }); ``` --- ## See Also - [Webhook Setup](/docs/developers/webhooks/setup) - Configure webhook endpoints - [Webhook Verification](/docs/developers/webhooks/verification) - Verify webhook signatures