Webhooks let your application react to signing events in real time — no polling required. This guide covers which events are fired, how to verify HMAC signatures, how to build an idempotent handler, and how to test locally.
Three rules for a production-ready webhook endpoint: verify the signature, acknowledge fast, process idempotently.
Compute HMAC-SHA256 of the raw body with your webhook secret. Use timingSafeEqual — never a regular string comparison.
Send 200 OK immediately. Move heavy processing to a background job. Slow responses trigger retries.
Store processed event IDs. Retries are normal — your handler must be safe to call multiple times for the same event.
An e-signature webhook is an HTTP POST request your e-signature service sends to a URL you control when a signing event occurs — for example, when a signer views a document, completes a signature, or when the last signer finishes and the document is sealed. Webhooks let your application react to signing milestones in real time without polling the API.
GetSigned fires webhooks for: envelope.sent (signing links dispatched), signer.viewed, signer.signed, envelope.completed (all signers done, document sealed), envelope.declined, envelope.voided, and envelope.expired. The most important event for most integrations is envelope.completed — this is when the sealed PDF is ready to download.
GetSigned signs each webhook payload with an HMAC-SHA256 signature using your webhook secret, delivered in the X-GetSigned-Signature request header. To verify: compute HMAC-SHA256 of the raw request body using your secret, then compare in constant time to the header value. Never compare with a standard equality check — use a constant-time comparison to prevent timing attacks.
Return 200 OK as quickly as possible — ideally within 5 seconds. If your handler needs to do significant work (database writes, downstream API calls), acknowledge with 200 immediately and process asynchronously in a background job or queue. GetSigned will retry failed deliveries (non-2xx or timeout) with exponential backoff.
Each webhook event has a unique event_id in the payload. Before processing, check whether you have already handled that event_id (store processed IDs in your database). If yes, return 200 immediately without reprocessing. This prevents duplicate side effects when GetSigned retries a delivery your server acknowledged too slowly or with a transient error.
Use a tunneling tool such as ngrok or Cloudflare Tunnel to expose your local server at a public HTTPS URL. Register that URL as your webhook endpoint in the GetSigned dashboard, then trigger events through the API. Alternatively, GetSigned provides a webhook test tool in the dashboard that fires synthetic events to your endpoint.
Related: Integration guide · Node.js guide · Multi-signer routing · Audit trail guide