Signature headers
Each request carries 3 headers, following the Standard Webhooks specification.
During a key rotation,
webhook-signature carries 2 signatures, one per key. A request is valid when any one of them verifies.
Getting your public keys
Your workspace’s public keys are published at a URL anyone can read. Public keys can’t sign anything, so they’re safe to share.public_key is whpk_ followed by the standard base64 (not base64url) of the 32 raw key bytes. The signature header carries no key ID, so try each key in the list.
Keys come newest first, a page at a time. When next_cursor isn’t null, request the next page with ?cursor=<next_cursor> until it is, and keep every key. A workspace holds one key, or two during a rotation, so the first page is usually the whole set.
Verifying a signature
Verification takes 3 checks, all on the raw request body, before you parse any JSON:- Check the timestamp. Reject a request whose
webhook-timestampis more than 5 minutes from your clock. This stops an old request from being replayed. - Build the signed content. Join
webhook-id,webhook-timestampand the raw body with a.between each:{webhook-id}.{webhook-timestamp}.{raw body}. - Verify. For each
v1aentry inwebhook-signature, verify its signature over the signed content with each of your public keys. Accept the request if any pair matches.
cryptography for Python), and returns true only for a genuine request.
When the key changes
A workspace admin can rotate or revoke the signing key from See public keys. Your receiver keeps working through both if it reads the key URL above, or if you add the new key in time.- Rotation: Base44 signs with both the old and the new key for 24 hours, and both appear in the key URL. If you store the key in your receiver, add the new one before the overlap ends. An admin can end the overlap early with Finish rotation.
- Revocation: Base44 stops signing with the revoked key on the next request. A receiver that reads the key URL picks up the replacement within 5 minutes. A receiver that stores only the revoked key rejects deliveries until you give it the new one, and those deliveries retry meanwhile.