Rotate a webhook secret
Makes a new signing secret and returns it, shown only here. For 24 hours the old secret signs too, as a second signature in webhook-signature, so you can deploy the new one without dropping events. Rotating again within those 24 hours drops the oldest.
Needs an API key with the generations:write scope.
curl --request POST \
--url https://api.tryleap.ai/v1/webhook_endpoints/{id}/rotate_secret \
--header 'x-api-key: <api-key>'const options = {method: 'POST', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.tryleap.ai/v1/webhook_endpoints/{id}/rotate_secret', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.tryleap.ai/v1/webhook_endpoints/{id}/rotate_secret"
headers = {"x-api-key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text){
"id": "we_5Tq8Lm2Xv9Kr4Wn7Bc1Yd3Hp",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/leap",
"description": "Production renders",
"events": [
"generation.succeeded",
"generation.failed"
],
"disabled": false,
"disabled_reason": null,
"created_at": "2026-10-04T18:20:03.441Z",
"updated_at": "2026-10-04T18:20:03.441Z",
"secret": "whsec_foO4NH7H4fkZ/TBkV6oqbUTlZgWKMsflfyzrjNDfrQs="
}{
"error": {
"type": "invalid_request_error",
"code": "conflicting_credentials",
"message": "Send one API key.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "authentication_error",
"code": "authentication_required",
"message": "Authentication is required.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "permission_error",
"code": "permission_denied",
"message": "Permission denied.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "That webhook endpoint does not exist.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Too Many Requests",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}Authorizations
Your workspace API key, leap_.... Create one at https://app.tryleap.ai/go/api, and keep it on your server.
Path Parameters
The endpoint's ID, we_....
Response
The endpoint, with its new signing secret.
An endpoint with its signing secret, as create and rotate_secret return it.
The endpoint's ID, we_....
"webhook_endpoint"Where Leap POSTs events.
Your note, if any.
The event types it gets; ["*"] for every type, including types added later.
Whether deliveries to it are stopped.
Why Leap disabled the endpoint, such as every delivery failing for 72 hours; null when it is on or you turned it off.
When it was created.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$When it last changed.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$The signing secret, whsec_ and base64. Shown only here: keep it in your server's environment.
curl --request POST \
--url https://api.tryleap.ai/v1/webhook_endpoints/{id}/rotate_secret \
--header 'x-api-key: <api-key>'const options = {method: 'POST', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.tryleap.ai/v1/webhook_endpoints/{id}/rotate_secret', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.tryleap.ai/v1/webhook_endpoints/{id}/rotate_secret"
headers = {"x-api-key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text){
"id": "we_5Tq8Lm2Xv9Kr4Wn7Bc1Yd3Hp",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/leap",
"description": "Production renders",
"events": [
"generation.succeeded",
"generation.failed"
],
"disabled": false,
"disabled_reason": null,
"created_at": "2026-10-04T18:20:03.441Z",
"updated_at": "2026-10-04T18:20:03.441Z",
"secret": "whsec_foO4NH7H4fkZ/TBkV6oqbUTlZgWKMsflfyzrjNDfrQs="
}{
"error": {
"type": "invalid_request_error",
"code": "conflicting_credentials",
"message": "Send one API key.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "authentication_error",
"code": "authentication_required",
"message": "Authentication is required.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "permission_error",
"code": "permission_denied",
"message": "Permission denied.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "That webhook endpoint does not exist.",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Too Many Requests",
"param": null,
"doc_url": null,
"request_id": "req_8kQ2vX9mR4tL6nB1cW3yZ5aD"
}
}