Skip to main content
Every webhook request from Paxos Labs includes a cryptographic signature that lets you confirm the request is authentic and hasn’t been tampered with. Always verify signatures before processing webhook payloads.

Headers

Each webhook POST request includes these headers:

Signature Scheme

X-PAXOS-LABS-SIGNATURE contains the raw hex-encoded HMAC-SHA256 digest. The timestamp used in the HMAC computation is sent in the separate X-PAXOS-LABS-TIMESTAMP header.

Verification Algorithm

1

Read the timestamp and signature headers

Read X-PAXOS-LABS-TIMESTAMP for the RFC 3339 timestamp and X-PAXOS-LABS-SIGNATURE for the hex signature.
2

Check the timestamp

Reject requests where the timestamp is more than 5 minutes from your server’s current time. This protects against replay attacks.
3

Construct the signed payload

Concatenate the timestamp, a literal period (.), and the raw request body (the exact bytes received — do not parse and re-serialize):
4

Compute the expected signature

Calculate an HMAC-SHA256 using your endpoint’s signing secret as the key and the constructed string as the message. Hex-encode the result.
5

Compare signatures

Use a constant-time comparison to check that your computed signature matches the v1 value from the signature header. This prevents timing attacks.

Implementation Examples

Use timingSafeEqual instead of === to prevent timing side-channel attacks.

Best Practices

Never process a webhook payload without verifying the signature first. An unverified payload could be forged by a malicious actor.
Standard string comparison (===, ==) leaks timing information that attackers can exploit. Always use timingSafeEqual (Node.js), hmac.compare_digest (Python), or hmac.Equal (Go).
Reject events where the timestamp is more than 5 minutes from your server’s clock. This prevents captured requests from being replayed later.
Compute the HMAC over the exact bytes received in the HTTP body. Parsing to JSON and re-serializing can change whitespace or key ordering, producing a different signature.
Keep your signing secret in a secrets manager or encrypted environment variable — never hard-code it or commit it to source control.
Return a 2xx status code within 10 seconds. Move heavy processing to a background queue so the webhook handler returns immediately.
Use the event id field to deduplicate. Store processed event IDs and skip any that you’ve already handled.

Troubleshooting