Webhooks
Rotate a webhook secret
Rotate a webhook’s signing secret, effective at once.
POST
/
api
/
v2
/
webhooks
/
{webhook_id}
/
rotate
from hai_agents import Client
client = Client()
webhook = client.webhooks.rotate_webhook_secret(webhook_id=webhook_id)
print(webhook.secret) # store it now; it is never returned again
import { HaiAgentsClient } from "hai-agents";
const client = new HaiAgentsClient();
const webhook = await client.webhooks.rotateWebhookSecret({ webhookId });
console.log(webhook.secret); // store it now; it is never returned again
curl -X POST https://agp.eu.hcompany.ai/api/v2/webhooks/$WEBHOOK_ID/rotate \
-H "Authorization: Bearer $HAI_API_KEY"
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"url": "https://example.com/hooks/h",
"enabled_events": ["*"],
"description": "Production listener",
"disabled": false,
"last_delivery_status": "succeeded",
"last_delivery_error": null,
"last_delivery_at": "2026-07-02T08:30:00Z",
"last_success_at": "2026-07-02T08:30:00Z",
"consecutive_failures": 0,
"created_at": "2026-06-11T15:04:05Z",
"updated_at": "2026-07-02T09:00:00Z",
"secret": "whsec_nZbY0eXaMpLeOnLyDoNotUse0aQ3rT5uV7wX9yZ1aB3c"
}
Behavior
As with Create, this response is the only time the newsecret is returned. Deliveries are signed at send time, so events (including retries already in flight) are signed with the new secret from this point on.
As soon as you have the new secret, make your receiver accept both: verify_webhook(body, sig, ts, ["whsec_old", "whsec_new"]). Deliveries rejected in between are retried. Remove the old secret once deliveries verify against the new one.
Path parameters
string
required
The webhook’s
id (UUID).Response
200 with the webhook object plus its new secret.
from hai_agents import Client
client = Client()
webhook = client.webhooks.rotate_webhook_secret(webhook_id=webhook_id)
print(webhook.secret) # store it now; it is never returned again
import { HaiAgentsClient } from "hai-agents";
const client = new HaiAgentsClient();
const webhook = await client.webhooks.rotateWebhookSecret({ webhookId });
console.log(webhook.secret); // store it now; it is never returned again
curl -X POST https://agp.eu.hcompany.ai/api/v2/webhooks/$WEBHOOK_ID/rotate \
-H "Authorization: Bearer $HAI_API_KEY"
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"url": "https://example.com/hooks/h",
"enabled_events": ["*"],
"description": "Production listener",
"disabled": false,
"last_delivery_status": "succeeded",
"last_delivery_error": null,
"last_delivery_at": "2026-07-02T08:30:00Z",
"last_success_at": "2026-07-02T08:30:00Z",
"consecutive_failures": 0,
"created_at": "2026-06-11T15:04:05Z",
"updated_at": "2026-07-02T09:00:00Z",
"secret": "whsec_nZbY0eXaMpLeOnLyDoNotUse0aQ3rT5uV7wX9yZ1aB3c"
}
Errors
| Status | Cause |
|---|---|
404 | Not found, or not in your organization. |
Was this page helpful?
⌘I
from hai_agents import Client
client = Client()
webhook = client.webhooks.rotate_webhook_secret(webhook_id=webhook_id)
print(webhook.secret) # store it now; it is never returned again
import { HaiAgentsClient } from "hai-agents";
const client = new HaiAgentsClient();
const webhook = await client.webhooks.rotateWebhookSecret({ webhookId });
console.log(webhook.secret); // store it now; it is never returned again
curl -X POST https://agp.eu.hcompany.ai/api/v2/webhooks/$WEBHOOK_ID/rotate \
-H "Authorization: Bearer $HAI_API_KEY"
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"url": "https://example.com/hooks/h",
"enabled_events": ["*"],
"description": "Production listener",
"disabled": false,
"last_delivery_status": "succeeded",
"last_delivery_error": null,
"last_delivery_at": "2026-07-02T08:30:00Z",
"last_success_at": "2026-07-02T08:30:00Z",
"consecutive_failures": 0,
"created_at": "2026-06-11T15:04:05Z",
"updated_at": "2026-07-02T09:00:00Z",
"secret": "whsec_nZbY0eXaMpLeOnLyDoNotUse0aQ3rT5uV7wX9yZ1aB3c"
}