How to create ?
- A WellWallet account (Sign up)
- An API key with appropriate permissions: Settings - Settings - API - Webhooks Managment - Create
whsec_...). You need it to verify that notifications really come from WellWallet — see Verifying webhooks.
Security
Every webhook is signed with HMAC-SHA256 following the open Standard Webhooks specification. Verifying the signature is the main way to make sure a request was sent by WellWallet and was not modified on the way.Request headers
Each webhook request contains three headers:Verifying webhooks
1
Take the raw request body
Use the body exactly as it was received, before any JSON parsing. Parsing and re-serializing changes the bytes (key order, spaces) and the signature will not match.
2
Check the timestamp
Reject the request if
webhook-timestamp differs from your current time by more than 5 minutes. This protects you from replayed requests.3
Build the signed content
Join the message ID, the timestamp and the raw body with dots:
4
Calculate the expected signature
Remove the
whsec_ prefix from your signing key and base64-decode the rest — these bytes are the HMAC key. Calculate HMAC-SHA256 of the signed content and base64-encode the result.5
Compare signatures
Compare the result with the value after
v1, in webhook-signature using a constant-time comparison. If no signature matches, reject the request with 401.Code examples
You can use the official Standard Webhooks libraries (available for Node.js, Python, PHP, Go, Java, Ruby, C#, Rust and others) — see github.com/standard-webhooks/standard-webhooks. Or verify the signature manually:Test vector
Use these values to check your implementation. With the timestamp check disabled, the signature must be valid:Source IP addresses
As an additional layer of protection, you can allow requests to your webhook endpoint only from WellWallet IP addresses:Signing key management
Each webhook has its own signing key. You can manage it in the bot: open the webhook card in Webhooks Managment — it shows whether request signing is configured.- Generate / Regenerate signing key — creates a new key. The action requires confirmation and your 2FA code.
- The new key is shown once and the message is deleted after 5 minutes.
- The previous key stops working immediately. Update the key on your server right away — until then signature verification of new notifications will fail.
Delivery and retries
- Notifications are sent as
POSTrequests withContent-Type: application/json. - Respond with HTTP
200or201to confirm receipt. Any other response or a timeout is treated as a failed delivery, and the request is retried several times. - A retried request has the same
webhook-id, but a newwebhook-timestampand a new signature. Usewebhook-idto process each event only once.
Request body
The event is sent in thedata object. Technical delivery metadata is passed in data.sys:
System fields (data.sys)
data.sys contains technical information for troubleshooting. Do not build business logic on these fields — use webhook-id to deduplicate notifications.Transaction statuses
Thestatus field shows the current state of the transaction:
For transactions with the
suspended status, the request also contains the aml_score field — the AML risk score of the transaction.
Deposit request example
Withdrawal request example
Migration for existing webhooks
Webhooks created before signing was introduced do not have a signing key and are still delivered without signature headers. This transition period lasts until 2026-12-14 23:59:59 (UTC 0). The request body format also changes when you switch to signed webhooks:sys.obj_id or the conv_* fields, update it to read data.sys.obj_id before generating a signing key.
1
Generate a signing key
Open your webhook card in the bot and press Generate signing key. From that moment on, all notifications for this webhook are signed.
2
Add signature verification
Implement the verification described in Verifying webhooks and deploy it together with the key.
3
Reject unsigned requests
After verification works, reject any request without valid signature headers.