Skip to main content

Verify Webhook Signatures

Signature header

Brale signs webhook deliveries with HMAC-SHA256. Each request includes:
The signature is computed over the exact raw request body bytes. Signature verification details:
  • The header value is the lowercase hex-encoded HMAC-SHA256 digest (no prefix like v1=, no version, no timestamp).
  • The HMAC is computed over the exact raw request body bytes (no canonicalization).
  • The HMAC key is the Base64URL-decoded sharedSecret value returned when creating the subscription.

Shared secret

When you create a webhook subscription, Brale returns a sharedSecret.
This value is Base64URL encoded. Decode it before using it as the HMAC key. Do not use the encoded string directly as the HMAC key.

Which secret should I use?

Each subscription has its own sharedSecret. Verify each delivery with the secret of the subscription that delivered it. Don’t look up a secret based on data.account_id.
  • With one managing-account subscription, use that subscription’s secret for every event it delivers. This includes events concerning the managing account and events concerning its managed accounts.
  • With multiple subscriptions, verify each delivery with the secret of the corresponding subscription.
Brale returns the sharedSecret only once, when you create the subscription. Store it immediately.

Node.js / TypeScript example

Express example

Mount the webhook route with express.raw() before express.json().

Python example

Common signature verification failures