Verifying webhook signatures
Check that a webhook came from Teak before you act on it.
When your subscription has a secret, Teak signs every webhook. Verify the signature before you act on an event, so no one else can send your endpoint fake events.
The recipe below walks through the code in Node.js and Python. This page covers the header, test values, and keeping your secret safe.
The signature header
Each request includes:
X-Protecht-Signature: sha256: 9gVpchQZGFoyjw+fuIl6ZgwR5vkOGuhc63yzDdD6cko=The value is the algorithm (sha256), a colon and a space, then a base64-encoded HMAC-SHA256 of the raw request body, keyed with your subscription's secret.
Without a secret, the header contains a timestamp instead (t: 1727539200). Add a secret to your subscription to receive signed webhooks.
Requests also include X-TicketGuardian-Signature with the same value, for older integrations. Use X-Protecht-Signature.
Test your verification
Check your code against this example before testing with real events:
| Input | Value |
|---|---|
| Secret | so-secret |
| Raw body | {"foo": "bar"} (with a space after the colon) |
| Expected header | sha256: 9gVpchQZGFoyjw+fuIl6ZgwR5vkOGuhc63yzDdD6cko= |
Your function should return true for this input, and false if you change the secret or a single byte of the body.
Keep your secret safe
- Store the secret in your server's secret manager or environment, never in source control or client-side code.
- Signatures don't include a timestamp, so they don't protect against a request being replayed. Handle repeats as described in Receiving webhooks, and serve your endpoint over HTTPS only.
- To rotate the secret, accept both the old and new secrets on your server while you update the subscription, so no webhook is rejected during the switch:
Next steps
With signatures checked, handle the events you subscribe to:
- Handle contract events when protection is issued, voided, canceled, or changed.
- Track a customer's refund request from submission to decision with refund request events.
Updated about 1 month ago
