Webhooks
You can configure webhook endpoints via the Weavr Portal, so that you are notified about events that apply to your customers, such as card purchases, completions of due diligence processes, transaction state changes, or receipts of deposits.
To use webhooks, you need to implement an endpoint that listens to events from Weavr. We always send webhooks using a POST request with the event details included in the request body.
See the full webhooks reference for the list of published webhooks.
Configure your app webhook URL
To start receiving webhooks, you need to turn on webhooks and configure the endpoint to which we send the event details through POST. You can do this in the Weavr Portal by navigating to the Settings > Application Details section.

Verify the authenticity of a webhook
When we send a webhook to your configured endpoint, each request includes cryptographic signatures that allow you to verify the request originated from Weavr (has not been tampered with).
HTTP headers
Every webhook request includes the following headers:
| Header | Type | Description |
|---|---|---|
call-ref | String | Unique identifier for this webhook delivery. Use for correlation and idempotencyIdempotency A property of an API that guarantees calling it multiple times with the same inputs produces the same result, with no additional side effects beyond the first call. An idempotent endpoint can therefore be safely retried after network errors or timeouts without risking duplicate transactions or state changes.. |
Published-Timestamp | String | Unix epoch timestamp in milliseconds when the webhook was published. |
Signature (deprecated) | String | Base64-encoded HMAC-SHA256 signature (legacy). |
Signature-v2 | String | Base64-encoded HMAC-SHA256 signature (recommended). |
Signature algorithms
Signature v2 (recommended)
Use Signature-v2 for all new integrations.
The Signature-v2 header contains a Base64-encoded HMAC-SHA256 hash computed over the concatenation of:
call-ref + request_body + published-timestamp
- No separators between the three components
request_bodyis the raw JSON payload exactly as received (do not parse and re-serialize)- Your API key is used as the secret key
API key selection for multiple API clients
If your program has multiple API clients, the platform selects the API key from the client with the oldest creation timestamp.
The webhook headers do not include a key identifier. During key rotation with multiple API clients, verify against your oldest API client first.
Verifying Signature-v2 headers
- Extract
call-ref,Published-Timestamp, andSignature-v2from request headers - Capture the raw request body before any parsing
- Concatenate:
{call-ref}{raw_body}{Published-Timestamp} - Compute HMAC-SHA256 using your API key as the secret
- Base64-encode the result
- Compare with
Signature-v2using constant-time comparison
Code examples
- Shell
- Java
- Python
- Node.js
- C#
echo -n "${CALL_REF}${PAYLOAD}${PUBLISHED_TIMESTAMP}" | \
openssl dgst -sha256 -hmac "${API_KEY}" -binary | base64
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
public boolean verifyWebhookSignature(
String callRef,
String rawBody,
String publishedTimestamp,
String signatureV2,
String apiKey) {
try {
String message = callRef + rawBody + publishedTimestamp;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(
apiKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
String computed = Base64.getEncoder().encodeToString(hash);
return MessageDigest.isEqual(
computed.getBytes(StandardCharsets.UTF_8),
signatureV2.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
return false;
}
}
import hmac
import hashlib
import base64
def verify_webhook_signature(
call_ref: str,
raw_body: str,
published_timestamp: str,
signature_v2: str,
api_key: str
) -> bool:
message = f"{call_ref}{raw_body}{published_timestamp}"
computed = base64.b64encode(
hmac.new(
api_key.encode("utf-8"),
message.encode("utf-8"),
hashlib.sha256
).digest()
).decode("utf-8")
return hmac.compare_digest(computed, signature_v2)
const crypto = require("crypto");
function verifyWebhookSignature(
callRef,
rawBody,
publishedTimestamp,
signatureV2,
apiKey
) {
const message = `${callRef}${rawBody}${publishedTimestamp}`;
const computed = crypto
.createHmac("sha256", apiKey)
.update(message, "utf8")
.digest("base64");
return crypto.timingSafeEqual(
Buffer.from(computed, "utf8"),
Buffer.from(signatureV2, "utf8")
);
}
using System;
using System.Security.Cryptography;
using System.Text;
public static bool VerifyWebhookSignature(
string callRef,
string rawBody,
string publishedTimestamp,
string signatureV2,
string apiKey)
{
var message = $"{callRef}{rawBody}{publishedTimestamp}";
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiKey));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
var computed = Convert.ToBase64String(hash);
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(computed),
Encoding.UTF8.GetBytes(signatureV2));
}
Rotating API keys
If you periodically rotate your API keys, you'll also need to update the Signature-v2 you expect. To do this:
- Create the new API client
- Additionally accept the new
Signature-v2(Webhooks continue using your oldest API client) - Delete the old API client when ready to switch
- Webhooks immediately begin using the new oldest API client
- Stop accepting the old
Signature-v2
During transition, in-flight webhooks may be signed with either key.
Security recommendations
- Verify signatures before processing payloads
- Use constant-time comparison to prevent timing attacks
- Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
- Store API keys securely; never expose in client-side code or logs
Webhook log
The webhook log displays the following information:
Event IDis a unique identifier linked to each webhook event, allowing for tracking and searching of specific events within the Webhook Logs page by searching by the event ID.Createddate is the timestamp when the webhook was initially created.Last Sentdate is the timestamp when the webhook was last triggered or replayed.Event Typeis a categorization of the type of event that triggered the webhook, such as a login, step-up, a type of transaction or an instrumentInstrument A financial product owned by an Identity. There are two types: Managed Accounts (stored-value accounts that hold balances and can receive wire transfers) and Managed Cards (prepaid cards - virtual or physical - used for purchases). operation.Operationdescribes the action associated with the webhook event.- The
HTTP Codereturned by the webhook event in response to the payload delivery attempt, indicating the success or failure of the operation (example 200 for success, 404 for not found, 500 for internal server error). Attemptsis the number of times the webhook event was replayed.Statusof the webhook if it was successful or not.
We restructured the list of webhook events to be presented in descending order, with the latest created event displayed first.
Webhook retries
We send webhooks as POST HTTP requests on the webhook URL that is specified in the Portal > Application Details.
Whenever an HTTP response error (408, 409, 425, 5xx) is received in response to a webhook request, we attempt to resend the webhook according to our webhook retry policy. If retries also result in a failure, the webhook is marked as Failed and no further attempts to send the webhook are made.
Webhook retry policy
If the initial delivery fails, we retry up to 5 times (6 attempts in total) with exponential backoff. The initial delay is 10 seconds, and each subsequent delay is 6× the previous one:
- Retry 1: 10 s after the initial failed attempt
- Retry 2: 60 s after retry 1 (10 s × 6), i.e. 1 minute
- Retry 3: 360 s after retry 2 (60 s × 6), i.e. 5 minutes
- Retry 4: 2160 s after retry 3 (360 s × 6), i.e. 36 minutes
- Retry 5: 12960 s after retry 4 (2160 s × 6), i.e. 3 hours 36 minutes
If retry 5 also fails, the webhook is marked as failed and no further attempts are made.
Webhook logs can be accessed via the Portal. You can also retry the particular webhook yourself via the Portal.
Notify your customers in real time
Webhooks are the trigger you use to push real-time updates to your end customers - by email, push, SMS, or in-app message. The events your customers care about most are typically those that affect their money or their access to it:
- Card transactions: purchases, declines, refunds, and ATM withdrawals - useful for spend alerts and fraud detection.
- Card status changes: card frozen, blocked, or replaced.
- Incoming funds: deposits, incoming wire transfersWire Transfer A transaction that moves funds between accounts. An incoming wire transfer moves funds from a third-party bank account to a Weavr managed account, while an outgoing wire transfer moves funds from a Weavr managed account to a third-party bank account. Wire transfers require the managed account to have an assigned IBAN (for EUR) or sort code and account number (for GBP)., and sends received.
- Outgoing transfers: outgoing wire transfersWire Transfer A transaction that moves funds between accounts. An incoming wire transfer moves funds from a third-party bank account to a Weavr managed account, while an outgoing wire transfer moves funds from a Weavr managed account to a third-party bank account. Wire transfers require the managed account to have an assigned IBAN (for EUR) or sort code and account number (for GBP). and sends, including state changes such as approval, completion, or rejection.
- Identity verification: changes to KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. or KYBKYB Know Your Business - the identity verification process for corporate identities. This process allows you to seamlessly and securely verify your business customer's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. status, including approvals, rejections, and requests for additional information.
- Authentication events: step-up challengesStep-up challenge A two-factor authentication challenge required to step-up a user's authentication token for Strong Customer Authentication (SCA) compliance. Users must complete a second authentication factor (such as OTP via SMS, push notification, or biometrics) to access sensitive information or initiate certain transactions as required by PSD2 regulations. and login activity from new devices, useful for security alerts.
Map each event to the channel that fits its urgency. A card decline or fraud check usually warrants a push notification; a periodic balance summary fits better as an email digest.