Skip to main content
flow_data is the JSON document that defines a SuperFlow workflow graph. The workflow endpoints accept it in three places: Create Workflow, Update Workflow, and inline in Execute Workflow. This page describes the envelope, the node object, connections, and the expression syntax. The full catalog of node types lives in the node types reference.
If you build workflows in the Studio editor, you rarely need this page. It exists for callers who construct or modify flow_data programmatically. For a task-oriented walkthrough of the same concepts in the UI, see the SuperFlow node reference.

Envelope

flow_data is a JSON object describing a directed graph of nodes. The engine recognizes the following top-level keys and ignores any others. The engine validates the document on submission. The nodes array must be non-empty, and there must be exactly one node of type lyzr-nodes-base.trigger; zero trigger nodes or more than one is an error. Connections whose source name does not match a real node are ignored, as are connection targets that are empty or reference a non-existent node.

Node object

Each entry in nodes is an object with the following keys.

Connections and error edges

connections is keyed by the source node’s name, not its id. Each value is an object with two optional keys, main for the success path and error for the failure path. Both keys have the same shape: an array of output slots, where slot i (for example main[i]) is itself an array of target objects. The slot index is the source node’s output index. Each target object has three keys. When a node has handleErrors: true in its parameters and fails permanently, downstream execution follows its error edges instead of aborting the run. Without handleErrors, a permanent failure aborts the run. error slots use the identical nested shape as main.

Loopback edges

Any edge that connects a node back to one of its upstream nodes is a loop. The target of that back-edge is the loop’s head, and the region between the head and the node that feeds the back-edge runs again each time items arrive on the back-edge. In the default while mode, the loop ends when the node that feeds the back-edge stops sending items to it. You configure each loop in settings.loopConfig, keyed by the name of its head node. A loop whose region overlaps another loop’s region, or that sits inside a Loop node’s body, is reported as a cycle validation error. For a loop that stops on a condition or a budget, use the Loop Until node, whose Continue output is its back-edge.

Workflow settings

The settings object holds workflow-level settings. The following keys control loopback edges. Each loopConfig entry takes the following keys.

Expression syntax

Before a node runs, its parameters are resolved recursively. For every string value at any depth, including strings nested in objects and arrays, the engine first strips a single leading = (the expression-mode prefix, as in "={{ $json.x }}"), then resolves every {{ ... }} block. If the whole string after the = prefix is exactly one {{ ... }} block, the resolved value keeps its native type (number, boolean, object, or array). Otherwise each block is interpolated into the surrounding string: primitives become text, and objects and arrays are JSON-encoded. The practical consequence is that every string parameter on every node supports expressions. The following forms are supported inside {{ }}. Dot-paths traverse object keys and array indices, for example results.0.name. A missing key or an out-of-range index yields null. A bare reference such as $json.x, $('N').json.x, or $node[...] is resolved directly with its native type preserved. An expression containing operators, arithmetic, or concatenation, such as {{ $json.score % 2 }}, is evaluated as JavaScript after each reference is substituted with its JSON value; a runtime error yields null.

Loop variables

Inside a loop region, expressions can read $loop. Outside a loop, $loop is null.
$items is not available in workflow expressions. Only $json, $input, $node[...], and $(...) are supported. $items exists only inside the Code node’s JavaScript sandbox.

Complete minimal example

The following document defines a trigger feeding a Set node, with one main connection.
Three details in this example are worth calling out. connections is keyed by node name (“Trigger”), not by id. main[0] is output slot 0, and its inner array holds the targets fed from that slot. The = prefix marks the Set value as an expression, so {{ $json.name }} resolves against the trigger’s output item.

Validation

Every workflow is checked against the published contract for each node type, as returned by the node catalog: which parameters a node accepts, what it emits, and how many inputs and outputs it has. The check runs in three places:
  • Validate Workflow runs it on demand without saving.
  • Create Workflow and Update Workflow run it on save and return the result as issues. The save still succeeds, so fix any errors before you run the workflow.
  • Execute Workflow refuses a run before it starts, with 400 and {"error": "invalid workflow: ..."}, when a node reachable from the trigger has an unknown type or a connection from an output it does not have. Nodes that are not reachable from the trigger are ignored, so an orphaned node never blocks a run.
Each issue has a severity. An error means the workflow cannot run or a node is certain to fail, and a warning means it runs but probably not as intended. Errors are listed first. The issue codes are invalid_json, no_nodes, trigger_count, unknown_node_type, missing_parameter, invalid_parameter, unknown_parameter, conditional_requirement, empty_configuration, duplicate_node_name, cycle, output_index_out_of_range, input_index_out_of_range, edge_from_terminal_node, edge_into_trigger, loop_without_body, unknown_connection_endpoint, unreachable_node, unwired_output, expression_unknown_node, expression_not_ancestor, and expression_unknown_field. A few codes need more context:
  • unknown_parameter comes with a hint that suggests the closest known parameter name.
  • cycle flags a loopback edge whose region overlaps another loop’s region or sits inside a Loop node’s body.
  • unreachable_node flags a node that is not connected to the Trigger, so it never runs.
  • expression_unknown_node, expression_not_ancestor, and expression_unknown_field check $('Node').json.field and $json.field references against what the upstream node actually emits.

Next steps

Every node type, with its parameters and outputs, is documented in the node types reference. To submit a document like the one above, see Create Workflow.