Webhooks
Webhooks let you receive HTTP POST requests to your server when events happen in VisiSign — such as a document being signed or completed. Use them to trigger downstream automations, send notifications, or sync data with other systems.
Creating a webhook endpoint
Section titled “Creating a webhook endpoint”- Go to Settings > Webhooks in VisiSign.
- Enter the HTTPS URL that will receive events.
- Select which events to subscribe to (or leave all selected).
- Click Add Endpoint. The signing secret is shown once — copy it immediately.
Supported events
Section titled “Supported events”| Event | Fires when |
|---|---|
signature_request.sent | A signature request is sent to signers |
signature_request.viewed | A signer opens the signing link |
signature_request.signed | A signer completes their signature |
signature_request.declined | A signer declines to sign |
signature_request.completed | All signers have signed |
signature_request.expired | The request reaches its expiration date |
signature_request.cancelled | The request is cancelled by the sender |
Subscribe to all events by leaving the events array empty, or select specific ones.
Payload format
Section titled “Payload format”Every webhook delivery is an HTTP POST with a JSON body:
{ "event": { "type": "signature_request.signed", "timestamp": "2026-03-04T12:00:00Z" }, "signature_request": { "id": "sr_123", "title": "Service Agreement", "status": "sent", "signers": [ { "id": "sig_456", "name": "Jane Smith", "email": "jane@example.com", "status": "signed", "signed_at": "2026-03-04T12:00:00Z" } ] }}Verifying signatures
Section titled “Verifying signatures”Each webhook endpoint has a signing secret (prefixed whsec_). Use it to verify that deliveries are genuinely from VisiSign by checking the X-VisiSign-Signature header.
Python
Section titled “Python”import hmacimport hashlib
def verify_signature(payload_body: bytes, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode(), payload_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(f"sha256={expected}", signature)expected = OpenSSL::HMAC.hexdigest("SHA256", secret, payload_body)valid = Rack::Utils.secure_compare("sha256=#{expected}", signature)Node.js
Section titled “Node.js”import { createHmac, timingSafeEqual } from "crypto";
function verifySignature(payloadBody, signature, secret) { const expected = "sha256=" + createHmac("sha256", secret) .update(payloadBody) .digest("hex"); return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));}Testing
Section titled “Testing”Send a test event from the VisiSign dashboard by clicking Test next to any webhook endpoint. This sends a delivery with a test payload so you can verify your endpoint is receiving and processing events correctly.
Failure handling
Section titled “Failure handling”Endpoints that fail to return a 2xx response accumulate consecutive failures. After 10 consecutive failures, the endpoint is automatically disabled. Fix your endpoint and re-create it in Settings.
Request headers
Section titled “Request headers”Each delivery includes these headers:
| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | VisiSign-Webhooks/1.0 |
X-VisiSign-Event | The event type (e.g. signature_request.signed) |
X-VisiSign-Signature | HMAC-SHA256 signature for verification |