Webhooks
Receiving events from Neo Dialer, and verifying they came from us.
Outbound webhooks push events to your endpoint as they happen, so you do not have to poll.
Setting one up
Admin → Configuration → Outbound Webhooks → Add. Provide a name, your endpoint URL, and the events you want. A signing secret is generated when the webhook is created.
You can add custom headers if your endpoint needs them, and there is a Test action that sends a sample delivery so you can confirm your endpoint accepts it before real traffic arrives.
Events
These are the event types the platform emits today:
| Event | Fires when |
|---|---|
call_completed | A call finishes, with outcome, duration and transcript |
appointment_booked | An appointment is successfully booked |
qa_scored | A QA scorecard is completed for a call |
compliance_checked | A compliance check runs against a call |
coaching_alert | A coaching alert is raised |
Subscribing to an event name outside that list is rejected when the webhook is saved, rather than silently accepted and never delivered.
The request
Deliveries are POST with a JSON body, and carry two headers:
POST https://your-endpoint.example.com/hooks/neodialer
Content-Type: application/json
X-Webhook-Event: call_completed
X-Webhook-Signature: sha256=<hex digest>Verifying the signature
The signature is an HMAC-SHA256 of the raw request body, keyed with your webhook's secret, hex-encoded and prefixed with sha256=.
Verify it before trusting anything in the payload:
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const expected =
'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
// Constant-time compare — a plain === leaks timing information.
const a = Buffer.from(header || '');
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Hash the raw body exactly as received. Parsing the JSON and re-serialising it will change key order or whitespace and the signature will not match.
Responding
Return a 2xx status as soon as you have accepted the payload. Do the actual work afterwards — a slow endpoint looks like a failed delivery.
Retries and delivery logs
Failed deliveries are retried, and every attempt is recorded. Admin → Configuration → Outbound Webhooks → Logs shows what was sent, what came back, and lets you replay an individual delivery once your endpoint is fixed.
This is the first place to look when an integration "stopped working": the log will tell you whether we sent it and what your endpoint said.
Inbound webhooks
Separately, Admin → Configuration → Webhooks covers webhooks into the platform — for example carrier event callbacks. Those are configured per provider.
Something here wrong or missing? Tell us — these pages describe the platform as it actually behaves, so a mismatch is a bug we want to know about.