Webhook Security

Zero Hash webhooks use request headers to ensure secure message delivery and verification. Our preferred method for securing webhooks is RSA-based signing, which avoids transmitting shared secrets and enables strong authenticity guarantees. We also support HMAC token-based signatures for clients preferring a simpler integration.

📢 Security Enhancement
To strengthen webhook security against replay attacks, we’ve introduced a new mechanism that includes a timestamp and new signature headers. These additions allow you to verify not only the authenticity of a webhook, but also its timeliness, helping prevent intercepted messages from being reused maliciously.



🔄 Graceful Transition Plan
To allow a smooth migration, both the existing and new security headers will be sent during a grace period. We encourage clients to begin validating the new headers as soon as possible, as the old headers will be deprecated in the future.

✅ Current headers: Will continue to be sent during the transition.

✅ New headers: Available now for improved protection.

❌ Deprecated: The old signature-only verification will be phased out after the grace period (timeline to be announced).



🔧 Header Reference

Standard Headers

NameDescription
x-zh-hook-notification-idUnique identifier for the notification. Use for idempotency checks.
x-zh-hook-payload-typeType of payload (e.g., participant_status_changed, payment_status_changed, etc.).

Depending on your security configuration, additional headers may also be included:


Current Security Headers (Legacy)

NameDescription
x-zh-hook-signature-256to_hex(hmac(sha_256(payload), your-secret))used if token-based signing was configured.
x-zh-hook-rsa-signature-256to_hex(rsa(sha_256(payload), zh-sec-key))— RSA signature of payload.

New Security Headers (Replay Attack Protection)

NameDescription
x-zh-hook-timestampUNIX timestamp (in milliseconds) when the webhook request was generated. Clients should validate that this value is within an acceptable window (e.g., ±5 minutes) of their system clock.
x-zh-hook-signatureto_hex(hmac(sha256(payload + timestamp), your-secret)) — includes timestamp in signature for replay protection.
`x-zh-hook-rsa-signature``to_hex(rsa(sha256(payload + timestamp), zh-sec-key)) — RSA signature of payload + timestamp.


🛡️ Recommended Verification Process

  1. Extract the following from the headers:
    1. x-zh-hook-timestamp
    2. x-zh-hook-signature or x-zh-hook-rsa-signature
  2. Check the timestamp:
    1. Ensure it's within ±5 minutes of your system time to guard against replay attacks.
  3. Reconstruct the signed message:
    1. Concatenate payload + timestamp (as raw strings, no delimiters).
  4. Validate the signature:
    1. For HMAC: Compute hmac(sha256(payload + timestamp), your-secret).
    2. For RSA: Verify rsa(sha256(payload + timestamp), zh-public-key).

🧭 IP Addresses

Zero Hash’s webhook requests will originate from the following IP addresses, should you need an allow-list:

  • 18.189.25.175/32
  • 3.18.218.32/32
  • 3.22.145.85/32

Sample Webhook Signatures