Rotate the webhook signing secret
Sample request
curl -X POST -H "x-api-key: $ABYSSALE_API_KEY" \
https://api.abyssale.com/signing-secret/rotateimport abyssale from '@abyssale/sdk';
const { data, error } = await abyssale.rotateSigningSecret();
if (error) console.error(error.id, error.message);
else console.log(data);from abyssale import Abyssale
with Abyssale() as client:
result = client.rotate_signing_secret()
print(result)Example 200 response
{
"secret": "whsec_2f1a8c4e6b9d0a7c3e5f8b1d4a6c9e2f0b3d5a7c1e4f6b8d0a2c5e7f9b1d3a5c",
"created_at_ts": 1755561234
}Example 401 error response
{
"message": "Unauthorized: missing or invalid API key.",
"id": "unauthorized"
}Issue a new signing secret and keep the previous one valid for 24 hours.
Behaviour, limits and caveats
During that window every delivery carries two v1 hashes — one per secret — so a receiver holding either value still verifies. That is what lets you deploy the new secret on your own schedule instead of coordinating a cutover.
Keep accepting the old secret for a few minutes after you switch: retries already in flight were signed before you deployed.
Takes no request body. If the workspace has no secret yet, one is created and immediately rotated, so the response always carries a usable value.
Calling this twice in a row is refused. A second rotate while the previous secret is still inside its 24-hour window would demote the secret the first rotate minted and drop the one your receiver is still verifying with — the outage the window exists to prevent. You get 409 previous_secret_still_active, and nothing changes. Either wait for the window to close (previous_secret_expires_at_ts from the first response tells you when), call POST /signing-secret/revoke to end the overlap now and rotate immediately after, or repeat the call with ?force=true if you really do mean to rotate twice and accept that anything signed with the oldest secret stops verifying.
Query parameters
force boolean
Rotate even though the previous secret is still valid, revoking it. Only needed to override the 409 above; a first rotate never needs it. Defaults to false.
Response 200
The new secret. The previous one stays valid for 24 hours.
secret string always
The secret to verify X-Abyssale-Signature with. Prefixed whsec_ so it is recognisable if it turns up somewhere it should not.
created_at_ts integer always
Unix second the secret was first issued.
rotated_at_ts integer | null
Unix second of the most recent rotation, or null if the secret has never been rotated.
previous_secret_expires_at_ts integer | null
When the previous secret stops being honoured — 24 hours after the rotation that demoted it.
More about previous_secret_expires_at_ts
When the previous secret stops being honoured — 24 hours after the rotation that demoted it. null when there is no overlap in progress, either because nothing was rotated, because the window has lapsed, or because it was ended with POST /signing-secret/revoke.
While this is set, deliveries carry two v1 hashes and a receiver holding either secret verifies. The previous secret's value is never returned — only its expiry.
Errors
Every failure uses the shared error envelope — {id, message, errors?}. Branch on id, never on message. See Errors.
| Status | When |
|---|---|
401 | Unauthorized — missing or invalid API key. |
409 | Conflict — the previous secret is still within its grace window, so rotating would revoke it. Nothing changed. Retry with ?force=true to rotate anyway. |
429 | Too Many Requests. |
500 | Internal Server Error — an unexpected error occurred on our side. |
