Rotate a webhook subscription's signing secret
/portal/v1/accounts/{accountSlug}/webhooks/{id}/rotate-secretGenerates a new signing secret for one webhook subscription id. The new secret is returned only in this response and is never retrievable again. The replaced secret keeps verifying for 24 hours: during that window every delivery's X-Canopy-Signature carries two space-separated v1, values, the new secret's first, and previous_secret_expires_at says when the window closes. A rotation inside an open window replaces the windowed secret rather than keeping a third. Send expire_previous: "now" for a leaked secret to skip the window; previous_secret_expires_at is then null. Returns 404 for an unknown subscription, writes a webhook.secret_rotated audit row, and requires webhook.manage.
Authentication
AuthorizationJWT access token. Never send alongside X-API-Key: a request carrying both is refused.
account_webhooks.manageAccountManage account-tier webhook subscriptions. Granted through an administrator role in the Admin Workspace; a valid token without it is refused with 403.
Path Parameters
accountSlugstring Required The Account's slug. An unknown one answers 404.
idstring Required Request body
application/json
expire_previousenum Optional `window` (the default) keeps the retired secret verifying for 24 hours so the receiver can roll the new value out. `now` stops it the moment the rotation lands, for a secret that has leaked.
Responses
application/json
data *WebhookSecretRotatedResponseDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
Errors
When the request can't be completed, the response body includes a stable error code you can branch on, and a correlation_id (also sent as the X-Correlation-Id header). Quote the correlation id when you contact support: it identifies the exact request in Canopy's logs.
account.capability_requiredForbiddenThe signed-in user's administrator roles do not grant the capability this endpoint requires.
Ask an account administrator to grant a role carrying the capability named in the Authentication section, then retry.
Returned object
curl -X POST "https://auth.canopy-io.com/portal/v1/accounts/value/webhooks/value/rotate-secret" \ -H "Authorization: Bearer $CANOPY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "expire_previous": "now" }'
{ "data": { "id": "string", "url": "string", "secret": "string", "previous_secret_expires_at": "2026-04-20T12:00:00.000Z" } }
Tell us how we can improve this guide.