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

# Rotate the signing secret

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

## Request

- Base URL: `https://api.poststack.dev`
- URL: `https://api.poststack.dev/webhooks/{id}/rotate-secret`
- Auth: one of:
  - HTTP bearer
  - OAuth 2
    - Authorization code: `https://poststack.dev/oauth/authorize`
    - Token URL: `https://poststack.dev/oauth/token`
- TypeScript: <https://skmtc.dev/poststack/apis/poststack-api/docs/webhooks/:id/rotate-secret/post.ts> (a function with typed inputs; its response is checked against the schema)

During the grace window (default 24 h, max 168, `0` = immediate) deliveries are signed with both secrets.

## Path parameters

- `id` integer, required

## Request body

- RotateWebhookSecretInput
  - `graceHours` integer

## Response `200`

Rotated. The new `signingSecret` is shown only here.

- WebhookWithSecret
  - `webhook` Webhook, required
    - `id` integer, required
    - `url` string, required
    - `events` string[], required
    - `signingSecret` string: Masked. The full secret is returned only by create and rotate-secret.
    - `active` boolean, required
    - `consecutiveFailures` integer
    - `disabledAt` string, date-time, nullable
    - `disabledReason` string, nullable
    - `secretRotatedAt` string, date-time, nullable
    - `previousSecretExpiresAt` string, date-time, nullable: End of the rotation grace window, if one is open.
    - `lastDeliveryAt` string, date-time, nullable: List only.
    - `lastDeliveryStatus` integer, nullable: List only: HTTP status of the latest delivery.
    - `createdAt` string, date-time
    - `updatedAt` string, date-time
  - `signingSecret` string, required: Plaintext signing secret — shown once. Verify `X-PostStack-Signature` with it.

## Other responses

- `400`: Validation failed or `graceHours` out of range.
- `401`: Missing, malformed or unknown credentials (`WWW-Authenticate: Bearer …` is set).
- `403`: The credential lacks the `webhooks:manage` scope (body `{ error: "insufficient_scope", required, missing }`), or the team is suspended.
- `404`: No such resource on this team.
- `429`: Rate limited (10/min). `Retry-After` gives the seconds to wait; `X-RateLimit-*` headers are sent on every response.

## Changes

- **2026-09-30** `4dc1e20989c8`: 15 warning
  - added the new `daily_limit_exceeded` enum value to the `anyOf[#/components/schemas/Error]/code` response property for the response status `403`
  - added the new `daily_limit_exceeded` enum value to the `code` response property for the response status `400`
  - added the new `daily_limit_exceeded` enum value to the `code` response property for the response status `401`
  - added the new `daily_limit_exceeded` enum value to the `code` response property for the response status `404`
  - …11 more
- **2026-09-29** `ef5b22b98333`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/poststack/apis/poststack-api/changes/webhooks/:id/rotate-secret/post.md)

---

[API](https://skmtc.dev/poststack/apis/poststack-api.md) - [All operations](https://skmtc.dev/poststack/apis/poststack-api/llms.txt) - [OpenAPI document](https://skmtc.dev/poststack/apis/poststack-api/revisions/0d3971e3a670?raw)
