Your API Key
Each webhook endpoint is assigned a unique API key by Baanx. This key is the shared secret used to generate and verify signatures. Key properties:- Generated and managed by Baanx — not client-generated
- Unique per webhook endpoint
- Can be rotated on request (or via the Rotate Key API)
- Custom keys can be configured in special cases
Request Headers
Every webhook request includes these headers:How the Signature is Calculated
Baanx constructs the signature as follows:X-Signature header.
Verification Steps
1
Extract headers
Read
X-Timestamp and X-Signature from the incoming request headers.2
Check the timestamp
Reject the request if the timestamp is more than 300 seconds (5 minutes) away from the current server time. This prevents replay attacks.
3
Build the signature payload
Concatenate the timestamp, a literal
., and the raw JSON body string:4
Compute the expected signature
Calculate HMAC-SHA256 over the payload using your API key, then hex-encode the result (lowercase).
5
Compare signatures
Use a timing-safe comparison to compare the computed signature against
X-Signature. Never use === — it is vulnerable to timing attacks.Code Examples
Replay Protection
TheX-Timestamp header protects against replay attacks — where an attacker captures a legitimate webhook request and re-sends it later.
Your endpoint should reject any request where the timestamp differs from the current server time by more than 5 minutes (300 seconds):
Common Verification Mistakes
Parsing the body before verifying
Parsing the body before verifying
If you parse the raw JSON into an object and then re-serialise it to compute the signature, the result may differ from the original raw string (different whitespace, key ordering). Always use the raw request body string from the HTTP request.
Using string equality instead of timing-safe comparison
Using string equality instead of timing-safe comparison
Using
=== to compare signatures leaks information through response time differences. Always use crypto.timingSafeEqual (Node.js) or hmac.compare_digest (Python).Not checking the timestamp
Not checking the timestamp
Without timestamp validation, a captured webhook request could be replayed indefinitely. Always reject requests where
| now - timestamp | > 300.Next Steps
Delivery & Retries
How to respond correctly and what happens when delivery fails
Rotate Signing Key
API reference for rotating your webhook API key