Rotating
webhooks:manage scope. Send no body.
Response 200:
secret is shown once. Store it before doing anything else. The response carries Cache-Control: no-store.
With the SDK: await kash.webhooks.rotateSecret().
60-second cooldown
A second rotation within 60 seconds of a successful one is refused with429 WEBHOOK_SECRET_ROTATION_COOLDOWN, and Retry-After counts down the rest of the cooldown.
The cooldown protects you from a retry storm. If your client timed out on the first rotation and retried, a second rotation would replace the previous-secret slot with a secret you never saw, and lose the secret your endpoint still trusts.
If you lost the response to a rotation, don’t rotate again. Report it from the info button in the Kash web app → Feedback → Report a bug, with the API key’s id.
During the overlap
UntilpreviousRetainedUntil, every delivery’s X-Kash-Signature carries two v1= values, one per secret:
v1= matches (the SDK and every reference implementation do) keeps working whichever secret it holds. After previousRetainedUntil, only the new secret signs.
Recommended rollout
- Rotate and capture the new secret.
- Deploy your endpoint with the new secret. If your verifier accepts any matching
v1=, that is all you need; otherwise configure both secrets and accept either. - Remove the previous secret from your configuration any time before
previousRetainedUntil.
What can go wrong
“I switched my verifier to the new secret straight away.” Fine: deliveries during the overlap carry a signature for each secret, so the new one matches. “I lost the new secret, but my endpoint still has the old one.” Your endpoint keeps verifying untilpreviousRetainedUntil. Don’t simply rotate again: a second rotation makes the lost secret the “previous” one, and the old secret your endpoint holds stops signing at once. Rotate again only when you are ready to deploy the result immediately, or report it from the info button in the Kash web app → Feedback → Report a bug.
“Verification started failing a week after rotating.” The overlap ended and your endpoint still had only the previous secret. Configure the current one. GET /v1/account/usage shows the failures in webhooks["7d"].failed.
There is no endpoint that reads a secret back: after the rotation response, the plaintext exists only in your configuration.
Next
Verifying signatures
Verification that handles both
v1= values.Webhooks overview
Events, envelope and delivery.