Signable signs each webhook request so you can verify that the request came from Signable and that the payload was not modified.
This feature is in early access and is currently available to selected customers.
When you create a webhook using POST /webhooks, we generate a secret for that webhook.
We return this value in the response as webhook_secret.
- This field is only returned when the webhook is created.
- You must store it securely.
- You need it later to verify webhook signatures.
- If you lose it, you must create a new webhook.
Each webhook request is signed using HMAC-SHA256, then encoded using Base64 before it is sent.
POST /your-webhook-endpoint HTTP/1.1
Host: example.com
Content-Type: application/json
Signature: bXlfc2lnbmF0dXJl
X-Signable-Webhook: 1710000000To verify a webhook request:
- Read the raw request body exactly as received.
- Generate the signature using your webhook secret:
HMAC_SHA256(your_secret, payload) - Base64 encode the result.
- Compare your generated value with the
Signatureheader. - Reject the request if the values do not match.
The signature is generated using:
- algorithm: HMAC-SHA256
- encoding: base64
- signed content:
<raw_body>The timestamp is included in the payload and in the X-Signable-Webhook header.
Each request includes a timestamp in both the payload and the X-Signable-Webhook header.
To reduce replay risk:
- Check that the timestamp is recent (for example, within 5 minutes).
- Reject requests with timestamps outside your allowed window.
This limits the usefulness of captured requests.
Each webhook subscription has its own secret.
Store the secret securely. Anyone with access to the secret could generate valid signatures for that webhook subscription.
⬅️ Back to Webhook improvements