improved

Withdrawals SDK: Webhook header update + payment_id field now included in /client_auth_token response

Release date

June 13th, 2025

Release type

Action is required if you fall into any of the below buckets:

  • You currently consume any webhooks of ours
  • You currently use the Account Funding: Withdrawals product

Summary

Payments webhooks: new timestamp header

📢 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 (cutover date is August 12th, 2025).

🔧 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-signatureto_hex(rsa(sha256(payload + timestamp), zh-sec-key)) — RSA signature of payload + timestamp.

/client_auth_token response: new payment_id field

We will now be providing the payment_id on the response of the POST /client_auth_token call If the permission = crypto-withdrawals or crypto-payouts. This payment_id will then be included in all subsequent payment webhook events associated with that SDK session. This payment_id is also included in the GET /payments/{payment_id} call.

Action required

  • For any Platforms that are currently consuming any webhooks of ours, the grace period to transition to our new webhook verification convention will end on August 12th, 2025. We'll send periodic reminders and as always can offer technical support if there are any questions.
  • For those Platforms that are using the Account Funding: Withdrawal product, please begin to consume the payment_id from the POST /client_auth_token as soon as possible. We'll then schedule a conformance test in accordance with the requirements laid out in the Withdrawals - Reconciliation guide.

Endpoints impacted

  • POST /client_auth_token

Relevant documentation