Skip to content

Webhooks

Assistant request

The webhook OnCore sends to your server when a call starts.

When a call starts, OnCore POSTs an assistant-request event to your server. It carries the same identifiers the end-of-call report will use, so it's the moment to pre-load customer context: look the caller up in your CRM, warm caches, or open a record you'll complete when the call ends.

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. See the webhooks overview. Deliveries are not retried; the call proceeds regardless of your response.

Payload#

FieldTypeDescription
typestringAlways assistant-request
timestampnumberUnix time in milliseconds when the event was produced
statusstringCall status at the time of the event (e.g. ringing)
customer_numberstringThe caller's number
tenant_idstringYour tenant
assistant_idstringThe assistant answering the call
call_idstringUnique call identifier; matches the call_id in the end-of-call report
restaurant_numberstringThe OnCore number that was called
call_sourcestringHow the call arrived: "webrtc", "pstn", or "whatsapp". May be absent
Example payload
{
  "type": "assistant-request",
  "timestamp": 1753872000000,
  "status": "ringing",
  "customer_number": "+15555550111",
  "tenant_id": "0195f1e2-1111-7000-8000-000000000000",
  "assistant_id": "0195f1e2-2222-7000-8000-000000000000",
  "call_id": "0195f1e2-3333-7000-8000-000000000000",
  "restaurant_number": "+15555550123",
  "call_source": "pstn"
}

Responding#

Respond with a 2xx quickly. Your JSON response body can optionally customize the call that is starting:

Response fieldDescription
data.custom_promptsArray of { title, content } prompt sections to inject for this call
data.overrides.first_messageOverride the assistant's greeting for this call
data.overrides.prompt_variablesMap of values for {%key:default%} placeholders in the assembled prompt
data.overrides.voice_id / transcriber_id / model_idSwap the voice, transcriber, or model for this call
data.overrides.voice / transcriber / modelAn object taking id to swap that channel and settings to change provider settings for this call
Response example
{
  "data": {
    "custom_prompts": [
      { "title": "Customer context", "content": "The caller has an active booking." }
    ],
    "overrides": {
      "first_message": "Welcome back. How can I help with your booking?",
      "prompt_variables": { "customer_tier": "gold" },
      "voice": {
        "id": "0195f1e2-4444-7000-8000-000000000000",
        "settings": {
          "speed": 1.1,
          "locale": "en-GB",
          "accent": "general-american",
          "normalization": "auto"
        }
      }
    }
  }
}

Custom prompt sections are appended to the call's system prompt. prompt_variables are applied after the prompt is assembled, so they can resolve placeholders in saved and custom prompt text. A non-empty first_message replaces the saved greeting.

Voice, transcriber, and model overrides are looked up by ID. A valid ID replaces the saved choice for this call; an unknown ID is ignored and the saved configuration remains in use. The same three channels also accept a settings object, which merges provider settings over whatever that channel resolved to, so a single response can swap a transcriber and retune it at once. The keys each model accepts are listed under Providers, and every one of them is overridable per call. The example above uses the Cartesia voice settings: speed, plus the locale, accent and normalization of sonic-3.5 and sonic-3.6. A key the chosen model does not accept is passed through to the provider as sent, so a wrong value fails at the provider rather than here. These response fields are read only for assistant-request; response bodies from end reports do not alter a completed call.

Keep this response fast

The call cannot finish assembling its configuration until this response arrives. Return only the context needed for this call and move unrelated work off the request path.

Next steps#