Skip to content

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 instructionsInstruction overrides
Resource/custom-instructions/assistants/{id}/tools/{toolId}/…/override, and …/text-override for text conversations
What it changesA standing behavior note on the assistantOne step of one tool's instruction flow
ScopeThe assistant you attach it toThe assistant-and-tool pair you set it on
Reach for it whenYou want to add or retire a small behavior noteA 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#

MethodPathPurpose
GET/custom-instructionsList custom instructions
POST/custom-instructionsCreate 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:

FieldDescription
idIdentifier of the custom instruction. A string.
assistantIdIdentifier of the assistant it is attached to. A string.
titleThe title of the custom instruction.
descriptionThe instruction text itself.
createdAtWhen 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.

bash
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:

Response data
{
  "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.

FieldTypeDescription
assistantIdstringThe assistant to attach the instruction to.
titlestringThe title of the custom instructions.
descriptionstringThe custom instructions for the assistant.
bash
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:

Response data
{
  "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:

ConstraintValue
title length1 to 36 characters
description length1 to 500 characters
Instructions per assistant6

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.

bash
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.

bash
curl -X DELETE https://core-api.heysadie.ai/custom-instructions/0195f1e2-0000-0000-0000-000000000001 \
  -H "Authorization: ApiKey YOUR_API_KEY"
Response data
{
  "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.

MethodPathPurpose
GET/assistants/{id}/tools/{toolId}/overrideRead every override set for this tool on this assistant
PUT/assistants/{id}/tools/{toolId}/description-overrideOverride the tool's when-to-call description for this assistant
PUT/assistants/{id}/tools/{toolId}/steps/{stepId}/overrideOverride one step
DELETE/assistants/{id}/tools/{toolId}/steps/{stepId}/overrideRestore one step to the tool's default
DELETE/assistants/{id}/tools/{toolId}/overrideRemove every override for this tool on this assistant
GET/assistants/{id}/tools/{toolId}/text-overrideRead every text-conversation override for this tool on this assistant
PUT/assistants/{id}/tools/{toolId}/text-description-overrideOverride the when-to-call description in text conversations
PUT/assistants/{id}/tools/{toolId}/steps/{stepId}/text-overrideOverride one step of the tool's text instructions
DELETE/assistants/{id}/tools/{toolId}/steps/{stepId}/text-overrideRestore one step of the tool's text instructions
DELETE/assistants/{id}/tools/{toolId}/text-overrideRemove 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.

bash
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:

Response data
{
  "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.

FieldTypeDescription
actionstringReplacement action text for this step. If omitted, the original action is kept.
additional_rulesstring[]Replaces the step's additional rules.
wait_for_responsebooleanWhether the assistant should wait for a caller response at this step. If omitted, the original value is kept.
_removebooleanSet 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:

bash
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:

Response data
{ "message": "…" }

To skip a step entirely for this assistant, send _remove on its own:

Terminal
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.

bash
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.

bash
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 textInstructionsA text conversation follows
YestextInstructions, with this assistant's text overrides applied
Noinstruction, 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:

bash
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_id values 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.