Skip to content
Assistants

PATCHhttps://core-api.heysadie.ai/assistants/{id}

id name voiceId transcriberId modelId developerPrompt parameters recordingEnabled failoverNumber failoverMode phoneNumberId firstMessage toolIds timezone address endOfCallMessage phoneNumberPassThrough summaryPrompt structuredDataPrompt categories promptId chatPromptId whisperSummaryPromptId voicePersonaPromptId backgroundSound serverUrl notifications csatFeedback idleMessages transferMode callTimeLimitSeconds idleTimeoutSeconds idleMessageMaxSpokenCount settings transferDialTimeout warmWhisperDelaySeconds warmReturnMessage taskDrivenMode transferSettings dictionaryIds dictionarySettings ivrSettings success data createdAt updatedAt featureFlags metadata timestamp version path error code message details field

Update assistant

Try it in the API Explorer

Example request

Terminal
curl -X PATCH "https://core-api.heysadie.ai/assistants/ASSISTANT_ID" \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "string",
    "voiceId": "0195f1e2-0000-7000-8000-000000000000",
    "transcriberId": "0195f1e2-0000-7000-8000-000000000000"
  }'

Authentication

Authenticate with an API key in the Authorization header using the ApiKey scheme. See Authentication for how keys work and where to get them.

Authorizationstringrequired

API key in the ApiKey scheme: ApiKey YOUR_API_KEY. Tenant keys authorize their own tenant; organization keys can act on any tenant in the organization.

X-Tenant-Idstring (uuid)optional

Required when authenticating with an organization key: it selects the tenant the request acts on. Omit with tenant keys.

Request

Path parameters

idstringrequired

The resource's UUID.

Body application/json · required

namestringoptional

Display name of the assistant (e.g., Sadie, Alex)

voiceIdstring (uuid)optional

The voice the assistant will use to speak to callers

transcriberIdstring (uuid)optional

The transcriber engine used to convert speech to text

modelIdstring (uuid)optional

The LLM model that powers the assistant's reasoning (e.g., GPT-4)

developerPromptstringoptional

Custom prompt section developers can inject into the default assistant prompt

parametersanyoptional

JSON object with dynamic values injected into developerPrompt (e.g., {{opening_hours}})

recordingEnabledbooleanoptional

Whether call recordings are enabled for this assistant

failoverNumberstringoptional

The phone number to transfer calls to if the assistant fails to respond (E.164 format)

failoverModebooleanoptional

Turn on or off the failover mode (in case it's enabled, the call will be forwarded to the failover number)

phoneNumberIdstring (uuid)optional

The phone number this assistant is assigned to

firstMessagestringoptional

The first message the assistant says when answering the call

toolIdsstring (uuid)[]optional

List of tool IDs the assistant can use

timezonestringoptional

Timezone of the business the assistant is handling calls for (e.g., Australia/Sydney)

addressstringoptional

Address of the business (used in prompt reasoning)

endOfCallMessagestringoptional

Final message before the call ends

phoneNumberPassThroughbooleanoptional

Whether the assistant can read and reference the caller's phone number if not anonymous

summaryPromptstringoptional

Prompt used to control how the assistant summarizes the call transcript

structuredDataPromptstringoptional

Prompt that helps classify calls based on the categories field

categoriesstring[]optional

List of categories the assistant can classify the call into (e.g., booking, edit)

promptIdstring (uuid)optional

The ID of the prompt associated with the assistant

chatPromptIdstring (uuid) | nulloptional

Optional chat/messaging prompt ID (type 'chat'); null clears it

whisperSummaryPromptIdstring (uuid) | nulloptional

Optional whisper-summary prompt ID (type 'whisper_summary'); null clears it

voicePersonaPromptIdstring (uuid) | nulloptional

Optional voice persona prompt ID (type 'voice_persona', realtime models); null = runtime default persona

backgroundSoundbooleanoptional

Whether the assistant has a background sound

serverUrlstring | nulloptional

The webhook URL override for the assistant; null clears it

notificationsstring[]optional

Array of notification webhook URLs for the assistant

csatFeedbackbooleanoptional

Whether CSAT (Customer Satisfaction) feedback is enabled for this assistant

idleMessagesstring[]optional

Array of messages to send when the assistant detects the caller is idle

transferModeenumoptional

Transfer mode behavior for escalations. Accepts exactly 'cold-transfer', 'smart-summary', or 'warm-return'; any other value is rejected with a 400. Matched exactly and case-sensitively. Defaults to 'cold-transfer' if not provided. 'smart-summary' briefs the destination then connects the caller; 'warm-return' briefs the destination and returns the caller to the assistant if nobody answers.

Allowed values:"cold-transfer""smart-summary""warm-return"
callTimeLimitSecondsstring (integer) | integeroptional

Maximum call duration in seconds. Must be between 10 and 43200 (12 hours). Null means no limit.

idleTimeoutSecondsstring (integer) | integeroptional

Number of seconds to wait before considering the caller idle. Min 0 - Max 60.

idleMessageMaxSpokenCountstring (integer) | integeroptional

Maximum number of times idle messages can be spoken before ending the call. Min 0 - Max 10.

settingsanyoptional

Per-assistant settings container. Currently holds conversationConfig; additional setting categories will be added here in the future. Structure: { conversationConfig: { endpointingPlan?: { mode?: "fixed"|"dynamic", minDelay?, maxDelay? }, turnDetectionPlan?: { timeout?, unlikelyThreshold? }, vadPlan?: { minSpeechDuration?, minSilenceDuration?, prefixPaddingDuration? }, interruptionPlan?: { minDuration? (0-5), minWords? (0-10) }, deliveryMode?: "none"|"emotion_tagging"|"expressive", expressiveOptions?: { disfluencies?: boolean, nonverbalSounds?: boolean | { laughing?, breathing?, sighing?, crying?, vocalizing?, mouthSounds?, reflexSounds? }, pace?: "slow"|"normal"|"fast", instructionsAppend?: string (max 2000) } | null, emotionTaggingEnabled?: boolean (legacy; superseded by deliveryMode) } }

transferDialTimeoutstring (integer) | integeroptional

Dial timeout in seconds for transfer attempts. Integer between 1 and 60. Merged into settings.transferDialTimeout; other settings keys are preserved.

warmWhisperDelaySecondsstring (integer) | integeroptional

Pause in seconds before the warm-transfer whisper plays to the supervisor. Integer between 0 and 30. Defaults to 0 when omitted. Merged into settings.warmWhisperDelaySeconds; other settings keys are preserved.

warmReturnMessagestringoptional

What the assistant says when a warm-return transfer goes unanswered and the caller comes back. Max 2000 characters. Merged into settings.warmReturnMessage; other settings keys are preserved. Send "" to restore the built-in wording. Set this to match whatever your server does when it receives supervisor_answered: false on the end-of-call report.

taskDrivenModebooleanoptional

When true, CoreProxy leaves {tool_instructions} empty and sends linked taskgroups/tasks as structured data to AgentSpawn. When false (default), the existing prompt pipeline runs unchanged.

transferSettingsmap<string, any> | nulloptional

Transfer knobs for this assistant, stored in the transfer_settings column. Structure: { amd_detection?: boolean, use_assistant_number?: boolean }. Unknown keys are rejected. This DEEP-MERGES on PATCH, so sending one knob leaves the others as stored; send null to clear the whole document. amd_detection controls answering-machine detection on a warm-return transfer destination and defaults to on when absent. Turning it off does not merely skip detection: the caller stays bridged to whatever answered, voicemail included, instead of being returned to the assistant. use_assistant_number controls the caller ID shown to the person receiving a cold or warm transfer and defaults to false when absent. When false, they see the customer's phone number, or the assistant's number if the customer withheld theirs. When true, they always see the assistant's own phone number, which is the number the customer called, so they can tell the call is a transfer. The tradeoff is that the customer's number is then not shown on their phone.

dictionaryIdsstring (uuid)[]optional

Tenant dictionaries to link, in precedence order. Replaces the whole set; [] unlinks all. A dictionary's own type decides whether its entries bias the transcriber or shape pronunciation.

dictionarySettingsmap<string, any> | nulloptional

Per-assistant STT keyterms and TTS pronunciation rules. Rules are provider-neutral: `phonemes` is space-separated IPA rendered per TTS model, `respell` is the plain-text fallback; at least one is required. Example: {"sttKeyterms":[{"term":"Gree","language":null}],"ttsPronunciations":[{"word":"Quatre","respell":"Kate","phonemes":"k a t","language":"fr"}]}. Replace semantics: send the whole object; null clears. Zod enforces the real shape.

ivrSettingsmap<string, any> | nulloptional

IVR router configuration for this assistant. Free-form JSON object; no inner structure is validated yet while the feature is in progress. On PATCH this DEEP-MERGES into the stored document, so sending one key leaves the others as stored: no read-modify-write needed. Per-key removal is not expressible: a key sent as null is stored as null, which every consumer reads as unset. Send the whole field as null to clear the document (null = no IVR configured). Omit the field to leave it unchanged.

Responses

200
successbooleanrequired

true on every 2xx

dataobjectoptional

The result

Show 42 child properties
idstringrequired
namestringrequired
firstMessagestringrequired
voiceIdstring | nullrequired
transcriberIdstring | nullrequired
modelIdstring | nullrequired
developerPromptstring | nullrequired
parametersanyrequired
recordingEnabledbooleanrequired
failoverNumberstring | nullrequired
failoverModebooleanrequired
phoneNumberIdstring | nullrequired
createdAtstring (date-time) | string (date) | number | nullrequired
updatedAtstring (date-time) | string (date) | number | nullrequired
toolIdsstring[] | nullrequired
timezonestringrequired
addressstring | nullrequired
endOfCallMessagestring | nullrequired
phoneNumberPassThroughbooleanrequired
summaryPromptstring | nullrequired
structuredDataPromptstring | nullrequired
categoriesstring[] | nullrequired
promptIdstring | nullrequired
chatPromptIdstring | nulloptional
whisperSummaryPromptIdstring | nulloptional
voicePersonaPromptIdstring | nulloptional
backgroundSoundbooleanrequired
serverUrlstring | nullrequired
csatFeedbackbooleanrequired
notificationsanyrequired
idleMessagesanyrequired
transferModeanyrequired
callTimeLimitSecondsnumber | nullrequired
idleTimeoutSecondsnumber | nullrequired
idleMessageMaxSpokenCountnumber | nullrequired
settingsany | nullrequired
taskDrivenModeboolean | nulloptional
featureFlagsmap<string, boolean>optional
ivrSettingsany | nulloptional
transferSettingsany | nulloptional
dictionarySettingsany | nulloptional
dictionaryIdsstring[]optional
metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

400The request is invalid. `details` lists each field that failed
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 3 child properties
codeenumrequired

A parameter or body field broke a rule

Allowed values:"VALIDATION_ERROR"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

detailsobject[]optional

One entry per field that failed

Show 2 item properties
fieldstringrequired

The offending field

messagestringrequired

The rule it broke

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

401Missing or invalid credentials
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

No valid credentials

Allowed values:"UNAUTHORIZED"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

403The credentials are valid but may not use this route
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

The credentials may not use this route

Allowed values:"FORBIDDEN"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

404Not found, or outside the caller's scope
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

An id names nothing the caller can see

Allowed values:"RESOURCE_NOT_FOUND"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

500An unexpected server error
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

An unexpected server failure

Allowed values:"INTERNAL_SERVER_ERROR"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested