# List webhook secrets

> Read owner-scoped metadata for your managed webhook signing secrets — never the secret value itself.

`GET /v1/webhooks/secrets` returns owner-scoped, **read-only** metadata for your managed webhook signing secrets (`whsec_…`). It lists which secrets exist and their status — it **never** returns the secret value.

<Note>
  Managed signing secrets are **created and rotated in the
  [dashboard](https://aisearchapi.dev/home)**, not through the API — the API
  treats them as read-only. Use this endpoint to check which secret is active
  before you rely on it to verify a [webhook](/guides/webhooks).
</Note>

## Request

<CodeGroup>

```bash cURL
curl https://api.aisearchapi.dev/v1/webhooks/secrets \
  -H "Authorization: Bearer $AISEARCH_API_KEY"
```

```javascript Node
const res = await fetch('https://api.aisearchapi.dev/v1/webhooks/secrets', {
  headers: { Authorization: `Bearer ${process.env.AISEARCH_API_KEY}` },
});
const { secrets } = await res.json();
```

```python Python
import os, requests

res = requests.get(
    "https://api.aisearchapi.dev/v1/webhooks/secrets",
    headers={"Authorization": f"Bearer {os.environ['AISEARCH_API_KEY']}"},
)
secrets = res.json()["secrets"]
```

</CodeGroup>

## Response

```json 200 OK
{
  "secrets": [
    {
      "id": "whsec_1a2b3c",
      "status": "active",
      "createdAt": "2026-06-20T09:00:00Z",
      "expiresAt": null
    },
    {
      "id": "whsec_9z8y7x",
      "status": "retiring",
      "createdAt": "2026-05-01T09:00:00Z",
      "expiresAt": "2026-07-01T09:00:00Z"
    }
  ]
}
```

<ResponseField name="secrets" type="object[]">
  Your managed signing secrets, metadata only.

  <Expandable title="secret">
    <ResponseField name="id" type="string">
      The secret's identifier (`whsec_…`) — not the signing value.
    </ResponseField>
    <ResponseField name="status" type="string">
      `active` (currently signing new deliveries) or `retiring` (still valid for
      verification during an overlap window, being phased out).
    </ResponseField>
    <ResponseField name="createdAt" type="string">
      ISO-8601 creation timestamp.
    </ResponseField>
    <ResponseField name="expiresAt" type="string | null">
      When a retiring secret stops being accepted; `null` for an active secret
      with no scheduled expiry.
    </ResponseField>
  </Expandable>
</ResponseField>

<Tip>
  During a rotation both an `active` and a `retiring` secret can be valid at
  once, so verify incoming deliveries against **every** non-expired secret until
  the old one's `expiresAt` passes. See [Webhooks](/guides/webhooks) for the
  signature-verification flow.
</Tip>

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Register a webhook and verify its HMAC-SHA256 signature.
  </Card>
  <Card title="The Envelope" icon="box" href="/guides/output-formats">
    The result shape delivered to your webhook.
  </Card>
</CardGroup>
