agents
agent.handoff
Agent Handoff
Effects: read
Delegate a multi-step task (research, composing messages, booking, scheduling) to the full agentic planner. Use when a user ask needs more than a direct answer. The specialist runs synchronously — its response is already shown to the user in real-time. Summarize the OUTCOME in past tense (e.g. 'The Media Creator generated your video' or 'The Document Composer failed because...'). Do NOT say 'I will delegate' — the delegation already happened. If status is timeout or error, explain what went wrong and offer to retry.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | no | Optional ID of another agent in the same workspace to delegate the task to. When set, this becomes cross-agent delegation; the target agent runs with ITS OWN prompt, tools, and model. Use this for specialty tasks (see agents.list to discover specialists). Prefer the in-loop variant (no agent_id) for one-off escalations. Spawns a new trace linked back to this trace via parent_trace_id (visible in the admin lineage card). |
mode | string | no | Execution mode: 'sync' (wait for result, default) or 'async' (fire and forget, child runs in background). Async is only available in background/trigger context. (one of sync, async; default sync) |
payload | object | no | Optional structured data for the target agent. For a rule_based (script) target this becomes the script's inputs['raw_data'] verbatim — pass the exact fields its script reads (same contract as the trigger event that script normally handles). For LLM targets it is appended to the task text as a [PAYLOAD] JSON block. VOICE callers: the voice pipeline's strict schemas seal free-form objects, so from a live call put the data in task_description instead — script targets receive it as inputs['message_text']. |
target_slug | string | no | Optional stable slug of a system-template specialist to delegate to (e.g. 'doc-composer' for the Document Composer). Env-portable alternative to agent_id — resolves the workspace's fork of that template (auto-forking on first use). Used by async handoffs that target a specialist without knowing its per-workspace id. |
task_description | string | yes | Plain-language description of what the planner should accomplish. Include everything the planner needs: the user's goal, constraints, and any context already gathered in this voice call. |
agent.silence
Agent Silence
Effects: read
End this turn without sending any message. Use when the thread is owned by a human operator after job.escalate, when the guest is self-resolving, when the message is a duplicate, or for observation-only turns. Calling this tool is the ONLY correct way to stay silent — narrated silence text (e.g. '(Staying silent…)', 'Internal:…') would be delivered to the guest verbatim.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
reason | string | yes | Free-form explanation for admin audit. Stored in trace_tool_executions.tool_params (ClickHouse String; reason filters are scan-only). |
agents.activity
Agent Activity
Effects: read
See what you — or another agent in your workspace — actually did over a time window: messages sent, documents created, calls made, plus a summary (run counts, per-day, top tools). Use this to answer 'what did I do today / yesterday / last week / in the last hour?' or 'what did <agent> do?' with real data instead of guessing.
Omit agent for your own activity, or pass another workspace agent's name, slug, or id. Pass since/until as ISO datetimes (e.g. '2026-06-03T09:00:00') for sub-day windows like the last hour, or plain dates ('2026-06-03') for whole days — compute them from the current date/time you were given. Defaults to the last 24h. Traces are retained 30 days.
Times are interpreted as UTC — if the current time you were given is in another timezone, convert to UTC before passing since/until.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent | string | no | Target agent: name, slug, or numeric id. OMIT for yourself. |
limit | integer | no | Max actions / recent runs to return. (default 50; min 1.0; max 200.0) |
since | string | no | Window start — ISO datetime or date. OMIT for last 24h. |
until | string | no | Window end — ISO datetime or date (exclusive day-end for a bare date). OMIT for now. |
agents.add_file
Add File to Agent
Effects: write
Attach a file to this agent's private knowledge (agent-specific files, not shared with other agents).
Workflow:
- Upload the file with files_upload (pass source_url for remote files)
- Index it with files_ingest (pass the file_id)
- Call this tool with agent_id + file_id
Returns chunk_count — shows 0 while still processing. Call agents.list_files later to see the final chunk count once indexing completes.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to attach the file to |
file_id | integer | yes | file_id returned by files_upload or files_ingest |
agents.approve_draft
Approve Agent Draft
Effects: send
Approve a pending agent draft and send the message.
The draft will be sent to the conversation it was generated for.
You can optionally edit the text before sending.
Use this when user says:
- 'Approve this draft'
- 'Send this reply'
- 'Approve and send'
- 'Looks good, send it'
IMPORTANT: This will send a message to a real person.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
draft_id | integer | yes | ID of the draft to approve |
edited_text | string | no | Optional edited response text (if user wants to modify before sending) |
agents.ask
Ask AI Agent
Effects: write
Send a message to an AI agent and get its response.
The agent runs with its configured prompt, tools, and knowledge.
Use this to test agents or have them process a task.
Returns: {status: 'replied'|'silent', response_text, messages[], full_reply, model_used, tokens_*, send_mode, execution_mode, tool_calls[]}. tool_calls[] is the per-tool trace in call order — each {tool, success, error, duration_ms} — so you can see which tool the agent ran and why it failed (e.g. a workbench script error) directly from this response, no trace lookup needed. messages[] carries each messages.send invocation the agent made (text, subject, reply_to_message_id, timestamp, message_id, attachments=[{file_id,name,mime}]). full_reply concatenates text only — attachment-only sends show up in messages but not full_reply. status='silent' iff both response_text is empty AND messages is empty.
Execution may take 10-60s depending on agent complexity. For runs that may exceed ~2 minutes (heavy multi-step agents), pass background=true: the call returns immediately with status='started' and the run continues server-side, detached from this connection — poll agents.traces_list / agents.trace_get for the outcome and agents.list_drafts for produced drafts.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the AI agent to ask |
background | boolean | no | Run detached from this MCP connection. Returns immediately with status='started'; the run survives client timeouts and disconnects (up to 15 min). Poll agents.traces_list for the outcome. Use for runs expected to exceed ~2 minutes — a synchronous call is cancelled when the MCP request dies. OMIT to run synchronously and get the answer in this call (the default). |
message | string | yes | Message/goal to send to the agent |
send_mode | string | no | Send mode for the agent run: 'draft' = create drafts, 'auto' = send directly. Defaults to the agent's configured default_send_mode. Does NOT change execution_mode — that is fixed by the agent's config. |
agents.create
Create AI Agent
Effects: write
Create a new AI agent in the workspace.
Execution modes:
- ai_assisted (default): Two-phase AI — fast pre-classifier (Haiku) for keyword filtering and simple replies, then full AI with tools for complex messages.
- agentic: Autonomous multi-step agent with planning and tool execution.
- rule_based: Simple pattern matching without AI.
Keyword filtering is available in ai_assisted mode via keywords in trigger conditions (free, deterministic) and/or auto_reply_rules (LLM-based) set through agents.update.
From a template: pass template (e.g. 'dm-auto-reply') to create the agent AND its built-in trigger in one call — deterministic, no need to add a trigger separately. Pass prompt_text for the agent's persona (stored inline). When template is set, name/text_engine/send_mode come from the template.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
allowed_tools | array | no | Explicit allow-list of tool IDs the agent may call on triggered runs (e.g. ['workbench.run_python', 'messages.send']). OMIT to use system defaults. Applied right after creation. |
description | string | no | Optional description of what this agent does |
max_iterations | integer | no | Hard cap on agentic-loop turns per run (1-50). OMIT for the default (10). |
model | string | no | LLM the agent runs on. OMIT to use the platform default (deepseek-v4-flash-nothink). Applied right after creation so you don't need a follow-up agents_update. (one of claude-haiku-4-5-20251001, claude-opus-4-6, claude-sonnet-4-6, claude-sonnet-5, deepseek-v4-flash, deepseek-v4-flash-nothink, gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, gpt-4o, kimi-k2.6, qwen-flash, qwen-plus, qwen3-vl-flash, qwen3-vl-plus, qwen3.6-flash, qwen3.6-plus) |
name | string | yes | Name of the AI agent (1-100 characters) (min length 1; max length 100) |
prompt_id | integer | no | ID of the prompt to assign to this agent |
prompt_text | string | no | Only with template: the agent's persona/instructions, stored inline on the agent (drives how it replies). No separate prompts tool needed. |
send_mode | string | no | Default send mode: 'auto' or 'draft'. OMIT to use 'draft' (the default). (one of auto, draft) |
template | string | no | Optional template slug to instantiate the agent + its built-in trigger from (deterministic). Use 'dm-auto-reply' for the customer DM auto-reply agent (incoming DM trigger, draft mode). When set, the trigger comes from the template — you don't need agents.trigger_create. OMIT to create a plain agent (no template). (one of dm-auto-reply) |
text_engine | string | no | Text-execution engine: 'rule_based', 'ai_assisted', 'agentic' (default), or 'claude_channels'. Voice is derived from triggers, not engine. OMIT to use the default ('agentic'). (one of rule_based, agentic, claude_channels) |
agents.delete
Delete AI Agent
Effects: write
Permanently delete an AI agent.
WARNING: This cannot be undone. The agent and all its triggers will be removed.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to delete |
agents.get
Get AI Agent
Effects: read
Get detailed information about a specific AI agent.
Returns full agent config including:
- Execution configuration
- Tool configuration
- Knowledge configuration
- Escalation configuration
- Triggers list
- Knowledge collections
- Custom AI instructions (prompt_text)
- Auto-reply rules override (auto_reply_rules)
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the AI agent to fetch |
agents.list
List AI Agents
Effects: read
List all AI agents configured in the workspace.
Returns agents with their basic info, trigger count, and knowledge collection count.
Each agent's description field tells you when that agent is useful. If you're a router-style agent deciding whether to delegate via agent.handoff, read descriptions and pick the best fit.
Use this to:
- See all configured AI agents
- Filter by status (active/paused/archived)
- Get agent IDs for further operations
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
status | string | no | Filter by status ('active' / 'paused' / 'archived'). Omit for all. (one of active, paused, archived) |
agents.list_drafts
List Agent Drafts
Effects: read
List pending agent drafts awaiting approval.
Shows drafts that have been generated by AI agents but not yet sent.
Each draft includes:
- Thread/conversation info
- Trigger message (what prompted the reply)
- Generated response text
- Creation time and expiration
Use this when user asks:
- 'Show pending agent drafts'
- 'What messages are waiting for approval?'
- 'List drafts to approve'
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
limit | integer | no | Maximum number of drafts to return (default 20; min 1.0; max 100.0) |
thread_id | string | no | Filter by specific thread ID (optional) |
agents.list_files
List Agent Files
Effects: read
List files directly attached to this agent (agent-specific files, not shared collections).
Returns file_id, title, status, and chunk_count for each file.
chunk_count shows how many indexed chunks were created — 0 means the file is still processing.
Use agents.add_file to attach a new file, or agents.remove_file to detach one.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent whose files to list |
agents.list_integrations
List Agent Integrations
Effects: read
List the workspace integrations enabled (or available) for an AI agent, with each one's workspace_integration_id, provider, enabled flag, and count of denied tools. Use this to see what an agent can call before toggling with agents_set_integration.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to inspect |
agents.prompt_history
Agent Prompt History
Effects: read
List past versions of an agent's prompt_text. Every edit to the agent's prompt is snapshotted to an append-only table — use this tool to browse history, find a prior known-good version, and copy it into agents.prompt_restore.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent |
before_version | integer | no | Cursor: return versions strictly below this version_number (min 1.0) |
limit | integer | no | Max versions to return (1-200, default 50) (default 50; min 1.0; max 200.0) |
agents.prompt_restore
Restore Agent Prompt
Effects: write
Restore a past version of an agent's prompt_text by version_number. Creates a new version pointing at the restored content — history is preserved. Use agents.prompt_history first to find the version_number you want.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent |
reason | string | no | Optional: why this restore is happening (shows up in history UI) |
version_number | integer | yes | The version_number to restore (get it from agents.prompt_history) (min 1.0) |
agents.reject_draft
Reject Agent Draft
Effects: write
Reject a pending agent draft without sending.
The draft will be marked as rejected and won't be sent.
Use this when the generated response isn't appropriate.
Use this when user says:
- 'Reject this draft'
- 'Don't send this'
- 'Cancel this reply'
- 'Delete this draft'
- 'This response is wrong'
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
draft_id | integer | yes | ID of the draft to reject |
reason | string | no | Optional reason for rejection (for logging/feedback) |
agents.remove_file
Remove File from Agent
Effects: write
Remove a file from this agent's private knowledge.
The file itself is not deleted — it's just detached from this agent.
Use agents.list_files to find the file_id to remove.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to remove the file from |
file_id | integer | yes | ID of the file to detach (from agents.list_files) |
agents.set_integration
Set Agent Integration
Effects: write
Enable or disable a connected workspace integration on an AI agent — this controls which ext<id>_<name> integration tools the agent (and its sandboxed workbench runs) may call. Use integrations_list to get the workspace_integration_id.
When enabling with no explicit denied_tools, WRITE-class tools are auto-disabled by default (read tools stay on); pass denied_tools=[] to force-allow everything, or a list of ext slugs / bare tool names to block specific ones. Idempotent upsert — safe to call repeatedly.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to configure |
denied_tools | array | no | Optional explicit block-list of tool names to deny (ext slugs or bare names). Omit to auto-deny WRITE-class tools on first enable; pass [] to allow all. |
enabled | boolean | no | True to enable the integration on this agent, False to disable (default True) |
workspace_integration_id | integer | yes | ID of the connected integration (from integrations_list) |
agents.simulate_inbound
Simulate Inbound Message
Effects: read
Replay an inbound message on a thread through the real trigger pipeline and return what would have happened. The router auto-picks the winning enabled agent + trigger by priority/specificity (same logic as production). By default send_mode='draft' so no real message is sent; pass send_mode='auto' on a test account to let the matched agent actually deliver (drafts get overwritten by the next draft, so 'auto' is the only way to verify Telegram/email delivery end-to-end).
Use to verify routing for a thread: which agent answers, which trigger wins, or — when nothing matches — the structured skip reason. Pass blockchain_tx_data instead of message_text to simulate a blockchain:transfer event on the thread.
Returns: {matched: true, matched_agent: {id, name, execution_mode}, matched_trigger: {id, trigger_type, conditions, specificity_score}, routing_reason, response_text, messages[], execution_mode, send_mode, model_used, tokens_input, tokens_output, latency_ms, } on a hit, or {matched: false, skip_reason, simulator_warnings} on a miss.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
attachment_file_ids | array | no | Optional list of workspace file IDs to attach to the simulated inbound message — same shape as a real Telegram message with image/document attachments. Use this to test agent behavior on incoming messages that carry images (e.g. logos for invoices) or documents the agent must reference. File IDs must belong to the API key's workspace. |
blockchain_tx_data | object | no | When set, simulate a blockchain:transfer event instead of a channel:message:new event. Expected keys: chain, to_address / from_address, tx_hash. |
channel_account_id | integer | no | Optional. The livechat widget's channel_account_id to host the fresh chat when create_new_livechat=true. Omit to auto-pick the workspace's active livechat widget. |
create_new_livechat | boolean | no | Start a FRESH, history-free livechat chat instead of using an existing thread_id — creates a new visitor + thread on the workspace's livechat widget and routes your message onto it. The response's thread_id is the new thread; pass it back (with send_mode='auto') to continue the conversation. Ideal for clean multi-turn text tests. OMIT to reuse an existing thread_id. Ignored if thread_id is given. |
message_text | string | no | Inbound message body to simulate. Defaults to '[MCP simulation test]' when omitted. |
send_mode | string | no | How the matched agent should deliver its reply. 'draft' (default, safe) creates a draft only — no real send, no idempotency key. 'auto' lets the agent deliver through the channel adapter exactly as it would in production — use this on a test account to verify Telegram/email delivery end-to-end. Drafts get overwritten by the next draft on the thread, so 'auto' is required when you want to see the message persisted. (one of draft, auto; default draft) |
system_message | object | no | Tag the simulated inbound as a system/service-message row (missed call, group join, pinned message, etc.) so the excluded_system_message_kinds trigger filter can be exercised end-to-end. Shape: {"category": <one of call_event | membership_change | contact_signup | pinned_message | chat_metadata_change | voice_chat_event | other_service>, "native_kind": <free-form upstream event class name, e.g. 'MessageActionPhoneCall'>}. The category is written into message.meta.system_message (mirroring the real Telegram ingest path) AND surfaced on the synthetic IncomingEvent so the trigger evaluator honors the block-list. Omit for a normal text-message simulation. |
thread_id | integer | no | Thread ID to route the simulated event from. Must belong to the API key's workspace. Omit and set create_new_livechat=true to test on a FRESH thread with no history. |
agents.task_complete
Report Agent Task Completion
Effects: write
Report that a Claude Code agent task has been completed. Call this when you finish processing an agent_task from DialogBrain.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
success | boolean | yes | Whether the task completed successfully |
summary | string | no | Brief summary of what was done |
trace_id | string | yes | Trace ID from the agent task event |
agents.trace_get
Get Agent Trace Detail
Effects: read
Fetch the full execution detail for a single trace — tool executions, events timeline, LLM call spans (with error_message on failures), and what the run cost.
cost_usd is the run's billed cost in USD, recorded even when the workspace pays with its own vendor key; 0 means nothing billable was recorded, null means the lookup could not run. Per-token detail is on each LLM span (input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens).
Use after agents.traces_list identifies a specific trace of interest (failed run, slow run, unexpected outcome).
By default LLM system_prompt and prompt_messages are stripped — set include_llm_bodies=true to fetch them when diagnosing prompt engineering issues (emits a WARNING audit log). Set full=true to disable all field truncation. completion_text on failed LLM calls is always returned (capped at 8 KB).
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | Expected agent_id — used for scope validation. Mismatch returns not_found. |
full | boolean | no | Disable all field truncation. Escape hatch for a human operator. OMIT for the standard truncated view. |
include_llm_bodies | boolean | no | Include system_prompt and prompt_messages in LLM spans. Audited at WARNING level. OMIT to keep them stripped (the default). |
trace_id | string | yes | Trace identifier returned by agents.traces_list. |
agents.traces_list
List Agent Traces
Effects: read
List recent execution traces for an agent — the same data as /admin/requests, scoped to one agent and readable by an LLM.
Use this when an agent call timed out, drafted the wrong response, or you want to know which tool/LLM call burned the latency. Pair with agents.trace_get for full detail on a specific trace.
Filters: status, success, source (single value or comma-separated: agent,voice), date_from/date_to (ISO-8601), pagination via limit/offset.
Returns returned_count, dropped_on_page (should be 0 — positive means the backend agent_id predicate let something through), and has_more. Edge case: a raw page of all-dedup-dropped rows yields returned_count=0, has_more=true; re-call with offset += limit.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | Agent ID to pull traces for (must belong to your workspace). |
date_from | string | no | ISO-8601 lower bound on created_at, e.g. '2026-04-10T00:00:00Z'. |
date_to | string | no | ISO-8601 upper bound on created_at. |
limit | integer | no | Max rows per page (1–100). (default 20; min 1.0; max 100.0) |
offset | integer | no | Rows to skip for pagination. OMIT to start at row 0 (default). (min 0.0) |
source | string | no | Filter by trace source. Single value or comma-separated, e.g. 'agent,voice'. Values: agent / auto_reply / agentic / outreach / voice. Note: source='agent' also matches voice traces today (known upstream bug). |
status | string | no | Filter by status. OMIT to include all statuses. (one of pending, executing, completed, failed, cancelled) |
success | boolean | no | Filter to succeeded (true) or failed (false) runs only. OMIT to include both. |
agents.traces_stats
Get Agent Trace Stats
Effects: read
Aggregated trace statistics for one agent over the last N days — total runs, success rate, avg duration, error breakdown, top tools used, runs-per-day histogram, and what the agent spent.
spend totals the agent's LLM usage over the same window: llm_calls, tokens_input, tokens_output, cost_usd, and own_key_cost_usd (the slice paid with the workspace's own vendor key, included in cost_usd rather than added to it). It covers usage recorded since per-agent attribution shipped, so it reads 0 for older runs; null means the lookup could not run.
Use this when you want a bird's-eye view of an agent's health before diving into individual traces with agents.traces_list / agents.trace_get. Scoped to the target agent (exact match, no substring bleed). days is capped at 30 — matches the ClickHouse request_traces TTL.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | Agent ID to compute stats for (must belong to your workspace). |
days | integer | no | Rolling window in days (1–30). (default 7; min 1.0; max 30.0) |
agents.trigger_create
Create Agent Trigger
Effects: write
Create a new trigger for an AI agent.
Triggers determine when the agent activates.
Trigger types:
- incoming_message: Activates on new incoming messages
- schedule: Activates on a schedule
- webhook: Activates on webhook events
- event: Activates on system events
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to create a trigger for |
blocked_sender_ids | array | no | Never react to these senders/callers, by their channel-side id — a phone number, a WhatsApp JID, a Telegram user id, an email address. Explicit deny: it beats every allow-list, and it applies to ALL trigger types, including incoming_call, so it is how you stop an agent answering one nuisance caller without silencing it for everybody. Phone-shaped ids are matched by their digits, so '+998901234567', '998901234567' and '998901234567@s.whatsapp.net' are the same person. Maps to conditions.sender_filter.excluded_external_ids. |
conditions | object | no | Trigger conditions (JSON). Supported fields for incoming_message: - keywords: ["pricing","demo"] — message must contain keyword(s) (free, no LLM cost) - keyword_match: "any" (default, OR) or "all" (AND) - channel_types: ["telegram","whatsapp","livechat_voice","twilio_voice","telegram_voice","voice",...] — filter by channel. For voice, use EITHER the three per-channel keys (scoped) OR "voice" alone (wildcard matching all three) — mixing them is redundant. Per-channel keys: "livechat_voice" (web widget), "twilio_voice" (PSTN inbound), "telegram_voice" (Telegram p2p calls) - context_types: ["dm","group","channel","livechat"] — filter by chat type - group_mode: "mentions_only" or "questions" — for group chats - channel_account_ids: ["123"] — restrict to specific accounts - folder_ids: [5,10] — restrict to threads in folders - ai_tag_ids: [1,2] — restrict to threads with AI tags - ai_filter_ids: [1,2] — semantic intent filters (message matched via embedding similarity, works in noisy groups) - ai_filter_mode: "any" (default, OR) or "all" (AND) — how multiple AI filters combine - ai_filters: [{id: 1}, {name: "...", description: "..."}] — shorthand: reference existing by id or create inline (calls Voyage embedding API). If a filter with the same name already exists, it is reused by id. Prefer referencing existing filters by id when available. Use ai_filters.create + ai_filters.test for fine-tuning before assigning. - contact_states: ["active"] — filter by contact state - cooldown_seconds: 30 — min gap between runs per thread - max_runs_per_thread_per_hour: 5 — rate limit - answer_delay_s: 15 — voice pickup only (incoming_call, or incoming_message scoped to a voice channel). Ring the human's own devices this long before the agent answers; if they pick up, the agent stands down. 0/absent = answer immediately. Honoured on WhatsApp and Telegram 1:1 — other voice channels have nothing ringing to wait for and still answer at once. - auto_join: true|false — voice pickup, GROUP calls only. Whether the bot enters a matching group call on its own (true) or the call becomes a pending invite an operator accepts (false). OMIT THE KEY to defer to the channel setting (channel_account.state.voice_auto_join_policy, default 'approval'); resolution is trigger-when-present, then channel, then approval, so an explicit false beats a channel set to auto. Absent and false are different answers. - chat_ids: ["-5172634473"] — voice pickup, Telegram GROUP calls only. Scopes the trigger to specific groups; omit for every group call. Any id spelling works (5172634473, -5172634473, -1005172634473 are the same group). A call whose chat is unknown never satisfies it, so do NOT set this together with 1:1 / Twilio / Telnyx / WhatsApp / Android / LiveChat voice channels or the "voice" wildcard: those calls have no chat and the trigger would stop answering them. Supported fields for job_completed (proactive callback when a delegated job finishes): - source_agent_id: <int> — fire only when this agent's job completed - source_agent_slug: <str> — alternate to source_agent_id - job_type: "agentic_session" — match a specific job type (default: any) - outcome: ["completed"] | ["escalated"] | ["completed","escalated"] — default ["completed"] - min_duration_seconds: <int> — skip very-short jobs (noise filter) - thread_filter: {thread_ids: [<int>...]} — restrict to specific threads Supported fields for calendar_event (fires N minutes before a Google Calendar event starts): - window_minutes_before: <int 1-1440> — REQUIRED, fire when an event starts within this window - channel_account_ids: [<int>...] — restrict to specific calendar accounts (default: all) - keywords: ["standup"] — word-boundary match on event title - prepare_meet_join: true — pre-invite pool bots to the event (enables unattended Meet join) incoming_message action fields: - action: "reply_text" (default, normal agent run) or "join_voice" (deterministically join the voice channel resolved from the message — requires send_mode=auto) - message_source: "real" (default) | "transcript" | "both" — real messages vs turns during a live call. Transcripts are turns that address the agent. calendar_event run-mode field (incoming_message uses action instead): - run_mode: "text" (default) or "voice" (join the meeting — requires send_mode=auto) - voice: {speak_first: <bool — greet immediately vs stay silent until addressed>, vision_mode: "off"|"on_demand"|"continuous_0_3fps"} — pairs with action=join_voice (incoming_message) or run_mode=voice (calendar_event) |
enabled | boolean | no | Whether the trigger is enabled. OMIT to use the default (true). |
excluded_thread_ids | array | no | Exclude specific threads (chats) by their numeric thread IDs — the opposite of thread_ids. When set, the trigger NEVER fires for messages in these threads, even if thread_ids would otherwise allow them (explicit deny wins). Only for incoming_message and job_completed triggers. Maps to conditions.thread_filter.excluded_thread_ids. |
priority | integer | no | Trigger priority — lower numbers run first (default: 100) |
send_mode | string | no | Send mode override for this trigger. OMIT to inherit from the agent. (one of auto, draft) |
thread_ids | array | no | Restrict this trigger to specific threads (chats) by their numeric thread IDs. When set, the trigger only fires for messages in these threads. Only for incoming_message and job_completed triggers. Maps to conditions.thread_filter.thread_ids. |
trigger_type | string | yes | Type of trigger: 'incoming_message', 'incoming_call', 'schedule', 'webhook', 'event', 'blockchain_event', 'job_completed', 'calendar_event', or 'lead_captured' (one of incoming_message, incoming_call, schedule, webhook, event, blockchain_event, job_completed, calendar_event, lead_captured) |
agents.trigger_delete
Delete Agent Trigger
Effects: write
Delete a trigger from an AI agent.
WARNING: This cannot be undone.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent that owns this trigger |
trigger_id | integer | yes | ID of the trigger to delete |
agents.trigger_update
Update Agent Trigger
Effects: write
Update an existing AI agent trigger.
All parameters are optional — only provided fields will be updated.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent that owns this trigger |
blocked_sender_ids | array | no | Never react to these senders/callers, by their channel-side id — a phone number, a WhatsApp JID, a Telegram user id, an email address. Explicit deny: it beats every allow-list, and it applies to ALL trigger types, including incoming_call, so it is how you stop an agent answering one nuisance caller without silencing it for everybody. Phone-shaped ids are matched by their digits, so '+998901234567', '998901234567' and '998901234567@s.whatsapp.net' are the same person. Empty list [] = unblock everyone (the allow-list, if any, is left alone). Maps to conditions.sender_filter.excluded_external_ids. |
conditions | object | no | New trigger conditions (replaces existing). Same fields as trigger_create: keywords, keyword_match, channel_types, context_types, group_mode, channel_account_ids, folder_ids, ai_tag_ids, ai_filter_ids, ai_filter_mode, ai_filters: [{id: 1}, {name: "...", description: "..."}] — shorthand: reference existing by id or create inline (calls Voyage embedding API). If a filter with the same name already exists, it is reused by id. contact_states, cooldown_seconds, max_runs_per_thread_per_hour. incoming_call (voice pickup): answer_delay_s, plus auto_join and chat_ids for GROUP calls — auto_join true|false decides whether the bot enters on its own or the call becomes a pending invite, and OMITTING the key defers to the channel setting (trigger-when-present, then channel, then approval; absent and false are different answers). chat_ids scopes to specific Telegram groups (any id spelling) and must not be combined with channels whose calls have no chat, which never satisfy it. Conditions are REPLACED, so dropping a key clears it. calendar_event: window_minutes_before (1-1440, required), channel_account_ids, keywords, prepare_meet_join. incoming_message: action "reply_text"|"join_voice" (join requires send_mode=auto), message_source "real"|"transcript"|"both". calendar_event: run_mode "text"|"voice" (voice requires send_mode=auto). Both: voice: {speak_first, vision_mode} |
enabled | boolean | no | Enable or disable this trigger. OMIT to leave the enabled flag unchanged. |
excluded_thread_ids | array | no | Exclude specific threads (chats) by their numeric thread IDs — the opposite of thread_ids. When set, the trigger NEVER fires for messages in these threads (explicit deny wins). Merged into conditions.thread_filter.excluded_thread_ids. Only for incoming_message and job_completed triggers. |
priority | integer | no | Trigger priority — lower numbers run first |
send_mode | string | no | New send mode override. OMIT to leave the send-mode unchanged. (one of auto, draft) |
thread_ids | array | no | Restrict this trigger to specific threads (chats) by their numeric thread IDs. When set, merged into conditions.thread_filter.thread_ids. If conditions is also provided, thread_ids is merged into it. Only for incoming_message and job_completed triggers. |
trigger_id | integer | yes | ID of the trigger to update |
trigger_type | string | no | New trigger type. OMIT to keep the existing type unchanged. (one of incoming_message, incoming_call, schedule, webhook, event, blockchain_event, job_completed, calendar_event, lead_captured) |
agents.update
Update AI Agent
Effects: write
Update an existing AI agent's configuration.
All parameters are optional — only provided fields will be updated.
Use this to:
- Enable or disable an agent
- Change agent name or description
- Assign or detach a prompt
- Change default send mode
- Replace knowledge collections
- Update agent status
- Change agent priority for trigger matching (lower number = higher priority)
- Override which tools the agent can/can't call on triggered runs
- Override which context sections (situation, communication style, job state, conversation history, thread summary) the agent receives
- Opt into boilerplate prompt sections (safety guidelines, data confidentiality, factual accuracy) — all default OFF
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the agent to update |
allowed_tools | array | no | Explicit allow-list of tool IDs this agent can call on triggered runs (e.g. ['messages.send', 'agent.handoff']). Empty list [] = clear the allow-list and fall back to system defaults. When set, only these tools (minus denied_tools) are exposed to the agent. Does NOT affect the My AI dropdown path. |
api_surface | string | no | OpenAI HTTPS endpoint for this agent's LLM calls (Phase 3a). 'chat_completions' (default, also when null) routes to /v1/chat/completions. 'responses' routes to /v1/responses — required for OpenAI native server tools (web_search, code_interpreter, image_generation, input_file PDFs). Capability still wins: agents whose tool list triggers the server_tool_responses_api substitution always route to Responses regardless of this setting. Ignored on non-OpenAI models (Anthropic, DeepSeek, Moonshot). OMIT to leave the api_surface unchanged. (one of chat_completions, responses) |
auto_reply_rules | string | no | Plain-English rules injected into the fast model's system prompt as a ## Rules block. No reserved keywords — the fast model reads them as guidance and decides per turn whether to reply directly or escalate to the main model for tools. Example: '- If the user greets, reply "Hi! How can I help?"\n- If the user asks what you can do, reply with a 1-sentence summary\n- If the question needs live data (prices, stock, booking), escalate' Engagement filtering (SKIP) belongs in trigger conditions (keywords, ai_filters, channel_types, cooldown), NOT here — if a message should be ignored the trigger shouldn't have fired. Pass null to clear. |
default_calendar_id | string | no | Default Google calendar_id applied at the TOOL layer whenever this agent calls a calendar tool without an explicit calendar_id (e.g. 'c_...@group.calendar.google.com'). Use for agents whose bookings must always land on one dedicated calendar — a prompt-only rule is advisory and the model occasionally drops the param. An explicit calendar_id in a tool call still wins. Pass an empty string to clear (falls back to 'primary'). OMIT to leave unchanged. |
denied_tools | array | no | Block-list of tool IDs the agent must not call on triggered runs. Applied after allowed_tools and default visibility. Empty list [] = clear the block-list. |
description | string | no | New description for the agent |
fast_model | string | no | Model for the fast-path responder (voice, text auto-reply, agent executor). Defaults to deepseek-v4-flash-nothink when unset. Non-Anthropic models (deepseek-v4-flash-nothink, gpt-4.1-nano, kimi-k2.6) do NOT use BYOK today — they use the system API key + credits. Pass null to revert to default. |
fast_prompt_override | string | no | Full fast-path prompt override. Placeholders substituted via .replace(): {message}, {history}, {rules}, {tools}, {output_contract}. agent.prompt_text is NOT injected into fast_prompt_override — include it yourself if you want it. Pass null to clear. |
include_conversation_history | boolean | no | Include recent messages from this thread (up to 20) in the agent's prompt. OMIT to leave this flag unchanged. |
include_data_confidentiality | boolean | no | Inject the Data Confidentiality block (~250 tokens, cross-contact PII isolation + prompt-injection defense) into the system prompt. Default OFF. Agentic mode only. OMIT to leave this flag unchanged. |
include_factual_accuracy | boolean | no | Inject the Factual Accuracy block (~100 tokens, generic anti-hallucination rules) into the system prompt. Default OFF — skip if you write domain-specific accuracy rules in Instructions. Agentic mode only. OMIT to leave this flag unchanged. |
include_job_state | boolean | no | Include current job state (active job context, tasks, notes) in the agent's prompt. OMIT to leave this flag unchanged. |
include_learned_style | boolean | no | Include learned communication style (per-contact tone, dormancy state) in the agent's prompt. OMIT to leave this flag unchanged. |
include_safety_guidelines | boolean | no | Inject the generic Safety Guidelines block (~80 tokens) into the system prompt. Default OFF — enable only if you don't already write safety rules in your Instructions. Agentic mode only. OMIT to leave this flag unchanged. |
include_situation | boolean | no | Include situation context (channel, sender info, trigger type) in the agent's prompt. OMIT to leave this flag unchanged. |
include_specialists | boolean | no | Inject a [SPECIALISTS] block (~50–200 tokens) listing the workspace's delegation-capable agents so a router-style agent can pick a handoff target without first calling agents.list. Default OFF for new agents; the Router template ships with this ON. Agentic mode only. OMIT to leave this flag unchanged. |
include_thread_summary | boolean | no | Include condensed summary of older thread messages in the agent's prompt. OMIT to leave this flag unchanged. |
include_tool_call_history | boolean | no | Include the agent's own tool calls and results from the last 3 runs on this thread, compacted to IDs + top hits (~200-1000 tokens). Lets the agent recall file IDs, search hits, and decisions it already made across turns. Default ON. Agentic mode only. OMIT to leave this flag unchanged. |
knowledge_collection_ids | array | no | Replace all knowledge collections with these IDs (empty list = clear all) |
max_iterations | integer | no | Hard cap on agentic-loop turns (LLM round-trips) per run, 1-50 (default 10). Each turn can call tools; the loop stops when the model replies with no tool call OR this cap is hit. Raise it for multi-step tool chains (e.g. browser automation: open → snapshot → fill → confirm → reply) that otherwise exhaust their turns before producing a final answer. OMIT to leave it unchanged. (min 1.0; max 50.0) |
model | string | no | Canonical source for which LLM the agent runs on. To switch models pass JUST this — do NOT also rewrite prompt_text (any 'duty model' section in the prompt is stale doc, not the config). OMIT to leave the model unchanged. (one of claude-haiku-4-5-20251001, claude-opus-4-6, claude-sonnet-4-6, claude-sonnet-5, deepseek-v4-flash, deepseek-v4-flash-nothink, gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, gpt-4o, kimi-k2.6, qwen-flash, qwen-plus, qwen3-vl-flash, qwen3-vl-plus, qwen3.6-flash, qwen3.6-plus) |
name | string | no | New name for the agent |
native_web_search | boolean | no | Whether this agent may use the model provider's built-in web search (Anthropic, OpenAI) instead of the platform's web.search tool. Default true. Set false when the agent needs to filter results by publication date, use the workspace's own Serper key, or control the query — the built-in search offers none of those. No effect on providers without a built-in search (DeepSeek, Qwen). OMIT to leave unchanged. |
output_text_filters | array | no | Deterministic post-processing of the user-facing text an AGENTIC run produces (messages.send text + auto-delivered final answer; drafts inherit; ai_assisted fast-path replies and messages.edit are NOT covered). List of {pattern, replacement} regex rules applied in order. Example — strip AI-tell em dashes while keeping '—————' separator runs and never gluing lines: [{"pattern": "[ \t](?<![—–])—–[ \t]", "replacement": ", "}] (use [ \t], not \s — \s matches newlines). Use for style rules the LLM won't reliably follow via prompt. Patterns are validated (invalid regex rejects the update). Max 20 rules. Empty list [] = clear all filters. OMIT to leave unchanged. |
priority | integer | no | Agent priority for trigger matching. LOWER number = HIGHER priority (wins tiebreaks). Typical range 1-100. Fallback auto-reply agents use 10; specialised/topical agents use 100. When two agents match the same incoming message, the one with the lower priority number fires. |
prompt_id | integer | no | Prompt ID to assign (null to detach) |
prompt_text | string | no | DESTRUCTIVE — REPLACES the entire system prompt. Pass ONLY when the user explicitly asks to edit/rewrite the prompt. To READ the prompt use prompts.get. When updating other fields (model, name, …) OMIT this. To append, prompts.get first then concatenate. Pass null to revert to the linked template. |
script | string | no | rule_based deterministic action (no LLM): Python run in the workbench sandbox on each matched event. Reads inputs (raw_data, message_id, from_name, …) and calls the agent's integrations via call_tool('ext<id>_<name>', {..}). Dedupe writes on inputs['message_id'] (retries re-run). Pass null to clear (falls back to per-trigger template). |
send_mode | string | no | Default send mode: 'auto' or 'draft'. OMIT to leave the send-mode unchanged. (one of auto, draft) |
status | string | no | Agent status: 'active', 'paused', or 'archived'. OMIT to leave the status unchanged. (one of active, paused, archived) |
text_engine | string | no | Text-execution engine: 'agentic', 'ai_assisted', 'rule_based', or 'claude_channels'. Replaces the legacy execution_mode field (20260523_002). Voice is now derived from triggers, not engine. OMIT to leave unchanged. (one of rule_based, agentic, claude_channels) |
vision_enabled | boolean | no | Per-agent opt-in for vision content. When true, the executor splices recent image attachments from the active thread into the LLM call (Phase 3a continuous vision for Meet bot screen-share, plus any future channel that uploads images). Requires the agent's model to support vision (model_has_vision check). Default false; new calls pay zero token cost until the operator opts in. OMIT to leave the vision flag unchanged. |
voice_call_analysis | boolean | no | Run a post-call LLM analysis after each answered call: summary, success verdict with reason, and a 1-10 quality score, stored on the voice session and returned by calls.get_transcript metadata. Default false (costs one LLM call per call). OMIT to leave unchanged. |
voice_denoise | boolean | no | Server-side noise suppression (DeepFilterNet) on the INBOUND caller audio before STT — cleans background noise so the agent hears callers in loud/public places and gets fewer false barge-ins. Channel-agnostic: applies to every voice channel the agent answers on. Default false (unset). OMIT to leave unchanged. |
voice_early_finalize_confidence | number | no | Flux early-finalize confidence (0.1-1.0, worker default 0.65). Lower = finalize sooner on trailing silence (snappier, small mid-word clip risk). Flux STT only. OMIT to leave unchanged. (min 0.1; max 1.0) |
voice_endpointing_max_delay | number | no | LiveKit endpointing.max_delay (0.5-10.0s, default 3.0). Ceiling on how long the agent waits for a turn to end. voice_endpointing_min_delay is the floor after silence; this is what stops a thinking pause from holding the turn open, and it is the knob to raise when an agent talks over someone who pauses mid-thought. (min 0.5; max 10.0) |
voice_endpointing_min_delay | number | no | Silence after end-of-utterance before agent replies (0.1-2.0s, default 0.3). Higher = fewer false interrupts; lower = snappier. (min 0.1; max 2.0) |
voice_endpointing_mode | string | no | LiveKit endpointing mode. 'fixed' (default) waits voice_endpointing_min_delay every turn; 'dynamic' adapts the wait from the conversation's own rhythm. OMIT to leave unchanged. (one of fixed, dynamic) |
voice_engine | string | no | Voice execution engine: 'pipeline' (default — Deepgram/Gladia STT + LLM + TTS), 'openai_realtime' (OpenAI Realtime API v2v; requires the workspace to have a BYOK OpenAI key connected — the worker falls back to 'pipeline' and logs why if the key is missing), or 'gemini_realtime' (Gemini 2.0 Flash with real-time API). OMIT to leave unchanged. (one of pipeline, openai_realtime, gemini_realtime) |
voice_filler_audio_preset | string | no | Which bundled clip plays as the 'thinking' filler while the agent is working (LLM + tool calls), used when voice_thinking_texts is empty. Requires voice_filler_enabled=true. Built-in presets: 'keyboard_typing' / 'keyboard_typing2' (keyboard-typing SFX — sounds like the agent is typing/looking something up), plus any bundled music preset. Pass '' to clear (fall back to spoken filler). An unknown value silently plays no filler. OMIT or null to leave unchanged. |
voice_filler_enabled | boolean | no | Emit 'thinking' filler audio while tools run so the caller hears life on the line (default true). OMIT to leave this flag unchanged. |
voice_flux_eager_eot_threshold | number | no | Flux eager end-of-turn threshold (0.1-1.0). Setting this ENABLES EagerEndOfTurn for faster turn-taking at the cost of +50-70% LLM calls. Flux STT only. OMIT to leave eager off. (min 0.1; max 1.0) |
voice_flux_eot_threshold | number | no | Flux STT end-of-turn confidence threshold (0.1-1.0). Higher = wait for more certainty before finalizing the turn. Flux STT only (ignored on nova-3). OMIT to keep the worker default (0.7). (min 0.1; max 1.0) |
voice_flux_eot_timeout_ms | integer | no | Flux end-of-turn hard timeout in ms (500-15000). Flux STT only. OMIT to keep the worker default (5000). (min 500.0; max 15000.0) |
voice_greeting | string | no | Opening line the agent speaks when the call connects. Pass an empty string "" to clear. Omit or null leaves unchanged. |
voice_greeting_interruptible | boolean | no | Allow the caller to barge in during the opener TTS. Default true (trial-friendly — long greetings can be interrupted). Set false on outbound-call agents whose configured opener would otherwise get preempted by the caller's 'Hello?' triggering an off-script auto-turn. OMIT to leave this flag unchanged. |
voice_greeting_returning | string | no | Greeting variant for RETURNING callers (thread has prior history or a resolved name). Supports '{name}' — replaced with the caller's name when known, stripped when not. Pass an empty string "" to clear (always use voice_greeting). Omit or null leaves unchanged. |
voice_group_barge_in_min_words | integer | no | GROUP/Meet barge-in word gate (1-6, default 1): a participant line must have at least this many words to interrupt the agent. 1 = any word interrupts (most responsive); raise to ignore short cross-talk. OMIT to leave unchanged. (min 1.0; max 6.0) |
voice_group_barge_in_requires_address | boolean | no | GROUP/Meet barge-in: when true, only lines that ADDRESS the agent (by name/keyword) interrupt it — two humans talking to each other won't break the walk. Default false. OMIT to leave unchanged. |
voice_group_barge_in_stop_words | array | no | GROUP/Meet barge-in stop-words: any of these words/phrases ALWAYS interrupts the agent, even below voice_group_barge_in_min_words (e.g. ['стоп','подожди','вопрос','stop','wait','question']). Empty list [] clears. OMIT to leave unchanged. |
voice_group_interim_barge_in | boolean | no | GROUP/Meet barge-in: interrupt the agent AS SOON AS a participant starts speaking (on the interim transcript), instead of waiting for the finished utterance. Default true. Set true to make a presenter/group agent easy to interrupt mid-sentence (word-gated by voice_group_barge_in_min_words so ambient noise can't trip it); false = only a completed utterance interrupts. OMIT to leave unchanged. |
voice_hold_ready_reply | boolean | no | Keep a finished reply the caller talked over (before any audio played) and speak it at the next pause, then answer what was said since. Without it (the default) stock LiveKit behaviour applies: that reply is discarded and regenerated from scratch. Default false. OMIT to leave unchanged. |
voice_interruption_min_duration | number | no | Min caller speech duration to interrupt the agent (0.1-1.5s, default 0.25). Higher = ignore short fillers like 'uh-huh'. (min 0.1; max 1.5) |
voice_max_call_duration_s | integer | no | Wall-clock cap for a voice call in seconds, clamped to 60-14400; the worker ends the call at it regardless of what the conversation is doing. OMIT to leave unchanged (default is no cap — a call ends when the conversation ends). To REMOVE an existing cap, clear the field in the agent's Voice settings UI (0 there = no limit). Two agents talking to each other are capped separately by calls.agent_duel's own max_duration_s. (min 1.0; max 14400.0) |
voice_max_tokens | integer | no | Max TTS tokens per voice reply (40-200, default 100). Lower = snappier, higher = more detail. Controls speech brevity only: when the agent has voice tools, the runtime floors the underlying LLM completion cap at 400 so tool-call JSON always fits. (min 40.0; max 200.0) |
voice_max_tool_calls | integer | no | Max tool calls per voice turn (1-10, default 3). OMIT to leave unchanged. (min 1.0; max 10.0) |
voice_mip_opt_out | boolean | no | Opt out of Deepgram's model-improvement program (privacy) for Flux STT. Default false. OMIT to leave unchanged. |
voice_output_gain_db | number | no | Output attenuation in dB applied to the agent's WhatsApp call audio before the codec (-12.0 to 0.0, default 0 = unchanged). Use a negative value (e.g. -3.5) when a hot voice engine (OpenAI Realtime rides near 0 dBFS) causes blown-speaker distortion on loud words: the 24 kbps call codec needs headroom, and this restores it. Applied on the next call, no deploy needed. (min -12.0; max 0.0) |
voice_preemptive_generation | boolean | no | Speculatively start the LLM on STT partials so the agent begins responding before end-of-utterance. Matches LiveKit stock template. Default true. OMIT to leave this flag unchanged. |
voice_primary_model | string | no | Primary LLM for voice turns (e.g. 'gpt-4.1-mini', 'claude-haiku-4-5-20251001'). Pass null to revert to default. |
voice_realtime_model | string | no | Realtime (v2v) model tier for voice_engine=openai_realtime: 'gpt-realtime' (~18c/min on short calls) or 'gpt-realtime-mini' (~75% cheaper). OMIT to keep the plugin default. (one of gpt-realtime, gpt-realtime-mini) |
voice_record_announce | boolean | no | On recorded calls, prepend a short 'this call may be recorded' notice to the agent's greeting. Only takes effect when voice_record_calls is enabled. Default false. OMIT to leave unchanged. |
voice_record_calls | boolean | no | Record voice calls handled by this agent (stereo audio: caller and agent on separate channels), stored with the call for later playback. Default false. Ensure callers are informed of recording where consent rules apply. OMIT to leave this flag unchanged. |
voice_stt_keyterms | array | no | Domain-vocab bias for STT — names, product SKUs, etc. Passed verbatim as repeated &keyterm=<w> query params. Works on both Nova-3 and Flux. Prefer short phrases over full sentences. Empty list [] = no bias. Omit leaves unchanged. |
voice_stt_language | string | no | STT language code, validated against the SELECTED voice_stt_provider. 'multi' (default) enables autodetect / code-switching on either provider; a singleton like 'en', 'ru', 'uz' gives higher accuracy when the caller language is known. Deepgram provider: 'en' runs on Flux (fastest, eager end-of-turn); 'multi' and every other language run on Nova-3. Some languages — notably Thai ('th'), Vietnamese ('vi'), Indonesian ('id'), Tagalog ('tl') — are NOT in Nova-3's 'multi' auto-detect set, so those callers MUST be given an explicit code. Gladia provider: use its codes (e.g. 'uz' Uzbek, 'kk' Kazakh, 'az' Azerbaijani, 'tg' Tajik) — these are NOT valid under Deepgram. The enum below lists the union of both providers' codes; a code invalid for the chosen provider is rejected on save. OMIT to leave the STT language unchanged. (one of af, am, ar, ar-AE, ar-DZ, ar-EG, ar-IQ, ar-IR, ar-JO, ar-KW, ar-LB, ar-MA, ar-PS, ar-QA, ar-SA, ar-SD, ar-SY, ar-TD, ar-TN, as, ast, az, ba, be, bg, bn, bo, br, bs, ca, ceb, cs, cy, da, da-DK, de, de-CH, el, en, en-AU, en-GB, en-IN, en-NZ, en-US, es, es-419, et, eu, fa, ff, fi, fo, fr, fr-CA, fy, ga, gd, gl, gu, ha, haw, he, hi, hr, ht, hu, hy, id, ig, ilo, is, it, ja, jv, ka, kk, km, kn, ko, ko-KR, la, lb, lg, ln, lo, lt, lv, mg, mi, mk, ml, mn, mo, mr, ms, mt, multi, my, ne, nl, nl-BE, nn, no, oc, or, pa, pl, ps, pt, pt-BR, pt-PT, ro, ru, sa, sd, si, sk, sl, sn, so, sq, sr, ss, su, sv, sv-SE, sw, ta, te, tg, th, th-TH, tk, tl, tn, tr, tt, uk, ur, uz, vi, wo, xh, yi, yo, zh, zh-CN, zh-HK, zh-Hans, zh-Hant, zh-TW, zu) |
voice_stt_model | string | no | Speech-to-text model (Deepgram provider only): 'flux' (alias for flux-general-en), 'flux-general-en' (English Flux, LLM-powered end-of-turn), 'flux-general-multi' (multilingual Flux), or 'nova-3' (silence-based fallback). Flux variants are more responsive; nova-3 is the fallback when your Deepgram plan lacks Flux. Ignored when voice_stt_provider='gladia' (Gladia has a single model). OMIT to leave the STT model unchanged. (one of flux, flux-general-en, flux-general-multi, nova-3) |
voice_stt_provider | string | no | Speech-to-text provider. 'deepgram' (default) runs Nova-3 / Flux and preserves existing behaviour. 'gladia' routes to Gladia streaming STT (solaria-1), which is Deepgram-class latency and covers ~115 languages Deepgram does NOT — including Uzbek ('uz'), Kazakh ('kk'), Azerbaijani ('az'), Tajik ('tg'). Pick 'gladia' when the caller's language is outside Deepgram's coverage, then set voice_stt_language to that language's code. The provider also decides which language codes voice_stt_language accepts. OMIT to leave the STT provider unchanged. (one of deepgram, gladia) |
voice_thinking_texts | array | no | Pool of phrases spoken while the agent sets up the turn before calling the LLM (e.g. ['Hmm', 'So', 'One sec']). Pre-rendered to PCM at call start; one is picked at random per turn so the agent doesn't repeat the same word. Pass [] to clear. Omit or null leaves unchanged. |
voice_tools | array | no | The EXACT set of tool IDs exposed to the LIVE VOICE runner (dotted IDs, e.g. ['knowledge.query','messages.send','messages.read_history','agent.handoff','calls.end','calendar.check_availability','calendar.create_event','contacts.capture_lead']). SEPARATE from allowed_tools (which governs TEXT mode): a tool only reaches the voice LLM if listed here. When set this REPLACES the whole voice surface — include EVERY tool the voice agent needs (the small default set is NOT auto-added once any voice tool is set). Tools listed here are also added to the text allow-list if absent. Empty list [] = no voice tools. OMIT to leave the voice tool surface unchanged. |
voice_transfer_numbers | array | no | Phone numbers (E.164, e.g. '+15551234567') the agent may cold-transfer a live call to ('let me put you through to a manager'). Any destination not on this list is refused; an empty list [] means the agent cannot transfer at all. Omit leaves unchanged. |
voice_tts_language | string | no | TTS language code, BCP-47 lite e.g. 'en', 'es', 'pt-BR' (Cartesia only, default 'en'). |
voice_tts_provider | string | no | Text-to-speech provider: 'deepgram' (default, Aura-2 EN-only), 'openai' (multilingual), 'cartesia' (Sonic-3, ultra-low TTFB, multilingual), 'alibaba' (CosyVoice v3-flash, multilingual, ~95ms TTFB), 'yandex' (best Russian), 'qwen' (Qwen3-TTS, self-hosted), or 'xai' (Grok, ~20 langs). OMIT to leave the TTS provider unchanged. (one of alibaba, cartesia, deepgram, openai, qwen, xai, yandex) |
voice_tts_speed | number | no | TTS playback speed multiplier (0.5-2.0, default 1.0). Yandex/OpenAI/Cartesia only — ignored for Deepgram. (min 0.5; max 2.0) |
voice_tts_voice | string | no | TTS voice id — provider-specific (e.g. 'aura-2-thalia-en' for Deepgram, 'alloy' for OpenAI, 'alena' for Yandex, Cartesia voice UUID). Pass null to revert to provider default. |
voice_turn_detector | string | no | Voice end-of-turn detector: 'vad' (default — sharp, low-latency) or 'multilingual' (semantic model, ~1s slower per turn, fewer mid-pause cuts). OMIT to leave unchanged. (one of vad, multilingual) |
voice_v2v_transcripts | boolean | no | Enable live transcripts for voice-to-voice engines (default true). OMIT to leave unchanged. |
agents.update_from_template
Update Agent From Template
Effects: write
Update a forked agent's instructions (prompt) to the latest version of the system template it was created from.
Use when the platform has improved a template and the user wants their forked agent to pick up the new prompt. This OVERWRITES the agent's prompt_text with the template's current prompt — any customizations to the prompt are replaced (recoverable via prompt history). Tool/model/execution settings are NOT changed. Only works on agents forked from a template (not from-scratch agents or templates themselves).
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
agent_id | integer | yes | ID of the forked agent to update from its template |