Webhooks notify you in real time when something happens in your workspace (a new contact, a delivered
message, a finished campaign…) via a POST to your URL.
Create an endpoint
You need the webhooks:manage scope. The URL must be https.
The response includes a secret (whsec_…) shown only once — store it to verify the
signature. Rotate it with POST /v1/webhooks/{id}/rotate_secret.
events accepts exact names (contact.created), per-resource wildcards (contact.*), or * (all).
See the full catalog at GET /v1/webhooks/events.
Event shape
POST headers:
Verify the signature
The signature is HMAC-SHA256 of `${timestamp}.${raw_body}` with your secret. Recompute and
compare in constant time. Reject if the timestamp is older than ~5 min (anti-replay).
Verify over the raw body (exact bytes), not the re-serialized JSON.
Delivery, retries, and auto-disable
- At-least-once: the same event may arrive more than once. Deduplicate by
id (or
X-ApyConnect-Delivery). Don’t assume order; use created_at.
- Respond 2xx quickly (< 8 s). If you fail, we retry with exponential backoff.
- After many consecutive failures, the endpoint becomes
auto_disabled (circuit breaker). Fix
your server and reactivate it with PATCH /v1/webhooks/{id} → {"status":"active"} (resets the counter).
Event catalog (excerpt)
message.received · message.sent · message.delivered · message.read · message.failed ·
conversation.created · conversation.assigned · conversation.closed · contact.created ·
contact.updated · contact.merged · deal.stage_changed · deal.won · ticket.created ·
campaign.completed · whatsapp.template.approved · job.completed … (full list at /v1/webhooks/events).