Overview
The signing secret lets the receiving system check that a request came from Appical and was not changed on the way. It is optional, but recommended for every Webhook, since all events carry personal data.
Setting the secret
Appical does not generate the secret. You create one, enter it in the Signing Secret field, and give the same value to whoever builds the receiving side.
Use a long random value, for example 32 or more characters from a password generator. The secret is used exactly as typed, including any spaces.
After saving, the secret is never shown again, also not to admins. Store it safely, for example in a password manager, before clicking Create.
Changing or removing the secret
Open the Webhook with the pencil icon. A saved secret shows as dots, with two buttons:
Replace: enter the new value under New signing secret and click Update.
Remove: click Remove, then Update. Requests are then sent without a signature.
📌 Important:
A change applies to every request sent after saving, including replays of older deliveries.
Update the receiving system at the same moment, or its checks will fail.
To change the secret without rejected requests, let the receiver accept both the old and the new secret for a short while.
What Appical sends
Every request has a webhook-id and a webhook-timestamp header. With a secret set, it also has webhook-signature: the text v1, followed by a Base64-encoded HMAC-SHA256 signature. Test events and replays are signed too. A replay gets a new timestamp and a new signature, so it passes the receiver's time check.
Verifying a request
The signature follows the Standard Webhooks spec. The receiver:
Takes the raw request body exactly as received, before parsing or re-formatting the JSON.
Builds the text ...
Computes an HMAC-SHA256 of that text, with the secret as typed in Appical as the key.
Base64-encodes the result and compares it with the part after v1, in webhook-signature, using a constant-time comparison.
Rejects the request if webhook-timestamp is more than 5 minutes away from its own clock.
📌 Important:
The official Standard Webhooks libraries, available for most languages, do these steps for you.
They expect the secret as whsec_ followed by the Base64 encoding of the secret, not the secret as typed.
For a secret mysecret, pass whsec_bXlzZWNyZXQ=. Passing the plain secret makes every check fail.
→ Example values to test a check against
secret: mysecret
webhook-id: evt-example
webhook-timestamp: 1780306200
body: {"event":"user.created","delivered_at":"2026-06-01T09:30:00Z","application_id":123,"data":{"user_id":42}}
webhook-signature: v1,L3bBkX/a0IVLkzn8uMVxBXQU4K7RxrIRKBbaMmxkOkE=👉 Let us know if this article answered your question by using the buttons below. If not, get in touch with our Support Channel for more information:
