Prepare your receiver
Confirm API & webhooks access in Plan & billing. Prepare a publicly reachable HTTPS endpoint that accepts POST requests with JSON bodies. A local or private-network URL cannot receive CallSync webhooks.
Use a test receiver first if incoming events create CRM records or trigger automations.
Add an endpoint
0 of 4 steps checked
Choose your events
| Event | When to use it |
|---|---|
| call_logged | A call syncs from an employee’s phone. |
| recording_updated | A call recording finishes uploading. |
| ai_analysis | AI transcript/summary results become available; review analysis status when including failures or skipped analyses. |
| caller_updated | A contact’s name, note or labels change. |
Send a test event
0 of 4 steps checked
Understand the payload
Requests include Content-Type: application/json, X-CallSync-Event and X-CallSync-Signature headers. Call-related payloads carry event, timestamp, org_id, payload_id and data. Contact-update payloads focus on caller data.
For call-related events, data contains call_id, staff, caller, call_details and automation. Treat recording and AI fields as optional. Inspect a test delivery for the complete event-specific payload.
Use data.call_id to associate call, recording and AI updates with the same call. Design downstream writes to tolerate repeated deliveries rather than creating a new CRM record for each update.
Verify the signing secret
Compute HMAC-SHA256 over the exact raw request body using the endpoint secret. Compare the hexadecimal digest with X-CallSync-Signature using a constant-time comparison. Verify the signature before trusting the parsed JSON.
This Node.js example is a verification helper. Your HTTP framework must supply the original body bytes; parsing and re-serializing JSON can change the signature.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyCallSync(rawBody, signature, secret) {
if (typeof signature !== 'string' ||
!/^[a-f0-9]{64}$/i.test(signature)) return false;
const expected = createHmac('sha256', secret)
.update(rawBody).digest();
const received = Buffer.from(signature, 'hex');
return received.length === expected.length &&
timingSafeEqual(received, expected);
}Check Delivery history
Respond promptly and queue longer processing after accepting an event. Use Delivery history to trace the event type, time and response. Do not assume a failed event will be retried automatically; confirm the delivery and processing state before taking further action.
| Result | What to check |
|---|---|
| 2xx | The request was accepted. Check processing separately. |
| 401 / 403 | Receiver authentication and signature verification. |
| 404 | Receiver URL and path. |
| 5xx | Receiver logs and server errors. |
| Timeout / connection error | Public HTTPS reachability and receiver response time. |
Verify one real event
After the test succeeds, sync a fresh work call. Find its event in Delivery history and verify it reached the intended CRM record. If you selected recording or AI events, verify those separately once audio is uploaded or analysis finishes.
To stop sending events, disable the endpoint in Webhooks. Keep signing secrets in server-side configuration and never share them with support.