Webhooks
Create a webhook endpoint
Register a destination. An endpoint created here is identical to one created in **Connectors → Webhooks**, including flipping the connector card to connected.
**Credential:** user token · **Role:** owner or admin (`manage_team`)
<Warning>**`events` is required.** Omitting it is a `400` naming the field — not a subscription to everything. Pass `["*"]` if you genuinely want every event, including ones added later.
`handoff.*` payloads carry real customer message text, so subscribing a new URL to them because a field was left blank is not a convenience.</Warning>
`channels` **is** optional and defaults to every channel, precisely because a channel filter can only ever narrow an event selection. The four `billing.*` events have no channel, so a channel filter never hides them.
<Warning>**The signing secret is returned by this response only** (and by [rotate-secret](/api/v1/webhooks/rotate-a-signing-secret)). It is never on a list, a GET or a PATCH, and there is no way to recover it later — store it now.</Warning>
POST
Create a webhook endpoint
Authorizations
A user token (pv_ut_…) as Authorization: Bearer pv_ut_…. X-Peeve-Key is accepted too. Never a query parameter — URLs end up in proxy logs and Referer headers.
The token carries its owner's live workspace role, re-read on every call.
Body
application/json
HTTPS only. Private, loopback, link-local and .internal destinations are refused.
Maximum string length:
2048Required. [] is refused; ["*"] means everything.
Minimum array length:
1Available options:
session.started, session.resolved, handoff.created, handoff.message.created, handoff.status.changed, lead.created, lead.status.changed, meeting.booked, meeting.status.changed, billing.payment_failed, billing.subscription.changed, billing.credits_low, billing.credits_expiring, * Maximum string length:
80Optional. Omit or null for every channel.
Available options:
human, agent, whatsapp, messenger, instagram, email false creates it paused.
Create a webhook endpoint