Settings reference
An agent’s configuration is one JSON document. GET /v1/agents/{agent} always returns it complete, with every default filled in; unknown fields are rejected. Edit it in the dashboard’s single-page editor or with a merge patch. The JSON Schema, with English and Arabic descriptions, is at GET /v1/agents/config_schema.
Limits on text are counted in characters (Unicode code points), so Arabic and English get the same room.
The whole document
Section titled “The whole document”A new agent’s configuration, with its defaults:
{ "locale": { "language": "en", "timezone": "Asia/Riyadh" }, "identity": { "enabled": false, "bot_name": "", "dialect": "match", "tone": "friendly", "persona_notes": "" }, "instructions": { "enabled": true, "text": "" }, "knowledge": { "sources": [] }, "tools": { "enabled": true, "builtin": { "transfer_to_human": { "enabled": true, "rules": "" }, "create_ticket": { "enabled": false, "rules": "" }, "flag_conversation": { "enabled": false, "rules": "" }, "search_knowledge": { "enabled": true, "rules": "" } }, "http": [], "client": [], "allow_anonymous_actions": false, "max_tool_rounds": 3 }, "guardrails": { "never_handle": { "enabled": true, "items": [ "Damage, injury or accident claims", "Legal threats, or mentions of lawyers, police or authorities", "Refund or compensation amounts", "Complaints that name an employee", "Requests for another customer's data" ] }, "escalation_reply": { "ar": "", "en": "" }, "business_scope": "" }, "handoff": { "ttl_hours": 24, "never_expire": false, "outside_hours": "record", "destinations": [{ "type": "desk" }], "notify": { "emails": [], "unclaimed_reminder_minutes": 10 }, "on_expire": "release_with_message", "expire_message": { "ar": "", "en": "" } }, "business_hours": { "enabled": false, "schedule": [ { "day": "sun", "open": "09:00", "close": "17:00" }, { "day": "mon", "open": "09:00", "close": "17:00" }, { "day": "tue", "open": "09:00", "close": "17:00" }, { "day": "wed", "open": "09:00", "close": "17:00" }, { "day": "thu", "open": "09:00", "close": "17:00" } ], "out_of_hours_message": { "ar": "", "en": "" }, "outside_hours_ai": "answer" }, "conversation": { "history_limit": 12, "idle_timeout_minutes": 30, "concurrency": "queue", "stream_mode": "auto" }, "model": { "provider": "openai", "model": "gpt-6-luna", "credential": "auto", "max_reply_tokens": 1024, "temperature": null, "fallback_models": [] }, "variables": [], "overrides": { "allowed": [], "models": [] }, "fallback": { "message": { "ar": "", "en": "" }, "handoff_on_failure": true }, "widget": { "greeting": { "ar": "", "en": "" }, "launcher_label": { "ar": "", "en": "" }, "theme": { "accent": "#0F766E", "position": "end" }, "anonymous_daily_conversations": 200 }}Texts in two languages
Section titled “Texts in two languages”Fields that customers read word for word are localized texts: an object {"ar": "…", "en": "…"}. K-Agent picks the language of the customer’s latest message (30% or more Arabic letters means Arabic), falling back to locale.language. A blank value uses the built-in default for that language, where one exists. Localized texts are guardrails.escalation_reply, fallback.message, handoff.expire_message, business_hours.out_of_hours_message, widget.greeting and widget.launcher_label.
Agent fields
Section titled “Agent fields”These sit beside the configuration, at the top level of the agent object.
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | — | Display name, required. |
slug |
string | from the name | URL name, ^[a-z0-9][a-z0-9-]{0,62}$, unique per project. Usable wherever {agent} appears. |
description |
string | "" |
For your team; never sent to the model. |
ai_paused |
boolean | false |
Stops AI replies at once. Not versioned; no If-Match needed; audited. |
actions_paused |
boolean | false |
Removes tools with side effects at once. Not versioned; audited. |
locale
Section titled “locale”| Field | Type | Default | Description |
|---|---|---|---|
language |
ar · en |
project’s language | The agent’s main language: the fallback for localized texts and the default widget direction. |
timezone |
IANA name | project’s time zone (Asia/Riyadh) |
Drives the agent’s clock, business hours, next_open_local and notices. Never the server’s time zone. |
identity
Section titled “identity”| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Turns the identity block on. When off it adds nothing to the prompt. |
bot_name |
string | "" |
The name the agent gives when asked who it is. |
dialect |
match · saudi · gulf · msa · english |
match |
The language and dialect of replies. match mirrors the customer. See Arabic dialect and tone. |
tone |
friendly · formal · brief |
friendly |
The register of replies. |
persona_notes |
string, ≤ 4,000 | "" |
Extra personality notes. {{variables}} allowed. |
instructions
Section titled “instructions”| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Off keeps the text but leaves it out of the prompt. |
text |
string, ≤ 20,000 | "" |
Your instructions: what the business does, how to answer, what to avoid. {{variables}} are rendered as clearly marked data. |
knowledge
Section titled “knowledge”| Field | Type | Default | Description |
|---|---|---|---|
sources |
array | [] |
{source_id, mode} items, in the order they appear in the prompt. mode is always (in the prompt) or searchable (behind search_knowledge). See Knowledge. |
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Master switch. Off removes every tool but keeps the grants below. |
builtin.transfer_to_human |
{enabled, rules} |
on | Hand the conversation to your team. |
builtin.create_ticket |
{enabled, rules} |
off | Open a ticket. |
builtin.flag_conversation |
{enabled, rules} |
off | Flag the session for review. |
builtin.search_knowledge |
{enabled, rules} |
on | Search the searchable knowledge. |
http |
array | [] |
{tool_id, rules} grants of HTTP tools. |
client |
array | [] |
{name, description, parameters, rules, effect} client tools. effect is read or action (default). |
allow_anonymous_actions |
boolean | false |
Let tools with side effects run for end users who are not verified. |
max_tool_rounds |
integer, 1–5 | 3 |
Model-and-tools rounds per turn before a final answer without tools. |
rules (every grant) is up to 4,000 characters and is added to that tool’s description as your company’s rules for it.
guardrails
Section titled “guardrails”| Field | Type | Default | Description |
|---|---|---|---|
never_handle.enabled |
boolean | true |
The never-handle block, placed last in the prompt. |
never_handle.items |
array of strings | 5 localized defaults | Situations the agent must hand over instead of answering. An emptied list stays empty. |
escalation_reply |
localized text, ≤ 500 each | empty | Sent word for word when a liability handoff succeeds. Empty means the agent words it itself; the dashboard suggests a text you can accept. |
business_scope |
string | "" |
One or two sentences on what this agent is for. |
None of these can be changed by per-request overrides. See Handoff and safety.
handoff
Section titled “handoff”| Field | Type | Default | Description |
|---|---|---|---|
ttl_hours |
integer, 1–720 | 24 |
How long an open handoff keeps the AI quiet. Claims and team messages extend it. 0 is rejected; use never_expire. |
never_expire |
boolean | false |
Keep handoffs open until someone resolves them. |
outside_hours |
record · withhold |
record |
Out of business hours, still record handoffs with honest wording (record), or remove transfer_to_human (withhold). |
destinations |
array | [{"type": "desk"}] |
Where agent handoffs go, in order: desk or webhook. Handoffs requested by the API, by policy or by your team always reach the Desk. |
notify.emails |
array of emails | [] |
Alert addresses for new and unclaimed handoffs (needs email to be configured on the server). |
notify.unclaimed_reminder_minutes |
integer | 10 |
When to send handoff.unclaimed for a handoff nobody has claimed. |
on_expire |
release_with_message · close |
release_with_message |
On expiry, give the conversation back to the agent with a notice, or close it. |
expire_message |
localized text | built-in default | The notice the customer sees when a handoff expires. |
business_hours
Section titled “business_hours”| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Tell the agent when your team is online. |
schedule |
array | Sun–Thu 09:00–17:00 | {day, open, close} with day in sun…sat and 24-hour HH:MM. A span with close ≤ open runs past midnight and belongs to its opening day. Days not listed are closed; enabled with an empty schedule means always open. |
out_of_hours_message |
localized text | built-in default | Used for handoffs out of hours, and sent as the whole reply with message_only. |
outside_hours_ai |
answer · message_only |
answer |
Out of hours, keep answering with AI, or send out_of_hours_message word for word with no AI call. |
Business hours use locale.timezone. When enabled, the agent is told whether your team is online now or when it is back.
conversation
Section titled “conversation”| Field | Type | Default | Description |
|---|---|---|---|
history_limit |
integer, 2–100 | 12 |
How many recent messages of the session the model sees. The window starts at a user message. |
idle_timeout_minutes |
integer | 30 |
Idle gap that starts a new segment. It never cuts history. |
concurrency |
queue · reject · interrupt |
queue |
Default policy for new API sessions. Widget sessions use interrupt. |
stream_mode |
auto · live · buffered |
auto |
live streams every token; buffered sends text per round; auto streams live unless an escalation reply is set, then buffers. |
| Field | Type | Default | Description |
|---|---|---|---|
provider |
openai · anthropic · deepseek · gemini · openai_compatible |
server default | The model provider. |
model |
string | server default | A model ID from GET /v1/models, which also shows each model’s tier, weight and whether your plan allows it. |
credential |
auto · platform · pcred_… |
auto |
auto uses the platform’s key for the provider if there is one, otherwise your project’s key for it. pcred_… pins one of your own provider keys (Settings → Model providers, or POST /v1/provider_credentials). |
max_reply_tokens |
integer | 1024 |
Budget for the visible reply per model call. Reasoning models get extra headroom on top automatically. |
temperature |
number or null |
null |
Sampling temperature, ignored for models that don’t accept one. |
fallback_models |
array | [] |
{provider, model} items tried in order when the main model fails. |
variables
Section titled “variables”Declare values your app passes per session or per message, then use them as {{name}} in instructions or persona notes:
{ "variables": [ { "name": "customer_name", "type": "string", "required": false, "default": "", "secret": false, "client_settable": true, "description": "First name, for greetings" }, { "name": "loyalty_tier", "type": "string", "required": false, "default": "standard", "secret": false, "client_settable": false, "description": "" }, { "name": "crm_token", "type": "string", "required": true, "default": "", "secret": true, "client_settable": false, "description": "Used by the order_status tool" } ]}| Field | Type | Default | Description |
|---|---|---|---|
name |
string | — | ^[a-z][a-z0-9_]{0,31}$. sys is reserved: {{sys.date}} and {{sys.end_user.name}} are built in. |
type |
string · number · boolean |
string |
Values are checked against it. |
required |
boolean | false |
A missing required variable returns 422 variable_missing; an undeclared one returns 422 variable_unknown. |
default |
same as type |
"" |
Used when no value is sent. Not allowed on secret variables. |
secret |
boolean | false |
Secret values are accepted only per request (ask, messages), are never stored, logged or shown to the model, and can be used only in HTTP tool headers as {{var.name}}. |
client_settable |
boolean | false |
Allow browsers (client tokens and the widget) to set this variable. Never for secrets. |
description |
string | "" |
For your team. |
Variables reach the model as clearly marked data, not as instructions.
overrides
Section titled “overrides”Overrides are denied by default. List the fields that may be changed for one ask call, or for a whole session with POST /v1/sessions and PATCH /v1/sessions/{session} (per-message overrides arrive in v1.1):
| Field | Type | Default | Description |
|---|---|---|---|
allowed |
array | [] |
Any of dialect, tone, instructions_append, temperature, model, tools_disable, history_limit (up to the configured value). |
models |
array | [] |
Models a request may switch to when model is allowed. |
Only secret keys can send overrides. never_handle, escalation_reply, tool grants and identity-bound tool access can never be overridden. Overriding anything that isn’t listed returns 422 override_not_allowed.
fallback
Section titled “fallback”| Field | Type | Default | Description |
|---|---|---|---|
message |
localized text | built-in default | What the customer sees when every model attempt fails. |
handoff_on_failure |
boolean | true |
Also hand the session to your team after a failure. |
widget
Section titled “widget”| Field | Type | Default | Description |
|---|---|---|---|
greeting |
localized text | built-in default | First message shown when the chat opens. |
launcher_label |
localized text | built-in default | Text on the launcher button. |
theme.accent |
color | #0F766E |
Accent color of the widget. |
theme.position |
start · end |
end |
Corner of the launcher; follows the page direction (end is bottom-right in English, bottom-left in Arabic). |
anonymous_daily_conversations |
integer | 200 |
Daily cap of anonymous widget conversations for this agent. |
The widget reads only bot_name, language, direction, greeting, launcher_label and theme from the published version.