The first integration everyone writes polls the calls endpoint every minute and looks for changes. It works, it is wasteful, and it is always a minute behind. Webhooks replace it: register an HTTPS endpoint and Veytrix posts to you the moment something happens.
What you get
Three events, each fired once per call:
- call.completed — a real conversation ended. Carries duration, the person's name and number, and the summary.
- call.failed — it did not connect, or nobody answered. Same shape, status failed or no-answer.
- rating.created — the scorecard is ready. Always arrives after that call's own event, sometimes by a minute, because scoring runs in the background.
That last point catches people out. Do not wait for both events before writing anything — handle each independently and update the same record twice.
Verifying the signature
Every delivery carries an HMAC-SHA256 signature over the exact raw body, keyed by your subscription secret. Two rules:
Verify before you parse. The signature covers the bytes you received. If your framework parses JSON first and you re-serialise it to check, the bytes have changed and it will never match. In Express that means the raw body middleware, not the JSON one.
Compare in constant time. Use a timing-safe comparison, not string equality.
The four mistakes that cost people days
Doing work before responding. Deliveries time out after ten seconds. Acknowledge immediately, then process out of band. A handler that writes to three systems before returning will start timing out under load, and a timeout looks identical to being down.
Assuming order. Deliveries are not ordered. Key everything on the call id and make the handler idempotent — the same event arriving twice must not create two records.
Assuming retries. A non-2xx response is logged, not automatically retried. If your endpoint was down you have missed those events. There is an endpoint to replay a specific call's events, which is what you want after an outage.
Pointing at an internal address. The target must be publicly reachable over HTTPS. Addresses that resolve to private ranges are refused at delivery time, not just at registration — so a DNS change cannot quietly turn your endpoint into an internal one.
What to build first
The smallest useful handler upserts an activity on call.completed with the summary, then patches it with the score on rating.created. That is twenty lines and it puts every outcome in your CRM without anyone exporting anything.
