Skip to content
ZiaSignZiaSign
ZiaSign
  • How it works
  • Free PDF Tools
  • 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
  • Free PDF ToolsFree
  • Browse use casesNew
  • How-to guides100+
  • How it works
  • Pricing
  • Documentation

Theme

Light mode

Sign Now
Sign Now
  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

  • How it works
  • Pricing
  • About
  • Blog
  • Security

Documentation

  • All Docs
  • Quickstart
  • API Authentication
  • Webhooks
  • Templates
  • Integrations

Free PDF Tools

  • All Tools
  • How-To Guides
  • Use-Case Guides
  • Organize PDFs
  • Convert PDFs
  • Edit PDFs
  • Security
  • Optimize
  • AI Tools

Compare

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

Company

  • FAQs
  • Investors
  • Privacy Policy
  • Terms of Services
ZiaSignZiaSign
ZiaSign

AI-native e-signature and document workflows for modern teams.

© 2026 ZiaSign. All rights reserved.

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