---
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    | Document or template ID                                |
| `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`        |
| `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` or `TEMPLATE`                       |
| `documentMeta`   | object    | 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               |
| `password`                 | string? | Document access password (if set)       |
| `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                               |
| `documentId`           | number?   | Parent document ID                         |
| `templateId`           | number?   | Template ID if created from a template     |
| `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               |

---

## 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,
    "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": "UTC",
      "password": null,
      "dateFormat": "MM/DD/YYYY",
      "redirectUrl": null,
      "signingOrder": "PARALLEL",
      "allowDictateNextSigner": false,
      "typedSignatureEnabled": true,
      "uploadSignatureEnabled": true,
      "drawSignatureEnabled": true,
      "language": "en",
      "distributionMethod": "EMAIL",
      "emailSettings": null
    },
    "recipients": [
      {
        "id": 52,
        "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,
        "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,
    "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": "UTC",
      "password": null,
      "dateFormat": "MM/DD/YYYY",
      "redirectUrl": null,
      "signingOrder": "PARALLEL",
      "allowDictateNextSigner": false,
      "typedSignatureEnabled": true,
      "uploadSignatureEnabled": true,
      "drawSignatureEnabled": true,
      "language": "en",
      "distributionMethod": "EMAIL",
      "emailSettings": null
    },
    "recipients": [
      {
        "id": 52,
        "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,
        "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,
    "status": "PENDING",
    "title": "contract.pdf",
    "source": "DOCUMENT",
    "recipients": [
      {
        "id": 52,
        "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,
    "status": "COMPLETED",
    "title": "contract.pdf",
    "source": "DOCUMENT",
    "completedAt": "2024-04-22T11:52:05.707Z",
    "recipients": [
      {
        "id": 51,
        "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,
    "status": "PENDING",
    "title": "contract.pdf",
    "source": "DOCUMENT",
    "recipients": [
      {
        "id": 52,
        "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,
    "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": "UTC",
      "password": null,
      "dateFormat": "MM/DD/YYYY",
      "redirectUrl": null,
      "signingOrder": "PARALLEL",
      "allowDictateNextSigner": false,
      "typedSignatureEnabled": true,
      "uploadSignatureEnabled": true,
      "drawSignatureEnabled": true,
      "language": "en",
      "distributionMethod": "EMAIL",
      "emailSettings": null
    },
    "recipients": [
      {
        "id": 50,
        "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,
        "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,
        "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,
        "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,
    "status": "PENDING",
    "title": "contract.pdf",
    "source": "DOCUMENT",
    "recipients": [
      {
        "id": 52,
        "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 the document owner or a team member deletes a document. Draft and pending documents are hard-deleted, while completed documents are soft-deleted.

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,
    "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",
      "password": null,
      "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,
        "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,
        "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"
}
```

### `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,
    "status": "PENDING",
    "title": "contract.pdf",
    "source": "DOCUMENT",
    "recipients": [
      {
        "id": 52,
        "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, with `source` set to `TEMPLATE` and `templateId` populated.

### `template.created`

Triggered when a new template is created.

**Event name:** `TEMPLATE_CREATED`

```json
{
  "event": "TEMPLATE_CREATED",
  "payload": {
    "id": 10,
    "title": "My Template",
    "status": "DRAFT",
    "templateId": 10,
    "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,
    "title": "My Updated Template",
    "status": "DRAFT",
    "templateId": 10,
    "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,
    "title": "Deleted Template",
    "status": "DRAFT",
    "templateId": 10,
    "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,
    "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`         | Owner or team member deletes document        | Document cancelled or deleted                                |
| `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 */}
<Steps>
  <Step>
    **Verify the signature** — Check the `X-Documenso-Secret` header matches your configured secret
  </Step>
  <Step>
    **Check event type** — Use the `event` field to determine the action
  </Step>
  <Step>
    **Process idempotently** — Webhooks may be retried, so handle duplicate events
  </Step>
  <Step>
    **Respond quickly** — Return a 200 status code within 30 seconds
  </Step>
</Steps>

```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
