# Replace a Webhook's Secret

A new secret for the webhook of one environment, shown once. It signs every delivery from now on.

## Overview

- The old secret stops at once, for retries too. Deliveries your server refuses until it has the new secret are retried ([Events to Your Server](https://docs.aureahub.com/docs/guide-events.md)), so put it in place within a few minutes.
- `secretHint` and `secretRotatedAt` change with it. The rest of the webhook stays as it is.
- `404` with `details.code` `NOAH_WEBHOOK_NOT_FOUND` when the environment has no webhook.
- For an Aurea administrator, or the tenant's own administrator. Written to the tenant's activity log with the new hint only.

## Endpoint

### `POST /v1/admin/tenants/{id}/webhooks/{environment}/rotate-secret`

Authentication: bearer token required.

Gives the environment's webhook a new secret and returns it once. No body.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Tenant UUID |
| `environment` | string | yes | `production` or `sandbox` |

**Responses**

`200` Replaced

```json
{
  "webhook": {
    "id": "5c03a06e-55f0-425a-8562-bd7bae35825d",
    "environment": "production",
    "url": "https://hooks.example.com/aurea/events",
    "eventTypes": [],
    "status": "active",
    "secretHint": "8vNw",
    "secretRotatedAt": "2026-09-17T11:30:02.202Z",
    "createdAt": "2026-09-17T09:02:11.030Z",
    "updatedAt": "2026-09-17T11:30:02.202Z"
  },
  "secret": "whsec_… (44 characters of base64, ending 8vNw=)"
}
```

`404` No webhook

```json
{
  "statusCode": 404,
  "error": "NotFoundError",
  "message": "This tenant has no webhook in production",
  "details": { "code": "NOAH_WEBHOOK_NOT_FOUND" }
}
```

---

Web version: https://docs.aureahub.com/#tenant-webhook-rotate
