List webhooks
List the webhook endpoints configured for the caller's organization. Requires the `manage` capability. The response is scoped to the caller's organization — webhooks owned by other organizations are never returned, and secrets are never included. This endpoint returns the full set in one page (the response carries an empty `nextCursor`); no pagination parameters are accepted. Errors: `403 forbidden` if the caller lacks the `manage` capability.
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
Response Body
application/json
application/json
curl -X GET "https://example.com/api/v1/webhooks"{ "data": [ { "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" } ], "nextCursor": "string"}{ "error": { "code": "not_found", "details": { "property1": null, "property2": null }, "message": "session not found" }}Vote on a poll message POST
Casts a vote on the poll message identified by `mid` (located by `chat`/`sender` in the body). `options` is the **complete** set of poll choices you want selected — it **replaces** your previous vote rather than adding to it. Send an empty array to clear your vote; for a single-choice poll send exactly one option. Returns **200** with a `SendResult`. ### Preconditions & errors - Requires the **`send`** capability. - **400 `validation_error`** — the target is not a poll or an option does not match the poll's choices. - **404 `not_found`** — the session or poll message does not exist or is not owned by your organization.
Create a webhook POST
Register a webhook endpoint for the caller's organization. Requires the `manage` capability. When a matching event fires, the gateway sends an HTTP `POST` to `url` whose body is the event envelope — the same JSON shape delivered over the realtime WebSocket. Use `events` to choose the event types to receive (`["*"]` for all) and `sessionId` to scope deliveries to one session (null/omitted = all of the organization's sessions). **Signing.** If you set a `secret`, every `POST` is signed: the gateway sends the lowercase-hex HMAC-SHA512 of the exact raw request body in the `X-Webhook-Hmac` header (with `X-Webhook-Hmac-Algorithm: sha512`). Recompute it on your end with the same secret to confirm the request really came from the gateway. The secret is stored encrypted and is never returned in any response. **Delivery headers.** Every `POST` also carries `X-Webhook-Request-Id` (the event id — use it to drop duplicate redeliveries) and `X-Webhook-Timestamp` (epoch milliseconds). Any `customHeaders` are applied last and can override the defaults. **Retries.** A delivery that returns non-2xx or fails to connect is retried on the `retryPolicy` schedule — by default exponential backoff (2s, 4s, 8s, …) for up to 15 attempts, after which it is given up (dead-lettered). On success returns `201` with the created webhook. Errors: `422 validation_error` if the body is malformed (e.g. `url` missing or not a valid URL); `403 forbidden` if the caller lacks the `manage` capability.