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
Name | Description |
---|---|
x-zh-hook-notification-id | Unique identifier for the notification. Use for idempotency checks. |
x-zh-hook-payload-type | Type 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)
Name | Description |
---|---|
x-zh-hook-signature-256 | to_hex(hmac(sha_256(payload), your-secret)) used if token-based signing was configured. |
x-zh-hook-rsa-signature-256 | to_hex(rsa(sha_256(payload), zh-sec-key)) — RSA signature of payload. |
New Security Headers (Replay Attack Protection)
Name | Description |
---|---|
x-zh-hook-timestamp | UNIX 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-signature | to_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
- Extract the following from the headers:
x-zh-hook-timestamp
x-zh-hook-signature
orx-zh-hook-rsa-signature
- Check the timestamp:
- Ensure it's within ±5 minutes of your system time to guard against replay attacks.
- Reconstruct the signed message:
- Concatenate
payload + timestamp
(as raw strings, no delimiters).
- Concatenate
- Validate the signature:
- For HMAC: Compute
hmac(sha256(payload + timestamp), your-secret)
. - For RSA: Verify
rsa(sha256(payload + timestamp), zh-public-key)
.
- For HMAC: Compute
🧭 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