---
title: "Rotate the signing secret"
method: POST
path: "/v1/webhooks/{id}/rotate-secret"
tags: ["Webhooks"]
---

# Rotate the signing secret

`POST /v1/webhooks/{id}/rotate-secret`

## Request

- Base URL: `https://api.mails.ai`
- URL: `https://api.mails.ai/v1/webhooks/{id}/rotate-secret`
- Auth: HTTP bearer

**Requires scope:** `manage`. Issues a new signing secret, returned once. For the next 24 hours every delivery's `X-Mails-Signature` carries a `v1` signature from the new secret and one from the previous secret, so a receiver can switch over without failing a delivery. Verify by accepting the header when any `v1` matches. Rotating again within the 24 hours retires the oldest secret. Closed to apps connected by sign-in (403 `connected_app_not_allowed`), and to a key tied to one agent (403): use an API key not tied to an agent, or the mails CLI. If the mails CLI sign-in that rotated it (or made the key that did) is later ended because one of its refresh tokens was used twice, the secret is rotated again and the replaced one stops signing at once.

## Path parameters

- `id` string, required

## Response `200`

The new secret and when the previous one stops signing.

- WebhookSecretRotated
  - `id` string, required: Id of the endpoint whose secret was rotated (`whe_…`): the id in the path.
  - `signing_secret` string, required: The new HMAC signing secret. SHOWN ONCE.
  - `secret_rotated_at` string, date-time, required: When this rotation happened; the endpoint's own `secret_rotated_at` now shows the same time.
  - `previous_secret_expires_at` string, date-time, required: Until this time every delivery carries a signature from the previous secret as well, so receivers can switch over without dropping events.

## Other responses

- `401`: Missing or invalid API key.
- `403`: The API key lacks the required scope (`insufficient_scope`), or the token belongs to an app connected by sign-in and this operation is closed to connected apps (`connected_app_not_allowed`).
- `404`: Resource not found in this workspace, or the agent a send names is archived (`agent_archived`).
- `429`: Rate or quota limit exceeded. The body's `resets_at` and `retry_after_seconds` say when the request can succeed. A `Retry-After` header is sent only when that is 60 seconds or less; a longer wait (an hourly, daily or monthly cap) sends none, so retry at `resets_at` or raise the limit instead of sleeping.
- `500`: Internal server error.

---

[API](https://skmtc.dev/mails/apis/mails-ai-api.md) · [All operations](https://skmtc.dev/mails/apis/mails-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mails/apis/mails-ai-api/revisions/4d4930a8c33b?raw)
