Skip to content
TriedDocs
Conversation flows

Create conversation flow

Create a node-and-edge response engine with every node type, edge and setting.

POSThttps://api.tried.com.au/create-conversation-flow

Creates a conversation flow: a graph of nodes joined by edges, where each node does one job (talk, call a function, transfer, branch, end). Attach it to an agent with response_engine: { "type": "conversation-flow", "conversation_flow_id" } on Create agent.

Every field is optional. When you send nodes without start_node_id, the first node becomes the start node. The new flow is version 0, a draft; it is published with the agent that uses it.

Request#

Model and prompt#

Field Type Required Description
global_prompt string No Prompt that applies on every node. Supports {{dynamic_variables}}. Default "".
model_choice object No type (cascading or s2s, default cascading), model (required, one of the LLM models), high_priority (default false), ultrafast, s2s_model (gpt-realtime or gpt-realtime-mini, for type: "s2s"). Default { "type": "cascading", "model": "gpt-5.6-terra", "high_priority": false }.
model_temperature number No 0 to 1. Default 0.
tool_call_strict_mode boolean No Strict JSON schema for tool calls.
flex_mode boolean No Compile the whole flow into one prompt; the model moves between steps itself.
start_speaker string No agent or user. Default agent.
begin_after_user_silence_ms integer or null No With start_speaker: "user", start talking after this much silence.
default_dynamic_variables object No Fallback string values for variables. Default {}.

The prompt limit is 32,768 tokens (characters divided by 4), counted as global_prompt plus the longest node instruction plus the JSON of tools.

Graph#

Field Type Required Description
nodes object[] No The nodes. IDs must be unique. See Nodes. Default [].
start_node_id string or null No First node. Must be one of nodes. Default: the first node.
tools object[] No Tools that function and subagent nodes reference. Each is a tool plus a tool_id string. Default [].
components object[] No Component (subflow) definitions used by component nodes: copies of library components or flow-only ones. Each has component_id, name, start_node_id, nodes, tools, begin_tag_display_position.
mcps object[] No MCP servers for mcp nodes and tools. Same shape as Retell LLM mcps.

Knowledge base#

Field Type Required Description
knowledge_base_ids string[] No Knowledge bases to search. Each must exist. 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 retrieval.

Canvas#

Field Type Required Description
begin_tag_display_position object No { "x", "y" } of the Begin tag. Default { "x": 0, "y": 0 }.
notes object[] No Sticky notes, display only: id, text, position ({ "x", "y" }), color, width, height.

Nodes#

Fields on every node#

Field Type Required Description
id string Yes Unique within the flow.
type string Yes Node type. See Node types.
name string No Display name. Default "".
display_position object No { "x", "y" } on the canvas. Default { "x": 0, "y": 0 }.
global_node_setting object No Makes the node global: it can be entered from anywhere. See global_node_setting.

Per-node overrides#

Any node can override agent or flow settings while it is active:

Field Type Description
model_choice object { "type": "cascading", "model", "high_priority"?, "ultrafast"? }.
voice_speed number 0.5 to 2.
responsiveness number 0 to 1.
interruption_sensitivity number 0 to 1.
stt_mode string fast or accurate.
boosted_keywords string[] Extra STT keywords.
knowledge_base_ids string[] Knowledge bases for this node.
kb_instruction string Up to 500 characters.
allow_dtmf_interruption boolean Keypad presses interrupt the agent.
reminder_trigger_ms integer At least 1000.
reminder_max_count integer 0 or more.
finetune_conversation_examples object[] Example exchanges: { "id", "transcript": [{ "role": "user" or "agent", "content" }] }.
finetune_transition_examples object[] Example transitions: { "id", "transcript", "destination_node_id" }.

global_node_setting#

Field Type Description
condition string When to jump to this node from anywhere (required).
go_back_conditions object[] { "id", "transition_condition" } entries: when to return to the node the conversation came from.
cool_down integer 0 to 100. After leaving, the node cannot trigger again for this many user turns.

Instruction#

Nodes that speak take an instruction:

Field Type Description
type string prompt (the model writes the reply from this text) or static_text (say these exact words).
text string The prompt or the words.

Node types#

type Fields (besides the common ones) What it does
conversation instruction (required), edges, skip_response_edge, always_edge, else_edge, skippable Talks with the caller. skip_response_edge moves on without waiting for a reply. always_edge is taken unconditionally. else_edge is taken when no other edge applies (prompt edges are then decided before replying). skippable lets the runtime skip the node when contact memory already answers it.
function tool_id (required), wait_for_result (default true), speak_during_execution (default false), instruction, edges, else_edge Runs one tool from tools.
transfer_call transfer_destination (required), transfer_option (default cold sip_invite), instruction, edge Transfers the call. Same destination and option shapes as the transfer_call tool. edge is followed when the transfer fails.
press_digit instruction (required), edges, delay_ms (0 to 5000) Presses keypad digits to navigate a phone menu.
branch edges, else_edge (required) Follows an edge whose condition holds, otherwise else_edge. Says nothing.
extract_dynamic_variables variables (required, analysis fields), edges Extracts values into dynamic variables, then follows edges.
end instruction, custom_sip_headers Says the instruction, if any, and ends the call.
subagent instruction (required), tool_ids (default []), edges, always_edge, else_edge A conversation node with its own tools that the model may call freely while in the node.
code code (required, JavaScript up to 20000 characters), timeout_ms (1000 to 60000), response_variables, speak_during_execution, instruction, edges, else_edge Runs code in the API sandbox, stores response variables, then follows equation edges.
sms sms_content (required), instruction, success_edge, failure_edge Sends an SMS to the caller. Same sms_content shapes as the send_sms tool.
agent_swap agent_id (required), agent_version, keep_current_voice, instruction, edge Hands the call to another agent; history and collected variables carry over. edge is followed when the swap fails.
mcp mcp_id (required), mcp_tool_name (required), arguments, parameters, response_variables, speak_during_execution, instruction, edges, else_edge Calls one tool on a server in mcps. arguments are fixed values (with {{variables}} rendered); the model fills the rest from the parameters schema.
component component_id (required), sync, edges, else_edge Runs a component subflow. sync: true always uses the latest library version. Otherwise the copy in components is used, or the library entry when the flow has no copy. When the subflow exits, this node's edges continue.
component_exit none Exit of a component subflow: control returns to the component node's edges.
bridge_transfer instruction Transfer agents: connect the waiting caller.
cancel_transfer instruction Transfer agents: give up and return the caller to the original agent.

Edges#

Field Type Required Description
id string Yes Edge ID.
destination_node_id string or null No Target node. Default null (not connected).
transition_condition object Yes When to take the edge. See below.

transition_condition#

type Fields Taken when
prompt prompt The model judges the condition in prompt is met.
equation equations (at least one), operator (&& or `
equation_prompt equations, operator, prompt The equations hold and the model judges the prompt condition met.

Each equation is { "left", "operator", "right" }. left and right are strings that can use {{variables}}; right defaults to "". operator is one of ==, !=, >, >=, <, <=, contains, not_contains, exists, not_exist.

Example request#

curl -X POST "https://api.tried.com.au/create-conversation-flow" \
  -H "Authorization: Bearer $TRIED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "global_prompt": "You are the receptionist for Bright Dental. Keep replies short.",
  "model_choice": {
    "type": "cascading",
    "model": "gpt-5.6-terra"
  },
  "start_node_id": "node_greet",
  "nodes": [
    {
      "id": "node_greet",
      "type": "conversation",
      "name": "Greeting",
      "instruction": {
        "type": "static_text",
        "text": "Hi, thanks for calling Bright Dental. Are you after a booking?"
      },
      "edges": [
        {
          "id": "edge_book",
          "destination_node_id": "node_book",
          "transition_condition": {
            "type": "prompt",
            "prompt": "Caller wants to book"
          }
        },
        {
          "id": "edge_other",
          "destination_node_id": "node_end",
          "transition_condition": {
            "type": "prompt",
            "prompt": "Caller wants something else"
          }
        }
      ]
    },
    {
      "id": "node_book",
      "type": "function",
      "name": "Check availability",
      "tool_id": "tool_availability",
      "speak_during_execution": true,
      "instruction": {
        "type": "static_text",
        "text": "One moment while I check."
      },
      "edges": [
        {
          "id": "edge_done",
          "destination_node_id": "node_end",
          "transition_condition": {
            "type": "equation",
            "equations": [
              {
                "left": "{{slot}}",
                "operator": "exists"
              }
            ]
          }
        }
      ]
    },
    {
      "id": "node_end",
      "type": "end",
      "instruction": {
        "type": "prompt",
        "text": "Thank the caller and say goodbye."
      }
    }
  ],
  "tools": [
    {
      "tool_id": "tool_availability",
      "type": "custom",
      "name": "check_availability",
      "url": "https://example.com/tools/availability",
      "response_variables": {
        "slot": "next_slot"
      }
    }
  ]
}'
const res = await fetch("https://api.tried.com.au/create-conversation-flow", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "global_prompt": "You are the receptionist for Bright Dental. Keep replies short.",
    "model_choice": {
      "type": "cascading",
      "model": "gpt-5.6-terra"
    },
    "start_node_id": "node_greet",
    "nodes": [
      {
        "id": "node_greet",
        "type": "conversation",
        "name": "Greeting",
        "instruction": {
          "type": "static_text",
          "text": "Hi, thanks for calling Bright Dental. Are you after a booking?"
        },
        "edges": [
          {
            "id": "edge_book",
            "destination_node_id": "node_book",
            "transition_condition": {
              "type": "prompt",
              "prompt": "Caller wants to book"
            }
          },
          {
            "id": "edge_other",
            "destination_node_id": "node_end",
            "transition_condition": {
              "type": "prompt",
              "prompt": "Caller wants something else"
            }
          }
        ]
      },
      {
        "id": "node_book",
        "type": "function",
        "name": "Check availability",
        "tool_id": "tool_availability",
        "speak_during_execution": true,
        "instruction": {
          "type": "static_text",
          "text": "One moment while I check."
        },
        "edges": [
          {
            "id": "edge_done",
            "destination_node_id": "node_end",
            "transition_condition": {
              "type": "equation",
              "equations": [
                {
                  "left": "{{slot}}",
                  "operator": "exists"
                }
              ]
            }
          }
        ]
      },
      {
        "id": "node_end",
        "type": "end",
        "instruction": {
          "type": "prompt",
          "text": "Thank the caller and say goodbye."
        }
      }
    ],
    "tools": [
      {
        "tool_id": "tool_availability",
        "type": "custom",
        "name": "check_availability",
        "url": "https://example.com/tools/availability",
        "response_variables": {
          "slot": "next_slot"
        }
      }
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.tried.com.au/create-conversation-flow",
    headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
    json={
        "global_prompt": "You are the receptionist for Bright Dental. Keep replies short.",
        "model_choice": {
            "type": "cascading",
            "model": "gpt-5.6-terra",
        },
        "start_node_id": "node_greet",
        "nodes": [
            {
                "id": "node_greet",
                "type": "conversation",
                "name": "Greeting",
                "instruction": {
                    "type": "static_text",
                    "text": "Hi, thanks for calling Bright Dental. Are you after a booking?",
                },
                "edges": [
                    {
                        "id": "edge_book",
                        "destination_node_id": "node_book",
                        "transition_condition": {
                            "type": "prompt",
                            "prompt": "Caller wants to book",
                        },
                    },
                    {
                        "id": "edge_other",
                        "destination_node_id": "node_end",
                        "transition_condition": {
                            "type": "prompt",
                            "prompt": "Caller wants something else",
                        },
                    },
                ],
            },
            {
                "id": "node_book",
                "type": "function",
                "name": "Check availability",
                "tool_id": "tool_availability",
                "speak_during_execution": True,
                "instruction": {
                    "type": "static_text",
                    "text": "One moment while I check.",
                },
                "edges": [
                    {
                        "id": "edge_done",
                        "destination_node_id": "node_end",
                        "transition_condition": {
                            "type": "equation",
                            "equations": [
                                {
                                    "left": "{{slot}}",
                                    "operator": "exists",
                                },
                            ],
                        },
                    },
                ],
            },
            {
                "id": "node_end",
                "type": "end",
                "instruction": {
                    "type": "prompt",
                    "text": "Thank the caller and say goodbye.",
                },
            },
        ],
        "tools": [
            {
                "tool_id": "tool_availability",
                "type": "custom",
                "name": "check_availability",
                "url": "https://example.com/tools/availability",
                "response_variables": {
                    "slot": "next_slot",
                },
            },
        ],
    },
)
data = res.json()

Response#

201 Created with the flow. All fields are returned with defaults filled in, plus:

Field Type Description
conversation_flow_id string conversation_flow_ plus 24 hex characters.
version integer 0 for a new flow.
is_published boolean false for a new flow.
last_modification_timestamp integer Epoch ms.
{
  "conversation_flow_id": "conversation_flow_2c3d4e5f6a7b8c9d0e1f2a3b",
  "version": 0,
  "is_published": false,
  "global_prompt": "You are the receptionist for Bright Dental. Keep replies short.",
  "model_choice": { "type": "cascading", "model": "gpt-5.6-terra", "high_priority": false },
  "model_temperature": 0,
  "start_speaker": "agent",
  "start_node_id": "node_greet",
  "nodes": [],
  "tools": [],
  "knowledge_base_ids": [],
  "default_dynamic_variables": {},
  "begin_tag_display_position": { "x": 0, "y": 0 },
  "last_modification_timestamp": 1792310400000
}

nodes and tools are shortened to [] in this example; the response contains them in full.

Errors#

Status When
400 Validation failed, duplicate node IDs (Duplicate node ids in conversation flow), start_node_id is not a node, the prompt is over the limit, or a knowledge base ID does 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.