Webhooks
End-of-conversation report
The webhooks OnCore sends when a messaging conversation starts and ends.
Messaging channels (SMS, web chat) have their own mirror of the voice webhooks. When a conversation starts, OnCore POSTs an assistant-request event; when it ends, an end-of-conversation-report with the transcript, summary, and analysis. The payloads are keyed with a conversation_id instead of a call_id — that's how your endpoint tells a conversation from a call — and carry channel / customer_identifier in place of the voice-specific fields.
Delivery#
Sent as an HTTP POST with a JSON body to your configured webhook URL (the assistant's serverUrl if set, otherwise your tenant-level server URL), verified with the plaintext x-sadie-core-secret header — exactly like the voice webhooks. See the webhooks overview.
Delivery is currently not retried — respond quickly with a 2xx and process asynchronously.
Common fields#
Both events share this base:
| Field | Type | Description |
|---|---|---|
type | string | assistant-request (start) or end-of-conversation-report (end) |
timestamp | number | Unix time in milliseconds when the event was produced |
customer_number | string | The customer's phone number, where the channel has one |
customer_identifier | string | The channel-appropriate customer identity (e.g. the visitor id for web chat) |
channel | string | The messaging channel the conversation happened on |
tenant_id | string | Your tenant |
assistant_id | string | The assistant that handled the conversation |
conversation_id | string | Unique conversation identifier — the messaging counterpart of call_id |
restaurant_number | string | The OnCore number the customer texted |
assistant-request (conversation start)#
Carries only the common fields. As with the voice assistant-request, your JSON response is read on start (it can apply overrides) and ignored on end.
end-of-conversation-report (conversation end)#
Adds the outcome fields (all optional):
| Field | Type | Description |
|---|---|---|
transcript | string | Full conversation transcript |
summary | string | AI-generated summary |
messages | array | Turn-by-turn messages |
analysis | object | Pass-through analysis, same shape as voice call analysis: { summary, structuredData: { category, category_list, technicalDifficultiesOccurred }, successEvaluation }. Forwarded verbatim, sentinel values included |
started_at / ended_at | string | Conversation start / end times |
ended_reason | string | Why the conversation ended |
{
"type": "end-of-conversation-report",
"timestamp": 1753872000000,
"customer_number": "+15555550111",
"customer_identifier": "usr_abc123",
"channel": "web_chat",
"tenant_id": "0195f1e2-1111-7000-8000-000000000000",
"assistant_id": "0195f1e2-2222-7000-8000-000000000000",
"conversation_id": "0195f1e2-4444-7000-8000-000000000000",
"restaurant_number": "+15555550123",
"transcript": "...",
"summary": "...",
"started_at": "2026-07-30T11:55:00.000Z",
"ended_at": "2026-07-30T12:00:00.000Z",
"ended_reason": "customer-ended-conversation"
}TODO — verify
The example values for channel and ended_reason are illustrative — the exact value sets are still being verified. Treat both as open strings.
Conversations are also readable via the API: see GET /conversations in SMS & texting.