Assistants
Custom instructions
Attach short titled behavior notes to an assistant, and override a shared tool's steps for one assistant only.
Two separate mechanisms live on this page, and they are easy to confuse. Custom instructions are short titled notes attached to one assistant: a lightweight way to adjust how it behaves without touching its prompt. Instruction overrides are surgical edits to a single step inside a tool's instruction flow, applied to one assistant so every other assistant sharing that tool keeps the original wording.
They live on different resources, take different bodies, and solve different problems.
| Custom instructions | Instruction overrides | |
|---|---|---|
| Resource | /custom-instructions | /assistants/{id}/tools/{toolId}/…/override, and …/text-override for text conversations |
| What it changes | A standing behavior note on the assistant | One step of one tool's instruction flow |
| Scope | The assistant you attach it to | The assistant-and-tool pair you set it on |
| Reach for it when | You want to add or retire a small behavior note | A shared tool is right for every assistant except this one |
Every endpoint on this page returns the standard envelope: success, data, and metadata (timestamp, version, path). The response examples below show the data payload; see API conventions for the full shape. All fourteen endpoints can return 400, 401, 403, 404 and 500 in the error envelope described in Errors.
Custom instructions#
| Method | Path | Purpose |
|---|---|---|
| GET | /custom-instructions | List custom instructions |
| POST | /custom-instructions | Create a custom instruction |
| PATCH | /custom-instructions/{id} | Update a custom instruction |
| DELETE | /custom-instructions/{id} | Delete a custom instruction |
All four return the same record:
| Field | Description |
|---|---|
id | Identifier of the custom instruction. A string. |
assistantId | Identifier of the assistant it is attached to. A string. |
title | The title of the custom instruction. |
description | The instruction text itself. |
createdAt | When the instruction was created. |
All three fields are nullable on read
title, description and createdAt are each a string-or-null on the returned record;
createdAt is a date. Creating an instruction requires a non-empty title and
description, so a null on read means an older or partially-written record rather than
something you just sent. Guard for it before rendering.
List custom instructions#
GET /custom-instructions takes an assistantId query parameter that narrows the list to a single assistant.
curl "https://core-api.heysadie.ai/custom-instructions?assistantId=0195f1e2-0000-0000-0000-000000000000" \
-H "Authorization: ApiKey YOUR_API_KEY"data carries the page in customInstructions and a total count:
{
"customInstructions": [
{
"id": "0195f1e2-0000-0000-0000-000000000001",
"assistantId": "0195f1e2-0000-0000-0000-000000000000",
"title": "…",
"description": "…",
"createdAt": "…"
}
],
"total": 1
}assistantId is required, and nothing else is accepted
Custom instructions are always read per assistant: assistantId is a required query
parameter and there is no way to list every instruction across your account in one call.
The query is also strict: any additional parameter is rejected rather than ignored, so a
stray limit or offset will fail the request with 400.
Create a custom instruction#
POST /custom-instructions attaches one instruction to one assistant.
| Field | Type | Description |
|---|---|---|
assistantId | string | The assistant to attach the instruction to. |
title | string | The title of the custom instructions. |
description | string | The custom instructions for the assistant. |
curl -X POST https://core-api.heysadie.ai/custom-instructions \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"assistantId": "0195f1e2-0000-0000-0000-000000000000",
"title": "Mention the special",
"description": "Whenever the caller asks about the menu, mention today'\''s special before anything else."
}'data is the created record:
{
"id": "0195f1e2-0000-0000-0000-000000000001",
"assistantId": "0195f1e2-0000-0000-0000-000000000000",
"title": "Mention the special",
"description": "…",
"createdAt": "…"
}Limits#
These are enforced on the server and are not expressed in the OpenAPI document, so a client that only reads the spec will not see them:
| Constraint | Value |
|---|---|
title length | 1 to 36 characters |
description length | 1 to 500 characters |
| Instructions per assistant | 6 |
Creating a seventh returns 400 with the message
Maximum number of custom instructions (6) reached for this assistant. Longer or broader
behaviour changes belong in the assistant's prompt rather
than in more instructions.
Update a custom instruction#
PATCH /custom-instructions/{id} takes title and description in the body: the title of the custom instructions, and the updated custom instructions for the assistant. The id path parameter is required.
curl -X PATCH https://core-api.heysadie.ai/custom-instructions/0195f1e2-0000-0000-0000-000000000001 \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Mention the special",
"description": "Mention today'\''s special only when the caller asks about food."
}'data is the updated record, in the same shape create returns.
Delete a custom instruction#
DELETE /custom-instructions/{id} detaches the instruction from its assistant. Unlike most delete endpoints in this API, it does not return an empty body: data is the record that was removed, so you can log or restore it without a prior read.
curl -X DELETE https://core-api.heysadie.ai/custom-instructions/0195f1e2-0000-0000-0000-000000000001 \
-H "Authorization: ApiKey YOUR_API_KEY"{
"id": "0195f1e2-0000-0000-0000-000000000001",
"assistantId": "0195f1e2-0000-0000-0000-000000000000",
"title": "Mention the special",
"description": "…",
"createdAt": "…"
}Instruction overrides#
A tool is usually shared: several assistants link the same one, and editing the tool changes it for all of them. An instruction override lets you customize how that shared tool behaves for a single assistant, without modifying the tool itself.
| Method | Path | Purpose |
|---|---|---|
| GET | /assistants/{id}/tools/{toolId}/override | Read every override set for this tool on this assistant |
| PUT | /assistants/{id}/tools/{toolId}/description-override | Override the tool's when-to-call description for this assistant |
| PUT | /assistants/{id}/tools/{toolId}/steps/{stepId}/override | Override one step |
| DELETE | /assistants/{id}/tools/{toolId}/steps/{stepId}/override | Restore one step to the tool's default |
| DELETE | /assistants/{id}/tools/{toolId}/override | Remove every override for this tool on this assistant |
| GET | /assistants/{id}/tools/{toolId}/text-override | Read every text-conversation override for this tool on this assistant |
| PUT | /assistants/{id}/tools/{toolId}/text-description-override | Override the when-to-call description in text conversations |
| PUT | /assistants/{id}/tools/{toolId}/steps/{stepId}/text-override | Override one step of the tool's text instructions |
| DELETE | /assistants/{id}/tools/{toolId}/steps/{stepId}/text-override | Restore one step of the tool's text instructions |
| DELETE | /assistants/{id}/tools/{toolId}/text-override | Remove every text-conversation override for this tool on this assistant |
The first five patch the tool's instruction. The text- five patch its textInstructions, which text conversations use instead; see Overrides for text conversations.
How overrides work#
Each step in a tool's instruction.steps array can carry a step_id (a stable, internal identifier that never appears in the prompt). That step_id is what you target: it becomes the {stepId} path segment, and the key under which the override is stored.
Every override endpoint has the same requirements:
- The assistant must belong to your account.
- The tool must belong to your account, or be a platform-provided global tool.
- The tool must be linked to the assistant.
PUT on a step adds one more: the step_id must exist in the tool's instruction.steps array.
Override the when-to-call description#
PUT /assistants/{id}/tools/{toolId}/description-override replaces the tool's when-to-call description for this assistant only. An empty string, or whitespace only, restores the default.
This is the path the Knowledge Base tab uses for When to look this up. The tool must already be linked. See Control when the assistant looks up for the Knowledge Base flow, including what the assistant is told after you set the text.
Read the current overrides#
GET /assistants/{id}/tools/{toolId}/override returns the full instruction_override object for that assistant-and-tool pair, or null if no overrides are set.
curl "https://core-api.heysadie.ai/assistants/0195f1e2-0000-0000-0000-000000000000/tools/0195f1e2-0000-0000-0000-000000000002/override" \
-H "Authorization: ApiKey YOUR_API_KEY"data is keyed by step_id under steps. When a when-to-call override is set, description is present at the top level too:
{
"description": "Only look this up when the caller asks about parking.",
"steps": {
"collect_email": {
"action": "Custom action text",
"wait_for_response": false
},
"collect_phone": {
"_remove": true
}
}
}Read this before writing: it shows which steps this assistant has already diverged on, and whether a description override is set. For the Knowledge Base tool, description is the when-to-look-up text.
Override a step#
PUT /assistants/{id}/tools/{toolId}/steps/{stepId}/override overrides a single step in a tool's instruction flow for one assistant.
| Field | Type | Description |
|---|---|---|
action | string | Replacement action text for this step. If omitted, the original action is kept. |
additional_rules | string[] | Replaces the step's additional rules. |
wait_for_response | boolean | Whether the assistant should wait for a caller response at this step. If omitted, the original value is kept. |
_remove | boolean | Set to true to remove this step entirely from the instruction flow for this assistant. |
Include only the fields you want to change; omitted fields keep the tool's default value.
If the tool has a step with "step_id": "collect_email", you can rewrite it for one assistant while every other assistant using the same tool still sees the original step:
curl -X PUT "https://core-api.heysadie.ai/assistants/0195f1e2-0000-0000-0000-000000000000/tools/0195f1e2-0000-0000-0000-000000000002/steps/collect_email/override" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "Just confirm the email already on file.",
"additional_rules": ["Skip if email is already confirmed."]
}'data carries a single message string:
{ "message": "…" }To skip a step entirely for this assistant, send _remove on its own:
curl -X PUT "https://core-api.heysadie.ai/assistants/0195f1e2-0000-0000-0000-000000000000/tools/0195f1e2-0000-0000-0000-000000000002/steps/collect_phone/override" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "_remove": true }'Restore one step#
DELETE /assistants/{id}/tools/{toolId}/steps/{stepId}/override removes a single step override. Afterwards that step uses the original action, additional_rules and wait_for_response values defined on the shared tool, including a step you had removed with _remove, which reappears in this assistant's flow.
curl -X DELETE "https://core-api.heysadie.ai/assistants/0195f1e2-0000-0000-0000-000000000000/tools/0195f1e2-0000-0000-0000-000000000002/steps/collect_email/override" \
-H "Authorization: ApiKey YOUR_API_KEY"data carries a single message string, as with PUT.
Restore every override#
DELETE /assistants/{id}/tools/{toolId}/override removes all instruction overrides for that tool on that assistant, including a description override. The tool's default instruction flow is restored and instruction_override is set back to null. Use it when an assistant should behave like everyone else again: it is one call instead of one per diverged step.
curl -X DELETE "https://core-api.heysadie.ai/assistants/0195f1e2-0000-0000-0000-000000000000/tools/0195f1e2-0000-0000-0000-000000000002/override" \
-H "Authorization: ApiKey YOUR_API_KEY"data carries a single message string.
Overrides for text conversations#
A tool can carry textInstructions: a second instruction flow that SMS, WhatsApp and web chat use instead of instruction. Its per-assistant overrides live apart from the voice ones, behind the five text- endpoints in the table above. Each takes the same body and returns the same response as its voice counterpart.
The two sets never touch each other. A text override does not change voice calls, a voice override does not change text conversations, and clearing one set leaves the other in place.
What a text conversation gets depends on the tool:
The tool has textInstructions | A text conversation follows |
|---|---|
| Yes | textInstructions, with this assistant's text overrides applied |
| No | instruction, with this assistant's voice overrides applied, exactly as on a call |
So a text override has no effect on a tool without textInstructions, and PUT on a text step checks the step_id against textInstructions.steps. It returns 400 when the tool has no text instructions, or when the step exists only in instruction.
This removes a step from one assistant's text flow while its calls keep the step:
curl -X PUT "https://core-api.heysadie.ai/assistants/0195f1e2-0000-0000-0000-000000000000/tools/0195f1e2-0000-0000-0000-000000000002/steps/special_requests/text-override" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "_remove": true }'GET /assistants/{id}/tools/{toolId}/text-override returns the text overrides in the same shape as the voice ones (steps keyed by step_id, and description when set), or null when none are set.
Next steps#
- Tools: define the shared tool, and give its steps the
step_idvalues an override targets. - Control when the assistant looks up: the Knowledge Base when-to-call override, and tenant-wide instructions for that tool.
- Assistants: link a tool to the assistant before you can override any of its steps.
- Prompts: when a behavior change is too broad for a short note, edit the assistant's prompt instead.