Creates a Retell LLM: the prompt-driven response engine used by single-prompt and multi-prompt agents. Attach it to an agent with response_engine: { "type": "retell-llm", "llm_id" } on Create agent.
- Single prompt: set
general_promptandgeneral_tools, leavestatesempty. - Multi-prompt: add
states. Each state has its own prompt, tools and edges to other states. Thegeneral_promptandgeneral_toolsapply in every state.
Every field is optional. The new LLM is version 0, a draft. It is published when an agent that uses it without a pinned version is published.
Request#
Model#
| Field | Type | Required | Description |
|---|---|---|---|
model |
string | No | One of gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.4-mini, gpt-4.1, gpt-4.1-mini, claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5, claude-sonnet-4-6, claude-haiku-4-5, gemini-3.5-flash, gemini-3-flash-preview, gemini-2.5-flash. Default gpt-5.6-terra. claude- models use Anthropic and gemini- models use Google; the rest use OpenAI. |
model_temperature |
number | No | 0 to 1. Default 0. |
model_high_priority |
boolean | No | Use the provider's priority tier. Default false. |
model_ultrafast |
boolean | No | Priority tier plus a low-latency model hint. |
s2s_model |
string or null | No | Speech-to-speech engine, gpt-realtime or gpt-realtime-mini. Replaces STT, LLM and TTS with one model. null or absent uses the cascading pipeline with model. |
tool_call_strict_mode |
boolean | No | Strict JSON schema for tool calls. Default true. |
Each provider needs its API key (OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY). Without it, that provider's models are mocked. Needs keys
Prompt and conversation start#
| Field | Type | Required | Description |
|---|---|---|---|
general_prompt |
string | No | System prompt used in every state. Supports {{dynamic_variables}}. Default "". |
begin_message |
string or null | No | First thing the agent says. null lets the model write the opening. Default null. |
start_speaker |
string | No | agent or user: who speaks first. Default agent. |
begin_after_user_silence_ms |
integer or null | No | With start_speaker: "user", the agent starts talking after this much silence. Default null. |
default_dynamic_variables |
object | No | Fallback values (strings) for variables the call does not set. Default {}. |
The prompt limit is 32,768 tokens, estimated as characters divided by 4. The count is general_prompt plus begin_message plus the JSON of general_tools, plus the largest state's prompt and tools. Above the limit the request fails with 400.
Tools and states#
| Field | Type | Required | Description |
|---|---|---|---|
general_tools |
object[] | No | Tools available in every state. See Tools. Default []. |
states |
object[] | No | States for a multi-prompt agent. See States. Default []. |
starting_state |
string or null | No | Name of the first state. Default null. |
mcps |
object[] | No | MCP servers that mcp tools can reference. See mcps. |
is_transfer_llm |
boolean | No | The LLM drives transfer legs for agentic warm transfers. |
Knowledge base#
| Field | Type | Required | Description |
|---|---|---|---|
knowledge_base_ids |
string[] | No | Knowledge bases to search. Each must exist in the workspace. Default []. |
kb_config |
object | No | top_k (1 to 10, default 3) and filter_score (0 to 1, default 0.6). |
kb_instruction |
string | No | Up to 500 characters that steer query rewriting and retrieval. |
States#
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | 1 to 64 letters, numbers, _ or -. |
state_prompt |
string | No | Prompt for this state, added to general_prompt. Default "". |
edges |
object[] | No | Transitions to other states. Default []. |
edges[].destination_state_name |
string | Yes | Target state. |
edges[].description |
string | No | When to take the edge. Default "". |
edges[].parameters |
object | No | JSON schema of values the LLM passes when it takes the edge. They become dynamic variables. |
tools |
object[] | No | Tools available only in this state. Default []. |
mcps#
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Your ID for the server, used by mcp tools as mcp_id. |
name |
string | No | Display name. Default "". |
url |
string | Yes | Streamable HTTP endpoint of the MCP server. |
headers |
object | No | Headers sent on every request. |
query_params |
object | No | Query parameters added to the URL. |
timeout_ms |
integer | No | 1000 to 600000. |
Tools#
Every tool has a type and these common fields:
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | One of the types below. |
name |
string | Yes | 1 to 64 letters, numbers, _ or -. The name the model calls. |
description |
string | No | When to use the tool. Default "". |
speak_during_execution |
boolean | No | Say something while the tool runs. |
speak_after_execution |
boolean | No | Feed the result back to the model for a spoken follow-up. Treated as true when absent. |
execution_message_description |
string | No | What to say while running: a prompt, or exact words when execution_message_type is static_text. |
execution_message_type |
string | No | prompt or static_text. |
typing_sound |
boolean | No | Play soft keyboard sounds while the tool runs. |
end_call#
Ends the call.
| Field | Type | Description |
|---|---|---|
custom_sip_headers |
object | SIP headers sent with the hang-up. |
transfer_call#
Transfers the caller to a phone number or SIP URI.
| Field | Type | Required | Description |
|---|---|---|---|
transfer_destination |
object | Yes | { "type": "predefined", "number" } or { "type": "inferred", "prompt" } (the model picks the number from the prompt). Both accept extension: DTMF digits sent after the destination answers (0-9, *, #, w for a 0.5 s pause, ,; up to 32). |
transfer_option |
object | No | How to transfer. Default { "type": "cold_transfer", "cold_transfer_mode": "sip_invite", "show_transferee_as_caller": false }. See below. |
custom_sip_headers |
object | No | SIP headers on the transfer. |
transfer_option by type:
type |
Fields |
|---|---|
cold_transfer |
cold_transfer_mode (sip_refer or sip_invite, default sip_invite), show_transferee_as_caller (default false), transfer_ring_duration_ms (5000 to 300000, sip_invite only). |
warm_transfer |
public_handoff_option and private_handoff_option (each { "type": "prompt" or "static_message", "prompt", "message" }), show_transferee_as_caller, agent_detection_timeout_ms (1000 to 600000: wait this long for a human), on_hold_music, opt_out_human_detection, ivr_option (digits up to 64, prompt up to 2000 characters, timeout_ms 1000 to 300000), enable_bridge_audio_cue, transfer_ring_duration_ms. |
agentic_warm_transfer |
transfer_agent ({ "agent_id", "agent_version"? }, required: the agent that handles the transfer leg), transfer_timeout_ms (10000 to 600000), action_on_timeout (bridge_transfer or cancel_transfer), show_transferee_as_caller, on_hold_music, transfer_ring_duration_ms. |
on_hold_music is none, relaxing, uplifting, ringtone, or an uploaded hold music asset ID (asset_ plus 24 hex characters).
press_digit#
Presses keypad digits, for navigating phone menus. The model passes digit.
| Field | Type | Description |
|---|---|---|
delay_ms |
integer | Pause before pressing, 0 to 5000. |
custom#
Calls your HTTP endpoint from the agent runtime. Requests go through the runtime's SSRF guard (private and loopback addresses are refused) and are signed with the workspace webhook key in x-retell-signature.
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Endpoint URL. |
method |
string | No | GET, POST, PUT, PATCH or DELETE. Default POST. |
headers |
object | No | Request headers. |
query_params |
object | No | Query parameters. |
parameters |
object | No | JSON schema of the arguments the model fills. |
speak_during_execution |
boolean | No | Default false. |
speak_after_execution |
boolean | No | Default true. |
timeout_ms |
integer | No | 1000 to 600000. Default 120000. |
response_variables |
object | No | { "variable_name": "json.path" }: values from the response saved as dynamic variables. |
max_retry |
integer | No | 0 to 5 retries on network errors, timeouts and HTTP 429, 500, 502, 503 or 504, with backoff of 0.5 s, 1 s, 2 s and so on. |
args_at_root |
boolean | No | Send the arguments as the top-level JSON body instead of { "name", "call", "args" }. |
parameter_type |
string | No | Body encoding for POST, PUT and PATCH: json (default) or form (application/x-www-form-urlencoded). |
extract_dynamic_variable#
Saves values from the conversation as dynamic variables.
| Field | Type | Required | Description |
|---|---|---|---|
variables |
object[] | Yes | Analysis fields to extract. |
send_sms#
Sends a text to the caller.
| Field | Type | Required | Description |
|---|---|---|---|
sms_content |
object | Yes | { "type": "predefined", "content" }, { "type": "inferred", "prompt" }, or { "type": "info_collection", "intro"?, "fields" }: asks the caller to text back details, and the reply is extracted into the call's collected variables. fields is at least one analysis field. |
agent_swap#
Hands the call to another agent. History and collected variables carry over.
| Field | Type | Required | Description |
|---|---|---|---|
agent_id |
string | Yes | Agent to swap to. |
agent_version |
integer | No | Version to run. |
keep_current_voice |
boolean | No | Keep speaking with the current voice. |
keep_current_language |
boolean | No | Keep the current language. |
code#
Runs JavaScript in the API sandbox. args, dv (dynamic variables) and metadata are in scope.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Up to 20000 characters. |
parameters |
object | No | JSON schema of args. |
timeout_ms |
integer | No | 1000 to 60000. |
response_variables |
object | No | Values from the result saved as dynamic variables. |
mcp#
Calls one tool on an MCP server.
| Field | Type | Required | Description |
|---|---|---|---|
mcp_id |
string | No | An id from mcps. Give this or url. |
url |
string | No | MCP server URL, inline. |
headers |
object | No | Headers for an inline server. |
query_params |
object | No | Query parameters for an inline server. |
mcp_tool_name |
string | No | Tool name on the server. Default: the tool's name. |
parameters |
object | No | JSON schema of the arguments. |
timeout_ms |
integer | No | 1000 to 600000. |
response_variables |
object | No | Values from the result saved as dynamic variables. |
List the tools a server offers with Get MCP tools.
bridge_transfer and cancel_transfer#
Used by transfer agents in an agentic warm transfer: bridge_transfer connects the waiting caller, cancel_transfer gives up and returns the caller to the original agent. Only the common fields apply.
integration_app#
Runs an action of a connected integration app. The API executes it.
| Field | Type | Required | Description |
|---|---|---|---|
app_id |
string | Yes | Integration app ID (app_...). |
action |
string | Yes | One of cal_com.check_availability, cal_com.book_appointment, cal_com.list_bookings, cal_com.reschedule_booking, cal_com.cancel_booking, hubspot.create_contact, hubspot.create_note, calendly.check_availability, calendly.create_scheduling_link, zendesk.create_ticket, salesforce.create_contact, dynamics365.create_contact, gohighlevel.create_contact, zoho.create_contact. |
parameters |
object | No | JSON schema of the arguments. Default: the action's own schema. |
static_arguments |
object | No | Fixed arguments merged under the model's arguments. |
response_variables |
object | No | { "variable_name": "json.path" } into the action's output. |
output_selection |
string[] | No | Output paths handed back to the model. Empty means the whole output. |
timeout_ms |
integer | No | 1000 to 120000. |
Example request#
curl -X POST "https://api.tried.com.au/create-retell-llm" \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-terra",
"general_prompt": "You are the receptionist for Bright Dental in Sydney. Be brief and friendly.",
"begin_message": "Hi, thanks for calling Bright Dental. How can I help?",
"general_tools": [
{
"type": "end_call",
"name": "end_call",
"description": "End the call when the caller is done."
},
{
"type": "custom",
"name": "check_availability",
"description": "Find free appointment times.",
"url": "https://example.com/tools/availability",
"parameters": {
"type": "object",
"properties": {
"day": {
"type": "string",
"description": "Day of the week"
}
},
"required": [
"day"
]
},
"speak_during_execution": true,
"execution_message_description": "One moment while I check."
}
],
"knowledge_base_ids": [
"knowledge_base_1a2b3c4d5e6f7a8b9c0d1e2f"
],
"default_dynamic_variables": {
"customer_name": "there"
}
}'const res = await fetch("https://api.tried.com.au/create-retell-llm", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "gpt-5.6-terra",
"general_prompt": "You are the receptionist for Bright Dental in Sydney. Be brief and friendly.",
"begin_message": "Hi, thanks for calling Bright Dental. How can I help?",
"general_tools": [
{
"type": "end_call",
"name": "end_call",
"description": "End the call when the caller is done."
},
{
"type": "custom",
"name": "check_availability",
"description": "Find free appointment times.",
"url": "https://example.com/tools/availability",
"parameters": {
"type": "object",
"properties": {
"day": {
"type": "string",
"description": "Day of the week"
}
},
"required": [
"day"
]
},
"speak_during_execution": true,
"execution_message_description": "One moment while I check."
}
],
"knowledge_base_ids": [
"knowledge_base_1a2b3c4d5e6f7a8b9c0d1e2f"
],
"default_dynamic_variables": {
"customer_name": "there"
}
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.tried.com.au/create-retell-llm",
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
json={
"model": "gpt-5.6-terra",
"general_prompt": "You are the receptionist for Bright Dental in Sydney. Be brief and friendly.",
"begin_message": "Hi, thanks for calling Bright Dental. How can I help?",
"general_tools": [
{
"type": "end_call",
"name": "end_call",
"description": "End the call when the caller is done.",
},
{
"type": "custom",
"name": "check_availability",
"description": "Find free appointment times.",
"url": "https://example.com/tools/availability",
"parameters": {
"type": "object",
"properties": {
"day": {
"type": "string",
"description": "Day of the week",
},
},
"required": ["day"],
},
"speak_during_execution": True,
"execution_message_description": "One moment while I check.",
},
],
"knowledge_base_ids": ["knowledge_base_1a2b3c4d5e6f7a8b9c0d1e2f"],
"default_dynamic_variables": {
"customer_name": "there",
},
},
)
data = res.json()Response#
201 Created with the LLM. All fields are returned with defaults filled in, plus:
| Field | Type | Description |
|---|---|---|
llm_id |
string | llm_ plus 24 hex characters. |
version |
integer | 0 for a new LLM. |
is_published |
boolean | false for a new LLM. |
last_modification_timestamp |
integer | Epoch ms. |
{
"model": "gpt-5.6-terra",
"model_temperature": 0,
"model_high_priority": false,
"tool_call_strict_mode": true,
"general_prompt": "You are the receptionist for Bright Dental in Sydney. Be brief and friendly.",
"begin_message": "Hi, thanks for calling Bright Dental. How can I help?",
"start_speaker": "agent",
"begin_after_user_silence_ms": null,
"general_tools": [
{ "type": "end_call", "name": "end_call", "description": "End the call when the caller is done." }
],
"states": [],
"starting_state": null,
"knowledge_base_ids": ["knowledge_base_1a2b3c4d5e6f7a8b9c0d1e2f"],
"kb_config": { "top_k": 3, "filter_score": 0.6 },
"default_dynamic_variables": { "customer_name": "there" },
"llm_id": "llm_9c8b7a6f5e4d3c2b1a0f9e8d",
"version": 0,
"is_published": false,
"last_modification_timestamp": 1792310400000
}The example response is shortened to one tool.
Errors#
| Status | When |
|---|---|
400 |
Validation failed, the prompt is over 32,768 tokens, or a knowledge base ID does not exist (One or more knowledge_base_ids do not exist). |
401 |
Missing or invalid API key. |
403 |
The key's IP allowlist or scopes reject the request. This route needs the agents scope. |
429 |
Rate limit exceeded. See Rate limits. |
See Errors for the body format.