Skip to main content
This is a special feature that automatically sends notifications to your server or system whenever a certain event occurs. In our case, that means any movement of funds in wallets created via the Well Wallet. Webhooks allow you to stay informed about all operations in real time without the need to constantly poll the API. It’s convenient, efficient, and saves resources.

How to create ?

  • A WellWallet account (Sign up)
  • An API key with appropriate permissions: Settings - Settings - API - Webhooks Managment - Create
Right after the webhook is created, the bot sends you a signing key (whsec_...). You need it to verify that notifications really come from WellWallet — see Verifying webhooks.
The signing key is shown only once, and the message with it is deleted automatically after 5 minutes. Copy it and store it securely (for example, in your secrets manager). If you lose the key, regenerate it.

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.
Always verify the signature before processing a webhook. Checking the source IP address alone is not enough: anyone who can send requests from an allowlisted network could imitate a notification.

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 POST requests with Content-Type: application/json.
  • Respond with HTTP 200 or 201 to 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 new webhook-timestamp and a new signature. Use webhook-id to process each event only once.

Request body

The event is sent in the data object. Technical delivery metadata is passed in data.sys:
The signature is calculated over the whole raw body.

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

The status 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:
If your integration reads 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.
On 2026-12-14 23:59:59 (UTC 0) the transition period ends automatically: unsigned notifications stop being sent. To resume notifications, generate a signing key and enable the webhook again in the bot.