CRM export: the outgoing webhook
Sayply does not integrate with one particular CRM. Instead, after every finished call it sends an outgoing webhook: an HTTP POST with a signed JSON to a URL you choose. A CRM with inbound webhooks, n8n, Make, Zapier or your own script can receive it.
Webhooks are available on the Pro and Business plans.
Setup
- Open app.sayply.com/Integrations.
- Put your receiver's address into Webhook URL and press Save.
- Press Send test event — Sayply immediately sends a test delivery and shows your server's response right on the page.
- Enable delivery with Turn on.
From then on the Export to CRM button in the summary window sends the call to your URL.
What arrives
A call.completed event, JSON:
{
"event": "call.completed",
"version": 2,
"callId": "b584cf6d-…",
"contact": { "name": "…", "company": "…", "phone": "…", "email": "…", "messenger": "…", "role": "…" },
"call": { "startedAt": "2026-08-22T14:00:00+03:00", "endedAt": "…", "durationSeconds": 1830, "category": "Work", "medium": "Voice" },
"summary": { "title": "…", "overview": "…", "agreements": ["…"], "openQuestions": ["…"] },
"tasks": [ { "title": "…", "description": "…", "owner": "…", "dueAt": "2026-08-25" } ],
"transcript": null
}- Timestamps are the local time of your computer, with the offset.
dueAtwithout a time of day is a bare date (2026-08-25); when the task has a time, it is a full moment with the offset.transcriptisnulluntil you tick the transcript checkbox on export; an empty array means "transcript enabled, but no lines were spoken".versionis2since app version 0.3.0:contactgainedrole(the person's job title as heard in the call). The field is additive — receivers written for version 1 keep working. When nothing about the other party was heard,contactisnull.
Verifying the signature
Every delivery carries these headers:
| Header | Meaning |
|---|---|
X-Sayply-Event | event name, currently always call.completed |
X-Sayply-Delivery | delivery id — use it for deduplication |
X-Sayply-Timestamp | Unix time of sending, seconds |
X-Sayply-Signature | sha256= + HMAC-SHA256 |
The signature is computed over the string timestamp + "." + request_body with the secret from the Integrations page:
signature = "sha256=" + hex( HMAC_SHA256( secret, timestamp + "." + body ) )Compare it with the header value — a mismatch means the request did not come from Sayply. The secret is revealed on the page only after an explicit Show secret click; Regenerate immediately breaks verification on your side until you update the secret in your receiver.
Retries and deduplication
A repeated export of the same call — the Retry button in the summary window or Export to CRM from the call history — arrives with the same callId and the same X-Sayply-Delivery. If your automation stores processed ids, a repeat will not create duplicate contacts or tasks.
Sayply waits up to 15 seconds for a response; a slow receiver never blocks the app.