Workflow Node Reference
Click a node on the canvas to open its editor (Edit … Node), change the fields, and click Save Changes. Saving a node also saves the workflow.
Each section lists the fields as labelled in the editor, the key the value is stored under in the workflow JSON (useful with the Platform API), and how the node behaves when a run reaches it.
Fields marked variables accept references such as ${node_2_result} or ${attribute.topic} — type $ to pick one. See Passing Data Between Steps.
Fields shared by several nodes
| Field | Key | Applies to | Description |
|---|---|---|---|
| Label | label | All | Name shown on the canvas. You can also double-click the name on the canvas to rename it. If you leave the generated name (such as "Agent 2"), the node takes the name of the agent, team, function, workflow, scenario or approval title you pick. Renaming never changes the node's ID, so references keep working. |
| Join Mode | join_mode | Agent, Team, Function, Condition, Approval, Mission | Shown only when the node has two or more incoming connections. Auto (∧ all parents, default) and ∧ All parents (AND-join) wait for every parent to finish. ∨ Any parent (OR-join) runs as soon as the first parent finishes and ignores the rest. ∅ None (no auto-fire) never runs from a parent finishing. The canvas shows a badge (∧ ALL, ∨ ANY, ∅ NONE) when set. |
Every node's ID (node_1, node_2, …) is assigned when you add it and never changes.
Trigger
The start of every run. A workflow must have exactly one. It has no input handle.
| Field | Key | Description |
|---|---|---|
| Trigger Type | trigger_type | Manual (manual), Scheduled (scheduled), Event-based (event), Webhook (webhook). Any type can still be run manually. |
Scheduled adds:
| Field | Key | Description |
|---|---|---|
| Frequency | frequency | Once, Hourly, Daily, Weekly, Monthly, Custom (Cron). |
| Start Date/Time | start_date | When the schedule begins. Interpreted as UTC. |
| Cron Expression | cron_expression | Only for Custom (Cron). Standard five-field cron, evaluated in UTC, for example 0 9 * * 1-5. |
Saving the workflow creates or updates its schedule. Changing the type away from Scheduled pauses the schedule. See Scheduling Workflows.
Webhook adds:
| Field | Key | Description |
|---|---|---|
| Webhook | webhook_id | Pick one of the project's webhooks. Disabled webhooks are marked "(disabled)". |
| Webhook URL | webhook_url | Read-only, with a copy button. |
Choosing a webhook here is for reference only. A webhook starts this workflow when the webhook's Linked Workflow (in Settings → Webhooks) is this workflow. See Webhooks.
Event-based adds Event Source (event_source, another node or an attribute), Event Action (event_action, for example onComplete) and Bound Attribute. These are stored but not acted on: no event currently starts a run.
At run time: does nothing and passes straight on.
Agent
Runs one agent.
| Field | Key | Description |
|---|---|---|
| Agent | agent_id (+ agent_name) | Required. |
| Input Message Template | input_message | Variables. The message sent to the agent. If empty, the agent receives the previous node's output, or the run's initial message if no node has produced output yet. |
| Max Retries | max_retries | Extra attempts if the node fails. 0 = no retries. |
| Output Mode | output_mode | Final Message (final_message, default) passes on only the agent's last message. Entire Chat (entire_chat) passes on the whole conversation text. |
| Model Override (optional) | llm_config_override_id | Variables. The ID of a model configuration to use instead of the agent's own, or a variable that resolves to one at run time. |
At run time: the agent runs with its own tools, knowledge and approval settings. Its conversation is saved as a chat session you can open from the mission canvas. The output is stored as ${<node_id>_result}. Tool calls that need approval pause the node — see Using Approval Gates.
Team
Runs a team using the team's orchestration pattern.
| Field | Key | Description |
|---|---|---|
| Team | team_id (+ team_name) | Required. |
| Input Message Template | input_message | Variables. Same fallback as the Agent node. |
| Output Mode | output_mode | Final Message or Entire Chat, as for Agent. |
At run time: as for Agent. The output is stored as ${<node_id>_result}.
Function
Calls a function directly, without a model.
| Field | Key | Description |
|---|---|---|
| Function | function_id (+ function_name) | Required. Changing the function clears its arguments. |
| Function Arguments | function_args | One field per parameter in the function's schema. Required parameters are marked *. Parameters with a fixed list of values show a drop-down; booleans show true/false; text, number, object and array parameters accept variables. |
| Output variable name (optional) | output_variable | Also store the result under this name. Letters, numbers and underscores only. If the result is JSON, it is stored parsed, and each top-level key of a JSON object is also stored as ${<name>_<key>}. |
At run time:
- Text arguments have their variables filled in and are passed as text. If the function has no arguments set, it receives the previous node's output (or the initial message) as its single input.
- Local Python functions, MCP stdio and MCP HTTP functions are supported. For an MCP function, the node calls the first tool the server exposes.
- The result is stored as
${<node_id>_result}and, if set, under the output variable. - If the function raises an error, the node fails.
Condition
Routes the run down exactly one branch.
The editor shows Branch Routing. Click Add Branch for each outcome, give it a name (for example APPROVED), and build its rules under Conditions:
| Rule part | Description |
|---|---|
| Source | A value to test: any other node's → result, → status or → output, or Attribute: …. |
| Operator | equals (==), not equals (!=), greater than (>), less than (<), greater or equal (>=), less or equal (<=), contains, does not contain, is empty, is not empty. |
| Value | What to compare with. Not shown for the "empty" operators. |
With more than one rule in a branch, choose AND or OR to combine them. A branch can't mix AND and OR.
Default Branch (when no conditions match) names a fallback branch. It gets its own output handle labelled "name (default)".
Stored as branches (a list of {id, name, expression}) and default_branch.
At run time:
- Branches are checked top to bottom and the first match wins. A branch with no rules always matches.
- The run follows the connection from the matching branch's handle. The other branches' first nodes show as Skipped.
- If nothing matches and there is no default branch, the Condition shows Failed and nothing after it runs.
- Each branch handle is named after its branch. If you rename a branch, reconnect its handle.
A Condition with no branches shows the older True / False handles and uses a single condition expression. The editor converts this form to a branch when you open it.
Loop Start
Begins a loop. Must be paired with a Loop End.
| Field | Key | Description |
|---|---|---|
| Loop Type | loop_type | Count (count, default): run the loop body a fixed number of times. For Each (for_each): run it once per item in a list. |
| Collection Variable | collection_variable | For Each only. The name of the variable holding the list, for example tasks. A JSON text list is parsed. Anything that isn't a list counts as empty. |
| Max Iterations / Max Iterations (safety cap) | max_iterations | Count: how many times to run. For Each: the most items to process. Default 100. |
| Loop End Node | loop_end_id | The paired Loop End. Set automatically when you connect Loop Start straight to Loop End. |
| Track output across iterations | persist_output | After each pass, save the combined text output of the loop body. |
| Output variable name | output_variable | With tracking on. Defaults to a name made from the label. ${<name>} holds the last pass's output; ${<name>_history} holds all passes as a list. |
At run time: the nodes connected after Loop Start form the loop body. Each pass runs the body until it reaches Loop End. For Each sets ${current_item}, ${current_index} (from 0), ${items_remaining} and ${loop_total} on every pass. An empty list skips the body. When the loop finishes, the run continues from the connections leaving Loop End.
Loop End
| Field | Key | Description |
|---|---|---|
| Loop Start Node | loop_start_id | The paired Loop Start. |
| Break Condition | break_condition | Optional rules, built like a Condition branch. When they match, the loop stops after this pass. |
At run time: checks the break condition each time a pass reaches it. A connection from Loop End back to Loop Start is optional — it's only drawn for readability.
Mission
Runs another workflow as a sub-workflow (stored as type MISSION_TEMPLATE).
| Field | Key | Description |
|---|---|---|
| Workflow | mission_template_id (+ mission_name) | The workflow to run. |
| Input Message Template | input_message | Variables. Becomes the sub-workflow's initial message, available inside it as ${initial_message}. |
| Output variable name (optional) | output_variable | As for Function. |
At run time: creates a separate mission for the sub-workflow and waits for it to finish. The sub-workflow does not receive the parent's attribute values — pass what it needs in the input message. The node's output is a JSON object of every sub-workflow node's result, keyed by node ID. Token usage is added to the parent run.
Wait
| Field | Key | Description |
|---|---|---|
| Duration | wait_duration | Default 5. |
| Unit | wait_unit | Seconds, Minutes, Hours. |
At run time: pauses for the duration, capped at 24 hours.
Approval
Pauses the run until a person decides.
| Field | Key | Description |
|---|---|---|
| Approval Title | approval_title | Heading of the alert sent to approvers. Default: "Approval required: label". |
| Approval Message | approval_message | What needs approving. |
| Timeout (seconds, 0 = no timeout) | approval_timeout_seconds | Rejects automatically after this long. 0 waits indefinitely. |
At run time: the node shows Action Required, an alert appears in the Alerts panel, and the run waits. Approve continues the run; Reject or a timeout fails the node and the run. The decision is recorded as oversight evidence.
The node has Approved and Rejected handles. Connect your next step to Approved and leave Rejected unconnected: after an approval the run currently follows every outgoing connection, including one from Rejected. See Using Approval Gates.
Kill Switch
| Field | Key | Description |
|---|---|---|
| On — runs pass through / Off — runs stop here | enabled | On by default. |
| Reason | reason | Why it is off. Shown on the canvas and in the logs. |
At run time: reads the switch's saved state every time a run reaches it, so switching it off stops runs already in progress the next time they reach it. Inside a loop it is checked on every pass. A stopped run ends Failed with "halted by label".
Test Case
| Field | Key | Description |
|---|---|---|
| Scenario Name | scenario_name | Required. |
| Trigger Payload (JSON) | trigger_payload | For example {"initial_message": "Hello"}. |
| Expected Final State (JSON) | expected_final_state | Expected outcome. |
| Expected Node Path | expected_node_path | Comma-separated node IDs. |
| Target Metrics | target_metrics | Any of AnswerRelevancy, Faithfulness, ContextualPrecision, ContextualRecall, Hallucination, Bias, Toxicity, GEval, Summarization, ToolCorrectness. |
Adding a Test Case node shows the Run All Tests toolbar button.
Test Case nodes can't currently be kept in a working workflow. The builder won't save a workflow with an unconnected node, and a run that reaches a Test Case node fails ("Unknown node type: TEST_CASE"). Run All Tests doesn't read these nodes anyway — it runs test scenarios saved through the API. See Testing Workflows.
Element
Shows a catalog element on the mission canvas. The editor only offers Label: set element_id (and optionally element_config) through the API. Without an element_id the node fails at run time.
Condition Branch (API only)
CONDITION_BRANCH is not in the palette. It is a labelled pass-through placed on one side of a Condition by API-built workflows. It has no settings you need to change.
Validation rules
The toolbar's Validate Workflow button (also run on every save and before Run Workflow) checks:
- the workflow has a name and at least one node
- there is exactly one Trigger node
- Loop Start and Loop End counts match, and each is paired
- every node except the Trigger is connected
- Agent, Team and Function nodes have their agent, team or function selected
- Test Case nodes have a scenario name
- For Each loops have a collection variable
POST /workflows/validate in the API also checks Condition branches (names present and unique, every branch connected, no edge routed to an unknown branch, default branch is one of the branches) and that Dropdown attributes have options.