Webhooks
End-of-call report
The webhook OnCore sends to your server when a call finishes.
When a call ends, OnCore POSTs an end-of-call-report event to your server with everything about the call: transcript, summary, timing, recording, and outcome data. This is the primary way to sync call results into your own systems.
Delivery#
The report is sent as an HTTP POST with a JSON body to your configured webhook URL:
- The assistant's
serverUrlif set (per-assistant override), otherwise - your tenant-level server URL.
Delivery is currently not retried — if your endpoint is down or returns a non-2xx status, that report is not redelivered. Respond quickly with a 2xx and process asynchronously.
Verifying requests#
Every delivery includes your client server secret (shown on the API Keys page) in a header. Compare it against the value you have on file and reject mismatches:
POST /your-webhook-endpoint HTTP/1.1
Content-Type: application/json
x-sadie-core-secret: YOUR_CLIENT_SERVER_SECRETapp.post("/sadie/webhooks", (req, res) => {
if (req.header("x-sadie-core-secret") !== process.env.SADIE_CLIENT_SERVER_SECRET) {
return res.status(401).end();
}
const event = req.body;
if (event.type === "end-of-call-report") {
// persist transcript, summary, recording_url, ...
}
res.status(200).end();
});Payload#
| Field | Type | Description |
|---|---|---|
type | string | Always end-of-call-report |
timestamp | number | Unix time in milliseconds when the event was produced |
call_id | string | Unique call identifier |
tenant_id | string | Your tenant |
assistant_id | string | The assistant that handled the call |
customer_number | string | The caller's number |
restaurant_number | string | The OnCore number that was called |
transcript | string | Full call transcript |
summary | string | AI-generated call summary |
messages | array | Turn-by-turn messages |
duration_seconds | number | Call duration in seconds |
duration_minutes | number | Call duration in minutes |
started_at / ended_at | string | Call start / end times |
recording_url | string | Call recording location ("NA" when no recording is available) |
category | string | Primary call category |
category_list | array | All matched categories |
transfer_reason_id | string | Set whenever a transfer was attempted during the call (regardless of ended_reason); omitted when no transfer occurred |
supervisor_answered | boolean | null | Transfer outcome: true if the transferred call was answered (voicemail counts as answered), false if it went unanswered (no-answer, busy, failed, or canceled), null when there is no transfer outcome to report (typically the call had no transfer) |
ended_reason | string | Why the call ended |
extra | object | Additional outcome data (tags, CSAT rating/feedback, SMS reason) |
A companion assistant-request event fires when a call starts, with the same identifiers (call_id, assistant_id, customer_number, call_source) — useful for pre-loading customer context before the call ends.
Reacting to missed transfers#
On a warm-return transfer, supervisor_answered: false means the destination never picked up and the caller came back to the assistant — use it to drive your own follow-up (for example, alerting the team that missed the call). What the caller hears at that moment is configurable via the assistant's warmReturnMessage.