Rotate a webhook secret
curl --request POST \
--url https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate \
--header 'Authorization: Bearer <token>'import requests
url = "https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyWebhooks
Rotate a webhook secret
Replace a webhook’s signing secret while both old and new secrets verify, so no delivery fails.
POST
/
api
/
v2
/
webhooks
/
{webhook_id}
/
rotate
Rotate a webhook secret
curl --request POST \
--url https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate \
--header 'Authorization: Bearer <token>'import requests
url = "https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://agp.eu.hcompany.ai/api/v2/webhooks/{webhook_id}/rotate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyReplaces the webhook’s signing secret. As with Create, this response is the only time the new
secret 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.
Returns the webhook object plus its new secret.
Path parameters
string
required
The webhook’s
id (UUID).Examples
curl -X POST https://agp.eu.hcompany.ai/api/v2/webhooks/f47ac10b-58cc-4372-a567-0e02b2c3d479/rotate \
-H "Authorization: Bearer $HAI_API_KEY"
from hai_agents import Client
client = Client()
webhook = client.webhooks.rotate_webhook_secret(webhook_id="f47ac10b-58cc-4372-a567-0e02b2c3d479")
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: "f47ac10b-58cc-4372-a567-0e02b2c3d479" });
console.log(webhook.secret); // store it now; it is never returned again
Response
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"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 | Webhook not found or you don’t have access. |
Was this page helpful?