Files
documenso/apps/docs/content/docs/developers/webhooks/index.mdx
T
Ephraim Duncan 29020bcbed docs(webhooks): correct retry policy, timeout and payload reference (#3132)
## Description

Corrects the webhooks documentation, which described delivery behavior
that does not exist in the implementation.

## Changes Made

- Replaced the fabricated retry schedule (5 attempts / immediate-to-2h
backoff) with the real provider-dependent behavior: retries belong to
the job provider (`NEXT_PRIVATE_JOBS_PROVIDER`) — local (default) 4
total attempts back-to-back, BullMQ 3 attempts with exponential backoff
from 1s, Inngest 5 attempts with platform backoff.
- Fixed the webhook timeout from 30 seconds to 10 seconds
(`WEBHOOK_TIMEOUT_MS = 10_000`, hard abort).
- Clarified failure semantics: non-2xx fails, 3xx redirects are not
followed (`redirect: 'manual'`), network/SSRF-blocked calls record
response code 0; failed deliveries mark only the `WebhookCall` record —
the webhook itself is never auto-disabled.
- Corrected URL requirements: `http://` is accepted; documented the SSRF
guard (private/loopback blocked,
`NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS` bypass for self-hosters).
- Added `envelopeId` to both field tables and all payload/recipient JSON
examples; framed numeric `id` as the legacy v1 identifier.
- Removed a documented `documentMeta` field that exists in neither the
Zod schema nor Prisma; fixed timezone/dateFormat examples to the
hardcoded `Etc/UTC` / `yyyy-MM-dd hh:mm a` values.
- Added missing `REJECTED`/`CANCELLED` statuses and
`TEMPLATE_DIRECT_LINK` source; fixed `templateId` to `null` on
TEMPLATE_* examples; documented the previously missing
`RECIPIENT_EXPIRED` event across setup, events, and verification pages.

## Testing Performed

Docs-only change. Every claim verified against the implementation
(`execute-webhook-call.ts`, job clients, `webhook-payload.ts`,
`assert-webhook-url.ts`, webhook-router schema).
2026-08-03 12:16:39 +10:00

70 lines
1.9 KiB
Plaintext

---
title: Webhooks
description: Receive real-time notifications for document and template events.
---
## How Webhooks Work
1. You configure a webhook URL in Documenso
2. When an event occurs, Documenso sends an HTTP POST to your URL
3. Your application processes the event and responds with 200 OK
Documenso supports webhook events for the full document lifecycle (created, sent, opened, signed, completed, rejected, cancelled), recipient-level events (recipient completed, reminder sent, recipient expired), and template events (created, updated, deleted, used).
---
## Getting Started
<Cards>
<Card
title="Setup"
description="Configure webhook endpoints."
href="/docs/developers/webhooks/setup"
/>
<Card
title="Events"
description="Available webhook event types."
href="/docs/developers/webhooks/events"
/>
<Card
title="Verification"
description="Verify webhook signatures for security."
href="/docs/developers/webhooks/verification"
/>
</Cards>
---
## Example Payload
```json
{
"event": "DOCUMENT_COMPLETED",
"payload": {
"id": 123,
"envelopeId": "envelope_abcdefhiklmnorst",
"title": "Contract",
"status": "COMPLETED",
"completedAt": "2024-01-15T10:30:00.000Z",
"recipients": [
{
"id": 1,
"envelopeId": "envelope_abcdefhiklmnorst",
"email": "signer@example.com",
"signingStatus": "SIGNED"
}
]
},
"createdAt": "2024-01-15T10:30:00.000Z",
"webhookEndpoint": "https://your-endpoint.com/webhook"
}
```
`payload.id` is the legacy numeric v1 ID. Use `payload.envelopeId` as the canonical v2 identifier. Each recipient repeats `envelopeId` as the reliable parent link because the legacy `documentId` and `templateId` fields depend on the parent envelope type, leaving one of them null.
---
## See Also
- [Document Lifecycle](/docs/concepts/document-lifecycle) - Understanding document statuses