Agent skill

Zoho Sign Webhooks Skill

Receive and verify Zoho Sign webhooks. Use when setting up Zoho Sign webhook handlers, debugging X-ZS-WEBHOOK-SIGNATURE HMAC verification, or handling e-signature events like RequestSubmitted, RequestSigningSuccess, RequestCompleted, RequestRejected and RequestExpired.

Install this skill

npx skills add hookdeck/webhook-skills --skill zoho-sign-webhooks


Zoho Sign is Zoho's e-signature product. Admins register up to two webhooks per account (Enterprise, API, Zoho One and People Plus plans). Each delivery is a JSON body with a requests object (the signature request) and a notifications object (what happened). HMAC signing is opt-in per webhook: tick the HMAC signature checkbox and Zoho Sign adds the X-ZS-WEBHOOK-SIGNATURE header.

When to Use This Skill

  • How do I receive Zoho Sign webhooks?
  • How do I verify the X-ZS-WEBHOOK-SIGNATURE header?
  • Why does my Zoho Sign HMAC verification fail?
  • How do I handle RequestCompleted or RequestSigningSuccess events?
  • How do I secure a Zoho Sign webhook endpoint?

Resources

Verification (core)

The signature is base64(HMAC-SHA256(key = secret as UTF-8, message = raw request body)) in X-ZS-WEBHOOK-SIGNATURE. No timestamp is signed.

const crypto = require('crypto');

function verifyZohoSign(rawBody, signatureHeader, secret) {
  if (!signatureHeader || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('base64');
  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Zoho's docs write the formula as HMAC SHA-256(payload+secret_key). That wording is misleading: the secret is the HMAC key, it is not appended to the payload. Use the raw body bytes (express.raw({ type: '*/*' }) in Express) so any content type verifies.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Event Types

The event is notifications.operation_type:

operation_typeFires when
RequestSubmittedA document is submitted for signature
RequestViewedA submitted document is viewed
RequestSigningSuccessOne signer completes signing
RequestCompletedAll signers/approvers have finished
RequestRejectedA signer rejects the request
RequestRecalledThe sender recalls the request
RequestForwardedA signer forwards the request to someone else
RequestExpiredThe signing deadline passes

Environment Variables

ZOHO_SIGN_WEBHOOK_SECRET=your_secret_key   # the key you entered/generated in Zoho Sign

Local Development

# Express / Next.js
npx hookdeck-cli listen 3000 zoho-sign --path /webhooks/zoho-sign
# FastAPI
npx hookdeck-cli listen 8000 zoho-sign --path /webhooks/zoho-sign

No account required: the CLI creates a guest account on first run and gives you a tunnel plus a web UI for inspecting requests.


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 4, 2026

View on GitHub →