Skip to content
ZiaSignZiaSign
ZiaSign
    • Individuals & TeamsPay by document, unlimited users.
    • DevelopersREST API, SDKs, webhooks, sandbox.
    • EnterpriseSSO, QES, dedicated CSM, on-prem.
    Individuals pricingDevelopers pricingEnterprise pricing
  • Free PDF Tools
  • Browse by topic

    • Getting StartedQuickstart, account, first send
    • Documents & SigningPrepare, send, sign, track
    • Developer APIREST, SDKs, webhooks, sandbox
    • AI FeaturesField detection, summaries, Q&A
    • Billing & PlansSubscriptions, invoices, limits
    • Mobile AppiOS & Android guides

    Quick links

    • Quickstart
    • API reference
    • Authentication
    • Webhooks
    • How-to guides
    • Changelog
    Building with the API?Free sandbox, full REST + webhooks, SDKs in 5 languages.
    Browse all documentation
  • Pricing
  • Company

    • About
    • Blog
    • Investors
    • Security

    Compare

    • vs DocuSign
    • vs Adobe Sign
    • vs PandaDoc
    • vs iLovePDF
    • vs Smallpdf
    • vs PDF24
    • vs Sejda
    Investor connectLatest blog
PDF ToolsFreePricing
Start Free
Start Free
  1. Home
  2. Documentation
  3. Developer API
  4. Webhooks
Developer API

Webhooks

Receive real-time HTTP notifications when documents are viewed, signed, completed, or declined.

Last updated April 15, 2026
Quickstart GuideAccount & Organization SettingsDocument TemplatesSecurity & ComplianceHelp & Support
Sending Documents for SignatureThe Signing ExperienceAudit Trail & Legal ValidityBulk SendPDF ToolsDocument Editor & StudioDocument LibraryAnalytics & Reports
API AuthenticationDocuments APIWebhooksSandbox & TestingEmbedded SigningIntegrations
AI Contract AnalysisAI Smart Workflows
Plans & PricingBilling & InvoicesReferral Program
Mobile App Guide
Changelog & Release Notes

Overview

Webhooks send HTTP POST requests to your endpoint whenever document events occur. This lets you build real-time integrations without polling the API.

Setting Up Webhooks

Via Dashboard

  1. Go to Dashboard → Developer APIs → Webhooks tab
  2. Click Create Webhook
  3. Enter your endpoint URL (must be HTTPS)
  4. Select the events you want to receive
  5. Copy the Webhook Secret for signature verification

Via API


Event Types

EventTriggered When
document.createdA new document is created
document.sentA document is sent for signature
document.viewedA signer opens the document
document.signedA signer completes their signature fields
document.completedAll signers have signed the document
document.declinedA signer declines to sign
document.voidedThe sender voids (cancels) the document
document.expiredThe signing period expires

Webhook Payload

All webhooks share a common payload structure:


Signature Verification

Every webhook request includes an X-Webhook-Signature header. Verify it to ensure the request is authentic:



Retry Policy

If your endpoint returns a non-2xx status code or times out (30 seconds), ZiaSign retries with exponential backoff:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry12 hours
6th retry24 hours

After 6 failed attempts, the delivery is marked as failed and you receive an email notification. You can view and manually retry failed deliveries in the dashboard.

Testing Webhooks

Use the Test button in the dashboard to send a sample event to your endpoint. You can also use the sandbox environment to trigger real events without affecting production data.

Frequently asked questions

How do I verify webhook signatures?

Each webhook includes an X-Webhook-Signature header containing an HMAC-SHA256 signature. Verify it using your webhook secret to confirm the request came from ZiaSign.

What happens if my endpoint is down?

ZiaSign retries webhook deliveries with exponential backoff: 1 min, 5 min, 30 min, 2 hours, 12 hours, 24 hours. After 6 failed attempts, the delivery is marked as failed.

Can I receive webhooks for specific events only?

Yes. When creating a webhook subscription, you select which events to subscribe to. You can update the event list at any time.

Related documentation

API Authentication

Authenticate your API requests using API keys with HMAC-SHA256 request signing for maximum security.

Documents API

Create, send, retrieve, download, and manage documents programmatically via the REST API.

Sandbox & Testing

Use the sandbox environment to test your integration with simulated documents, signers, and events.

Previous

Documents API

Next

Sandbox & Testing

On this page

OverviewSetting Up WebhooksVia DashboardVia APIEvent TypesWebhook PayloadSignature VerificationRetry PolicyTesting Webhooks

Product

  • eSignature
  • AI Document Assistant
  • Templates & Workflows
  • Pricing
  • What's New

Solutions

  • Individuals & Teams
  • Developers & API
  • Enterprise
  • Trust & Security

Free PDF Tools

  • Browse All Tools
  • Merge PDF
  • Split PDF
  • Compress PDF
  • PDF to Word
  • Use-Case Guides

Developers

  • Documentation
  • API Reference
  • How-To Guides
  • Status

Compare

  • vs DocuSign
  • vs Adobe Sign
  • vs PandaDoc
  • vs iLovePDF
  • vs Smallpdf
  • vs Sejda

Company

  • Investors
  • Blog
  • Privacy
  • Terms
  • DPA
  • Sub-processors
ZiaSignZiaSign
ZiaSign

Sign. Automate. Scale — with AI.

© 2026 ZiaSign. All rights reserved.

SOC 2 (in audit)GDPR · DPDPeIDAS · ESIGN
bash
curl -X POST "https://api.ziasign.com/api/v1/webhooks" \
  -H "X-Api-Key: $API_KEY" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/ziasign",
    "events": ["document.sent", "document.signed", "document.completed"],
    "description": "Production webhook"
  }'
json
{
  "id": "evt_xyz789",
  "type": "document.completed",
  "createdAt": "2026-04-15T14:32:07Z",
  "data": {
    "documentId": "doc_abc123",
    "documentName": "Service Agreement.pdf",
    "status": "completed",
    "signer": {
      "name": "Jane Doe",
      "email": "jane@example.com",
      "signedAt": "2026-04-15T14:32:07Z"
    }
  }
}
typescript
import crypto from "crypto";

function verifyWebhook(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler
app.post("/webhooks/ziasign", (req, res) => {
  const signature = req.headers["x-webhook-signature"] as string;
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET!
  );

  if (!isValid) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  // Process the event
  const { type, data } = req.body;
  switch (type) {
    case "document.completed":
      // Handle completed document
      break;
    case "document.declined":
      // Handle declined document
      break;
  }

  res.status(200).json({ received: true });
});
python
import hashlib
import hmac
import os

from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["WEBHOOK_SECRET"]


def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), payload, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)


@app.route("/webhooks/ziasign", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-Webhook-Signature", "")
    if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
        return jsonify({"error": "Invalid signature"}), 401

    event = request.json
    event_type = event["type"]

    if event_type == "document.completed":
        # Handle completed document
        pass
    elif event_type == "document.declined":
        # Handle declined document
        pass

    return jsonify({"received": True}), 200