Skip to content

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 serverUrl if 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:

Request headers
POST /your-webhook-endpoint HTTP/1.1
Content-Type: application/json
x-sadie-core-secret: YOUR_CLIENT_SERVER_SECRET
Express example
app.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#

FieldTypeDescription
typestringAlways end-of-call-report
timestampnumberUnix time in milliseconds when the event was produced
call_idstringUnique call identifier
tenant_idstringYour tenant
assistant_idstringThe assistant that handled the call
customer_numberstringThe caller's number
restaurant_numberstringThe OnCore number that was called
transcriptstringFull call transcript
summarystringAI-generated call summary
messagesarrayTurn-by-turn messages
duration_secondsnumberCall duration in seconds
duration_minutesnumberCall duration in minutes
started_at / ended_atstringCall start / end times
recording_urlstringCall recording location ("NA" when no recording is available)
categorystringPrimary call category
category_listarrayAll matched categories
transfer_reason_idstringSet whenever a transfer was attempted during the call (regardless of ended_reason); omitted when no transfer occurred
supervisor_answeredboolean | nullTransfer 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_reasonstringWhy the call ended
extraobjectAdditional 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.