Update a webhook
const url = 'https://api.retorio.com/be/v2/organization_webhooks/9d4e2b71_3c8a_4f05_b6e2_1a7c5d9e0f38';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"name":"CRM sync","url":"https://hooks.customer.example/retorio","subscribedEvents":["coaching.result.available"],"customHeaders":[{"name":"Authorization","value":"Bearer <your endpoint token>"}],"rotateSigningSecret":false,"isEnabled":true,"expectedLastChangedAt":"2026-04-15T12:00:00Z"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.retorio.com/be/v2/organization_webhooks/9d4e2b71_3c8a_4f05_b6e2_1a7c5d9e0f38 \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "CRM sync", "url": "https://hooks.customer.example/retorio", "subscribedEvents": [ "coaching.result.available" ], "customHeaders": [ { "name": "Authorization", "value": "Bearer <your endpoint token>" } ], "rotateSigningSecret": false, "isEnabled": true, "expectedLastChangedAt": "2026-04-15T12:00:00Z" }'Updates a webhook by appending a new configuration version. The full configuration is restated on every update, not patched: customHeaders omitted keeps the stored set (credential included), [] removes every custom header, and an array that is sent is the whole set going forward. Inside a sent array, an entry with a name and no value keeps the value stored under that name, so you can keep a credential you cannot read back. An entry with no value whose name is not stored is a 400. Pass expectedLastChangedAt (the lastChangedAt you last read) to get a 409 instead of overwriting an edit made since you read it. A 409 can also answer an update that collides with a concurrent one. rotateSigningSecret: true replaces the signing secret and returns the new one once. Every receiver verifying with the old one then fails until updated.
Authentication
Section titled “Authentication”- Auth
- Access key
- Roles
- Owner / Custom
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Example
9d4e2b71_3c8a_4f05_b6e2_1a7c5d9e0f38Request Bodyrequired
Section titled “Request Bodyrequired”object
Shown in the webhook list. Must contain at least one letter, digit, punctuation mark or symbol.
Example
CRM syncYour endpoint. It must use https, be at most 2048 characters and carry no credentials (no user name or password).
Example
https://hooks.customer.example/retorioAt most 10 headers, sent with every delivery. Together they may take at most 8192 bytes, counting each as <name>: <value>\r\n, stored values included.
object
A valid HTTP header name, unique within the set regardless of case. Names starting with X-Retorio- and these are reserved: connection, content-encoding, content-length, content-type, expect, host, keep-alive, proxy-authenticate, proxy-authorization, te, trailer, transfer-encoding, upgrade, user-agent.
Example
AuthorizationThe header value, sent exactly as given. At most 4096 characters of printable ASCII or tab, with no line breaks. Leave it out on an update to keep the value stored under this name, so a credential you cannot read back is kept. Leaving it out for a name that is not stored, or on create, is a 400.
Example
Bearer <your endpoint token>Responses
Section titled “Responses”OK
object
True when the stored custom headers cannot be decrypted, in which case customHeaderNames is empty. While it is true, every delivery to this webhook, the test event included, fails and is not retried. Repair it with an update that sends every header with its value, or customHeaders: []. An entry without a value cannot be kept from an unreadable set, and the update answers 400.
The secret that signs every delivery, returned only by create and by an update with rotateSigningSecret: true. The HMAC key is the full signingSecret string exactly as returned, whsec_ prefix included, taken as UTF-8 bytes. Do not strip the prefix or base64-decode it.
Example
{ "subscribedEvents": [ "coaching.result.available" ]}The configuration is not valid (see the request fields), a custom header entry without a value names no stored header or the stored headers cannot be read, the custom headers exceed 8192 bytes once merged, your organization already has 5 webhooks (create only), or this environment cannot store webhook credentials. Also answered when the request body is not valid JSON.
object
Canonical error name, e.g. INVALID_ARGUMENT.
object
The HTTP reason phrase, e.g. Bad Request.
Example generated
{ "message": "example", "status": "example", "details": "example"}Not authenticated: the bearer token is missing, malformed, expired or revoked, its sign-in method does not match your organization’s configuration, the user it belongs to was removed, or your organization is deactivated.
object
Canonical error name, e.g. INVALID_ARGUMENT.
Example generated
{ "message": "example", "status": "example", "details": "example"}Refused: the token does not belong to an admin, or the admin’s roles do not grant webhooks:manage.
object
Canonical error name, e.g. INVALID_ARGUMENT.
object
The HTTP reason phrase, e.g. Bad Request.
Example generated
{ "message": "example", "status": "example", "details": "example"}No webhook with this extId in your organization.
object
Canonical error name, e.g. INVALID_ARGUMENT.
Example generated
{ "message": "example", "status": "example", "details": "example"}The webhook was edited by someone else since expectedLastChangedAt, or by a concurrent update that committed first. Reload it and retry.
object
The HTTP reason phrase, e.g. Bad Request.
Example generated
{ "statusCode": 1, "message": "example", "error": "example"}The request body is larger than 10 MB.
object
The HTTP reason phrase, e.g. Bad Request.
Example generated
{ "statusCode": 1, "message": "example", "error": "example"}The Content-Type charset or the Content-Encoding is one the API cannot decode. Send UTF-8 JSON without a content encoding.
object
The HTTP reason phrase, e.g. Bad Request.
Example generated
{ "statusCode": 1, "message": "example", "error": "example"}Internal Server Error
object
Example generated
{ "additionalProperty": "example"}Retorio is GDPR and DSGVO compliant, EU AI Act aligned, ISO 27001 certified, and hosted on Google Cloud with EU data residency. For anything specific to your rollout, ask your Retorio contact.