WhatsApp Gateway
API referenceWebhooks

Update a webhook

Update the webhook identified by `id` — its `url`, `events`, `sessionId` scope, `secret`, `customHeaders`, `retryPolicy`, or `active` flag. Requires the `manage` capability, and the webhook must belong to the caller's organization. **Secret rotation.** Send a new `secret` to rotate it; omit the field to leave the stored secret unchanged. As elsewhere, the secret is never returned. On success returns `200` with the updated webhook. Errors: `404 not_found` if no webhook with that id is owned by the caller's organization; `422 validation_error` if the supplied fields are invalid (e.g. a malformed `url`); `403 forbidden` if the caller lacks the `manage` capability.

PATCH
/api/v1/webhooks/{id}

Authorization

AuthorizationBearer <token>

Send Authorization: Bearer <token>. The router accepts two kinds of token and tries each in turn: a frontend-minted login JWT (verified against the frontend JWKS; the person's org + role are read from it), or an api-key for a script/service (carrying a fixed set of gateway permissions). The bearerFormat: JWT label describes the person-login case.

In: header

Path Parameters

id*string

The webhook id to update. Must reference a webhook owned by the caller's organization, otherwise the request fails with a 404 "not_found".

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

active?boolean

Whether the webhook is enabled. An inactive (false) webhook is kept but receives no deliveries. Defaults to enabled when omitted on create.

customHeaders?

Extra HTTP headers attached to every delivery POST. Applied last, so they can override the gateway's default headers. Use for static auth tokens or routing hints the receiver requires.

events?array<string>|

Event types to deliver to this webhook. Use ["*"] to receive every event type; an explicit list (e.g. ["message.received", "session.connected"]) delivers only those types; an empty list delivers nothing. See the event catalog for the full set of type names.

retryPolicy?

How failed deliveries (non-2xx response or connection error) are retried. Omit to use the gateway default: exponential backoff with a 2s base delay (2s, 4s, 8s, …) for up to 15 attempts, after which the delivery is given up (dead-lettered).

secret?string

Plaintext HMAC signing secret. When set, the gateway signs each delivery: it sends the lowercase-hex HMAC-SHA512 of the exact raw request body in the X-Webhook-Hmac header (alongside X-Webhook-Hmac-Algorithm: sha512), so the receiver can recompute it with the same secret and confirm authenticity. Stored encrypted at rest and never returned in any response. On update: send a new value to rotate the secret; omit the field to leave the stored secret unchanged.

sessionId?string

Scope this webhook to a single session: only events produced by that session are delivered. Omit or set to null to receive events from all of the caller organization's sessions. Must reference a session owned by the caller's organization.

url?string

The HTTPS endpoint that receives the delivery POSTs. Required on create (validated server-side; a missing or malformed value yields a 422 "validation_error"). The gateway POSTs the event envelope (the same JSON shape pushed over the realtime WebSocket) to this URL as the request body.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/api/v1/webhooks/01HHX5WEBHOOK..." \  -H "Content-Type: application/json" \  -d '{}'
{  "active": true,  "createdAt": 1719662400000,  "customHeaders": {    "X-Tenant": "acme"  },  "events": [    "message",    "poll.vote"  ],  "id": "wh_01J9...",  "organizationId": "org_01J9ABC...",  "retryPolicy": {    "attempts": 15,    "delaySeconds": 2,    "policy": "exponential"  },  "sessionId": "01J9ZX8K2QHV0M3T6R7P4N5W8C",  "updatedAt": 1719662400000,  "url": "https://example.com/webhooks/wa"}
{  "error": {    "code": "not_found",    "details": {      "property1": null,      "property2": null    },    "message": "session not found"  }}