Skip to content

Guides

Assistants

The full assistant lifecycle — create, configure voice and behavior, attach knowledge and tasks, wire up webhooks, and enable SMS.

An assistant is a configured AI voice agent that answers calls (and optionally texts) on behalf of your business. This guide walks the whole lifecycle: pick the building blocks, create the assistant, tune its behavior, attach knowledge and task flows, point webhooks at your server, and toggle the SMS channel.

For endpoint-by-endpoint request/response schemas, see the Assistants API reference.

Pick a voice, model, and transcriber#

Every assistant references three lookup resources by UUID:

ResourceEndpointWhat it is
VoiceGET /voicesThe voice the assistant speaks with
ModelGET /modelsThe LLM that powers reasoning and responses
TranscriberGET /transcribersThe speech-to-text engine

All three lists support limit and offset query params, and each has a GET /{resource}/{id} detail endpoint.

bash
curl "https://core-api.heysadie.ai/voices?limit=50" \
  -H "Authorization: ApiKey YOUR_API_KEY"

curl "https://core-api.heysadie.ai/models?limit=50" \
  -H "Authorization: ApiKey YOUR_API_KEY"

curl "https://core-api.heysadie.ai/transcribers?limit=50" \
  -H "Authorization: ApiKey YOUR_API_KEY"

Keep the id of the voice, model, and transcriber you want — you'll pass them as voiceId, modelId, and transcriberId when creating the assistant.

To help you choose, each voice row carries optional language (the language codes that voice can speak with its underlying TTS model) and tags (guidance badges such as gender, accent, and personality) — see Voices, Models & Transcribers. Voice display names are not unique (the same voice can appear once per underlying model), so always reference voices by id.

Create the assistant#

POST /assistants

bash
curl -X POST https://core-api.heysadie.ai/assistants \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Front Desk",
    "voiceId": "0195f1e2-...",
    "modelId": "0195f1e2-...",
    "transcriberId": "0195f1e2-...",
    "developerPrompt": "We are open {{opening_hours}}. Always ask for a callback number before ending the call.",
    "parameters": { "opening_hours": "10am to 10pm" },
    "firstMessage": "Hi! You have reached Joe'\''s Pizza. How can I help?",
    "endOfCallMessage": "Thanks for calling — have a great day!",
    "recordingEnabled": true,
    "failoverNumber": "+15551234567",
    "failoverMode": false,
    "toolIds": [],
    "timezone": "Australia/Sydney",
    "address": "1 Example Street, Sydney",
    "phoneNumberPassThrough": true
  }'

Placeholders must match

Make sure your parameters keys match the {{placeholders}} used in developerPrompt — if the prompt says {{opening_hours}}, then parameters must include "opening_hours".

Core field guide#

FieldTypeDescription
namestringDisplay name of the assistant (e.g. "OnCore", "Alex").
voiceId / modelId / transcriberIdUUIDThe voice, LLM, and speech-to-text engine (see lookups above).
developerPromptstringYour own section injected into the default system prompt. Example: "Always ask for membership ID before confirming a reservation."
parametersobjectDynamic values like {{opening_hours}} or {{branch_name}}, inserted into the prompt.
firstMessagestringWhat the assistant says at the start of the call.
endOfCallMessagestringThe last thing the assistant says before hanging up. On updates you can clear it (empty string or null) for "no scripted goodbye".
recordingEnabledbooleanIf true, calls are recorded.
failoverNumberstringE.164 number the call is forwarded to if the assistant fails or needs to escalate. On updates, an extension may follow a comma (e.g. +15551234567,101).
failoverModebooleanIf true, calls are forwarded to the failover number.
phoneNumberIdUUIDOptional — links the assistant to a phone number you own.
toolIdsUUID[]Tools the assistant may use during a call.
timezonestringIANA timezone of the business (e.g. "Australia/Sydney").
addressstringThe business address.
phoneNumberPassThroughbooleanIf true, the assistant can reuse the caller's number ("Would you like to use the number ending in 595?"); if false, it always asks.
summaryPromptstringGuides how the assistant summarizes the call at the end.
structuredDataPromptstringWorks with categories to classify calls.
categoriesstring[]Call classification labels, e.g. ["booking", "edit", "cancel"].
promptIdUUIDThe prompt the assistant uses; omit for the default.
chatPromptIdUUID | nullOptional chat/messaging prompt (nullable so it can be unset).
whisperSummaryPromptIdUUID | nullOptional whisper-summary prompt (nullable so it can be unset).
backgroundSoundbooleanWhether the assistant plays a background sound.
serverUrlURL | nullWebhook URL override for this assistant (see below). On updates, null (or an empty string) clears it.
notificationsURL[]Up to 10 notification webhook URLs. New URLs are appended to existing ones, not replaced.
csatFeedbackbooleanEnables CSAT (customer satisfaction) feedback. Defaults to false.
transferModestringTransfer mode for escalations. Defaults to cold-transfer.
warmWhisperDelaySecondsintegerWarm-transfer whisper delay, 0–30 seconds. Defaults to 0.
transferDialTimeoutintegerTransfer dial timeout, 1–60 seconds.
warmReturnMessagestringWhat the assistant says when a warm-return transfer goes unanswered and the caller comes back (max 2000 characters). Stored under settings.warmReturnMessage; send "" to restore the built-in wording. Pairs with supervisor_answered: false on the end-of-call report.
callTimeLimitSecondsintegerMaximum call length, 10–43200 seconds.
idleMessages / idleTimeoutSeconds / idleMessageMaxSpokenCountIdle-caller behavior: messages spoken after idleTimeoutSeconds (max 60) of silence, at most idleMessageMaxSpokenCount (max 10) times.
taskDrivenModebooleanEnables task-group-driven conversation flow.
settings.conversationConfigobjectConversation timing and speech delivery tuning — see below.

Conversation timing (settings.conversationConfig)#

All sub-plans and fields are optional; omitted values use agent defaults, and null clears a stored value.

PlanFields
endpointingPlanmode ("fixed" | "dynamic" — dynamic adapts to the caller's pause pacing), minDelay / maxDelay (seconds of silence before the agent responds).
turnDetectionPlantimeout (seconds), unlikelyThreshold (0–1 probability).
vadPlanminSpeechDuration, minSilenceDuration, prefixPaddingDuration (seconds).
interruptionPlanminDuration (0–5 s of sustained caller speech before a barge-in stops the agent), minWords (0–10 transcribed words required to register an interruption).

Speech delivery (settings.conversationConfig.deliveryMode)#

How expressive the assistant's voice sounds. One mode per assistant; the mode is read at call start, so a change applies from the next call.

ValueBehavior
"none"Plain delivery. The default.
"emotion_tagging"A classifier picks at most one fitting emotion per response and injects the matching emotion tag into the speech. Supported by Cartesia Sonic 3 / 3.5 and ElevenLabs v3 voices; English calls only. Other voices keep their normal delivery.
"expressive"The model itself steers delivery — pacing, natural disfluencies, and nonverbal sounds such as laughter. Supported by Cartesia, Fish Audio, xAI, and Inworld voices. Other voices keep their normal delivery.

With deliveryMode: "expressive", the optional expressiveOptions object (also under settings.conversationConfig) tunes the built-in defaults. Only the keys you set override a default; send expressiveOptions: null to clear all stored overrides.

FieldTypeDescription
disfluenciesbooleanNatural fillers ("um", "uh"). On by default; set false to opt out.
nonverbalSoundsboolean | objecttrue / false switches all nonverbal sounds at once, or pass an object of per-category booleans: laughing, breathing, sighing, crying, vocalizing, mouthSounds, reflexSounds.
pacestring"slow", "normal", or "fast". Omit to let the model pace itself.
instructionsAppendstringExtra delivery guidance appended to the built-in instructions (max 2000 characters).

Legacy flag

settings.conversationConfig.emotionTaggingEnabled (boolean) is the older opt-in for emotion tagging. It is superseded by deliveryMode but still honored when deliveryMode is absent.

Update the assistant#

PATCH /assistants/{id} — partial update; send only the fields you want to change. The body accepts the same fields as create.

Terminal
curl -X PATCH https://core-api.heysadie.ai/assistants/ASSISTANT_ID \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "firstMessage": "Thanks for calling Joe'\''s — what can I do for you?" }'

Attach knowledge and task flows#

Once the assistant exists, wire in its supporting resources:

  • Documents — attach knowledge-base documents with POST /assistants/{id}/documents. See Knowledge base.
  • Task groups — link structured task flows with POST /assistants/{id}/taskgroups and set per-assistant task overrides. See Task groups.
  • Tools — set toolIds on the assistant (create or PATCH). See Tools.
  • Custom instructions — add up to six short behavior tweaks. See Custom instructions.
  • Capture forms — collect structured caller details. See Capture forms.

Point webhooks at your server (serverUrl)#

serverUrl is the per-assistant webhook URL override: set it (on create or PATCH) to receive call results on your own endpoint, e.g. the end-of-call report. notifications holds up to 10 additional webhook URLs — remember that PATCHing notifications appends new URLs rather than replacing the list.

Terminal
curl -X PATCH https://core-api.heysadie.ai/assistants/ASSISTANT_ID \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "serverUrl": "https://api.example.com/sadie/webhooks" }'

URLs are validated for safety at write time — unresolvable or disallowed hosts are rejected with a validation error.

To remove the override, PATCH serverUrl to null (an empty string works too); deliveries then fall back to your tenant-level webhook URL.

Enable or disable SMS#

PATCH /assistants/{id}/sms-enabled

Terminal
curl -X PATCH https://core-api.heysadie.ai/assistants/ASSISTANT_ID/sms-enabled \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smsEnabled": true }'
  • smsEnabled: true turns the SMS channel on; false turns it off.
  • Enabling requires a linked Twilio phone number. The number is attached to the SMS sender pool automatically (idempotent). If no Twilio number is linked, the request fails with 400 (NO_PHONE_NUMBER_LINKED / NON_TWILIO_PROVIDER) and the flag is left unchanged.
  • Disabling only clears the flag — the number intentionally stays registered for SMS so re-enabling doesn't require re-registration.
  • The response returns the assistant id and its featureFlags map; other channel flags are preserved.

SMS traffic then shows up as conversations.

Delete the assistant#

DELETE /assistants/{id} — deletes the assistant. Attached sub-resources (documents, task groups, overrides) are managed through their own endpoints.

Terminal
curl -X DELETE https://core-api.heysadie.ai/assistants/ASSISTANT_ID \
  -H "Authorization: ApiKey YOUR_API_KEY"

Next steps#

  • Prompts — reusable system prompts and global templates.
  • Phone numbers — buy a number and link it via phoneNumberId.
  • Calls — read call activity for your assistants.