TheDocumentation Index
Fetch the complete documentation index at: https://docs.kash.bot/llms.txt
Use this file to discover all available pages before exploring further.
webhook_secret is what your endpoint uses to verify incoming webhook signatures. Rotate it on the same triggers as any sensitive credential: a team change, a leaked log line, or just routine hygiene.
The rotation flow has a built-in 7-day overlap window so deliveries in flight are never dropped. Both the previous and new secret are valid during the window — your verifier just needs to accept either.
Rotating
200 OK):
secret plaintext is shown once — capture it and roll it out to your endpoint.
Required scope: webhooks:manage. The key must already have a webhook URL + secret configured at issuance time — rotation only swaps the secret on a configured webhook, it does not provision one.
Rotation cooldown (60 seconds)
Calling rotate again within 60 seconds of a successful rotation returns429 WEBHOOK_SECRET_ROTATION_COOLDOWN with a Retry-After header counting down to the cooldown’s expiry.
What happens during the 7-day window
Whilenow < previousRetainedUntil:
- The webhook delivery worker dual-signs every delivery. The
X-Kash-Signatureheader carries TWOv1=entries — one with the new secret, one with the old. - Your verifier should accept signatures matching either secret. Both reference implementations and the SDK already do this.
previousRetainedUntil, dual-signing stops and only the new secret is used.
Recommended rollout
- Rotate the secret.
POST /v1/auth/api-keys/me/webhook-secret/rotate. Capture the new plaintext. - Update your endpoint to know about both secrets. Most setups use a
KASH_WEBHOOK_SECRETenv var — addKASH_WEBHOOK_SECRET_PREVIOUSand have your verifier try the new one first, then the previous. Or use a verifier (like the SDK’sconstructEvent) that already accepts multiplev1=entries. - Deploy. Your endpoint now accepts signatures under either secret.
- Wait for in-flight deliveries to drain. Conservatively, a few minutes. The 7-day window gives you generous headroom.
- (After 7 days, optional) Remove
KASH_WEBHOOK_SECRET_PREVIOUSfrom your config. AfterpreviousRetainedUntil, the old secret no longer signs anything; carrying it in your verifier just adds dead code.
v1= parsing is already in there.
What can go wrong
”I rotated and immediately replaced the secret in my verifier”
If your verifier only knows the new secret, deliveries signed during the rotation overlap (with both new and old signatures) still verify because at least onev1= entry matches. You’re fine — but if you’d swapped to the OLD secret only, you’d lose deliveries.
The safe rule: during overlap, accept either secret. Never accept only the old one after rotation.
”I lost the new secret”
Two cases:- You captured the previous response and just didn’t store the new secret. Rotate again. Each rotate creates a fresh secret and re-starts the 7-day window. Your previously-captured new-secret becomes the rotation’s “previous” — both still valid during the new window. Wait at least 60s between rotations to avoid the cooldown gate.
- The previous rotation response was lost (network timeout, dropped response). Do NOT just retry rotate yourself — that would silently overwrite the rollback slot with a secret no one ever held. Contact [email protected]; operations can either roll back to the prior known-good secret (preserving your verifier) or perform an operator-path rotation that captures the new secret onto a support channel rather than into the void.
”Rotation broke my verifier and I need to roll back”
Within 7 days of a rotation, operations can roll back to the prior secret via thekash-admin api-keys rollback-webhook-secret operator command. This atomically swaps webhook_secret_previous back into webhook_secret, so your endpoint immediately starts receiving deliveries signed with the secret your verifier knows.
To trigger a rollback, email [email protected] with:
- The API key id (UUID — visible in the webapp Settings → API Keys page)
- A short description of what broke (so the operator captures it in the audit row)
- Confirmation that the prior secret you remember is still configured on your endpoint
”My endpoint started rejecting signatures after the window expired”
Check that you’re verifying with the current secret and that you didn’t accidentally remove thev1= parsing. After previousRetainedUntil, the old secret stops signing; if your verifier was relying on the old secret being valid, it’ll start failing.
GET /v1/account/usage will surface the failure rate via webhooks.7d.failed going up.
Inspecting current state
There’s no API to read the secret back — once issued, the plaintext lives only in your config. To check rotation timestamps, the webapp’s Settings → API Keys → [key] → Webhook page showsrotatedAt and previousRetainedUntil.
URL changes
If you changewebhook_url (different domain or path), the API does a one-time validation to confirm the new URL responds 2xx to a probe before queuing real deliveries. To prevent abuse, URL changes also have a 1-hour cooldown between consecutive changes.
The API will warn you if the old URL has unprocessed deliveries pending; redirect them with manual redelivery once the new URL is live.
Going dark
If you want to temporarily pause webhook delivery without changing your URL or rotating the secret, the cleanest path is to revoke and re-issue the key (no deliveries are queued for a key with nowebhook_url). For short pauses, just respond 429 with a long Retry-After from your endpoint — the breaker opens and we back off.
Next
Verifying Signatures
The verification recipe that handles the dual-
v1= overlap window.Webhooks Overview
Back to the webhooks overview.