Both send the same JSON body:
2xx. GET /v1/webhooks/events lists every event type you can subscribe to.
For double opt-in, LIST_SUBSCRIPTION_CONFIRMED is sent once for each list a confirmation click activates, with data of { "contactId", "email", "listId", "listName" }. CONTACT_CONFIRMED ({ "contactId", "email" }) is sent only when the contact itself goes from pending to active. See Webhooks.
Subscribing a REST hook
201 { "id": "…" }. Subscribing the same event and URL again returns the same id. To remove the subscription, call DELETE /v1/webhooks/{id}.
Verifying signatures
Endpoints registered under Settings → Webhooks with a secret receive these headers:webhook-id: the message ID. It stays the same across retries, so use it to deduplicate.webhook-timestamp: Unix seconds.webhook-signature:v1,<base64 HMAC-SHA256>of"{webhook-id}.{webhook-timestamp}.{raw body}".X-Signature-256: the legacy header,sha256=<hex HMAC-SHA256 of the raw body>.
whsec_, base64-decode the rest to get the HMAC key. Otherwise the key is the secret’s UTF-8 bytes. Endpoints without a secret receive no signature headers.
X-Webhook-Event and X-Webhook-Attempt.
Retries and disabling
For dashboard endpoints, delivery is tried three times in a row, 1 and 2 seconds apart. After that it is retried on a schedule of +5 min, +30 min, +2 h, +5 h, +8 h, +8 h and +10 h. A429 reschedules the delivery without counting it as a failure. An endpoint that keeps failing for more than 12 hours is disabled until you re-enable it in Settings → Webhooks.
The full delivery schema, with every header and payload field, is in Settings → API reference in the app.