One webhook for the project
v2 has one webhook per project. It receives every event it is subscribed to, from every address: messages, conversations, calls, templates, campaigns, domains and invitations.201 that creates it returns webhook.secret once. Keep it: later reads
do not return it. POST /v2/webhook/secret rotates it, and the old one stops
working at once.
url must be HTTPS. An event name that does not exist is refused with 400,
with the valid names in details.allowed.
Payload
No sender id appears anywhere in the payload. Project-level events
(
invitation.*, domain.*, broadcast.*) are not about one address: read
data for them.
The event names and their data are listed under WebhookEvent in the
reference, and explained in Webhook events.
Signature
Every delivery carriesX-Zavu-Signature, signed with the webhook’s secret:
v2 is HMAC_SHA256(secret, "{t}.{body}") over the raw body, and it is the
default for a new v2 webhook. signatureVersion can also be v1 or v1+v2.
Moving straight between v1 and v2 is refused with 400: go through
v1+v2. Verification code is in Security.
Retries
A delivery that does not get a2xx is retried, up to 5 attempts in total:
after 1 minute, 5 minutes, 15 minutes and 1 hour. Each event has its own id;
use it to skip a delivery you already processed.
Next to v1 webhooks
Setting up the v2 webhook is the opt-in. From then on each event goes to it in addition to any v1 sender webhook or v1 project webhook subscribed to the same event. They are separate deliveries with different event ids, and nothing is deduplicated.senderWebhooks on GET /v2/webhook lists the v1 sender webhooks still on.
Once your v2 receiver works, switch them off in the same call:
DELETE /v2/webhook does not turn them back on.
The v2 webhook is stored apart from the v1 project webhook
(/v1/invitations/webhook). Neither API reads or writes the other’s.