Outbound Webhooks
Outbound webhooks send real-time HTTP POST notifications to external URLs when events occur in the system. Use them to integrate with automation platforms like n8n, Zapier, Make, or custom middleware.
Overview
When an event occurs (such as a contact being created, an extension being updated, or a message being sent), the system sends an HTTP POST request to each webhook URL subscribed to that event. The payload includes the event type, a timestamp, and the relevant data.
Outbound webhooks are configured under Integrations > Outbound Webhooks in the tenant settings.
Creating a Webhook
Click Add to create a new webhook. Each webhook has:
- Name - a descriptive label for the webhook
- URL - the destination endpoint that will receive the POST requests
- Secret - an optional shared secret used to sign payloads with HMAC-SHA256 so consumers can verify authenticity
- Active - enable or disable delivery without deleting the webhook
- Events - select which events trigger this webhook, organized into three categories
Event Categories
Events are grouped into three categories, each with its own selector:
CRM Events
- Contact - created, updated, deleted
- Account - created, updated, deleted
- Lead - created, updated, deleted, converted to contact
- List - created, updated, deleted
- Activity - created
- Deal - created, updated, stage changed
- Task - created, completed
- Campaign - created, status changed
Wildcard subscriptions are supported (e.g., contact.* matches all contact events).
Configuration Events
- Extension - created, updated, deleted
- DID - created, updated, deleted
- Trunk - created, updated, deleted
- Queue - created, updated, deleted
- Hunt Group - created, updated, deleted
- IVR - created, updated, deleted
- Administrator - created, updated, deleted
Communications Events
- Call - completed, missed
- Voicemail - received
- WhatsApp - message received, message sent
- SMS - message received, message sent
Payload Format
Each webhook delivery sends a JSON payload:
{ "event": "extension.created", "timestamp": 1710700000, "data": { "name": "john", "extension": "1001", "first_name": "John", "last_name": "Doe" }}The following HTTP headers are included:
| Header | Description |
|---|---|
Content-Type | application/json |
X-Webhook-Event | The event name (e.g., contact.created) |
X-Webhook-Timestamp | Unix timestamp of the delivery |
X-Webhook-Signature | HMAC-SHA256 signature (if a secret is configured) |
Verifying Signatures
If a secret is configured, the system signs each payload using HMAC-SHA256. To verify:
- Concatenate the timestamp and the raw request body with a
.separator - Compute HMAC-SHA256 using the shared secret
- Compare the result with the
X-Webhook-Signatureheader
Example in Python:
import hmac, hashlib
def verify_webhook(payload_body, timestamp, signature, secret): expected = hmac.new( secret.encode(), f"{timestamp}.{payload_body}".encode(), hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature)Testing Webhooks
Click the Test Webhook button on the webhook grid to send a test event (webhook.test) to the configured URL. This verifies connectivity and lets you inspect the payload format at the receiving end.
The test delivery is logged in the delivery log just like regular events.
Trying it without a real receiver
You do not need to stand up a real HTTP service to validate that webhook delivery is working. Free public request inspectors are convenient for ad-hoc testing:
- webhook.site - generates a unique URL on load and shows every incoming request in real time, including headers and body. Paste the URL into the URL field, save, then click Test Webhook and switch back to the webhook.site tab to inspect the request.
- requestbin.com - similar to webhook.site with a different UI.
https://httpbin.org/post- returns 200 and echoes the request back in the response body. Useful when you want to confirm the test handler reports a clean success.
About redirects (HTTP 301 / 302)
Webhook delivery does not follow HTTP redirects on POST. If your receiver returns a 301 or 302, the test will report the redirect status as a failure rather than re-POSTing to the redirect target. This is intentional - silent redirect-following is a security and reliability hazard for webhook receivers. If you see a 301 in the test result, the most common causes are:
- The URL was typed with
http://and the host now requireshttps:// - The URL is missing or has an extra trailing slash that the server canonicalizes
- The URL points at a vanity host that redirects to a
www.or other canonical host
Run curl -i -X POST '<your-url>' and look at the Location: response header to see the URL the receiver wants you to use, then save that as the webhook URL.
Delivery Log
Click the Deliveries badge on the webhook grid to open the delivery log. The log shows:
- Time - when the delivery was attempted
- Event - which event triggered the delivery
- Status - HTTP status code (green for 2xx, red for errors)
- Payload - the JSON payload that was sent
- Response - the response body from the receiving server
The delivery log retains the most recent 200 entries per webhook.
Retry Behavior
Webhook delivery uses a 5-second timeout. If the destination does not respond or returns a non-2xx status code, the failure is logged and the webhook’s failure counter is incremented. The last_triggered and last_status_code fields on the webhook record are updated after each delivery attempt.
Permissions
Access to outbound webhooks requires the outbound_webhooks permission, which is included in the Global Admin, System Admin, Tenant Admin, and Multi-Tenant Admin roles by default.
See Also
- System Webhooks - the cross-tenant equivalent for platform administrators who need to receive provisioning events from every tenant in a single subscription.