# Creating a Flow

> Build a multi-step workflow visually.

**URL:** https://inference.sh/docs/flows/creating
**Last updated:** 2026-10-13

---

Build a multi-step workflow visually.

---

## Open the editor

1. Go to [Flows](https://app.inference.sh/flows)
2. Click **New Flow**

---

## The canvas

You'll see:
- **Left sidebar** — Nodes you can add
- **Center canvas** — Where you build
- **Right panel** — Node settings

---

## Add an Input node

Every flow starts with an Input node.

1. Click **+ Input** in the sidebar
2. Click on the canvas to place it
3. Define what your flow accepts

### v2 editor

The v2 flow editor is the flow page at `/flows/{id}`.

The v2 editor places the **input** and **output** nodes on the canvas for you. They cannot be deleted.

To define the input schema:

1. On the input node, click **+ add input** to open the field palette
2. Pick a field type: text, integer, number, checkbox, list of strings, list of numbers, list of files, or file
3. Drag fields to reorder them. Each field can be edited, duplicated, or removed
4. Use the toolbar button to switch between **edit fields** and **view input**, which previews the run-time input form

A file field is stored in the input schema as `{"type": "object", "format": "file"}`. A list of files is an array whose `items` have that shape.

Example input:
```
image (file) — The image to process
```

---

## Add App nodes

1. Click **+ App** in the sidebar
2. Search for an app
3. Place it on the canvas

Add as many as you need.

In the v2 editor, click the **+** button at the bottom center of the canvas and choose **app** to open the app catalog. The same menu adds **constant**, **gate**, **selector**, and **merge** nodes.

---

## Gate nodes (v2 editor)

A gate node lets downstream steps run only when a condition is true. The platform evaluates the condition at run time against the gate's wired inputs. No app runs for the gate. See [Flows API: Gate nodes](/docs/api/rest/flows#gate-nodes) for operators and runtime behavior.

Add one from the **+** menu, then wire an upstream output into the gate's input handle. Configure the condition on the node:

| Control | Purpose |
|---------|---------|
| **field** | Input key to evaluate. When upstream nodes are connected, this is a dropdown of `{sourceNodeId}.{fieldKey}` options. Otherwise it is a text input |
| **condition** | `equals`, `not_equals`, `contains`, `gt`, `lt`, `is_empty`, or `is_not_empty` |
| **value** | Right-hand side of the comparison. Hidden for `is_empty` and `is_not_empty` |

Connect the steps that should run when the condition is true to the gate's output handle. After a run the gate shows a **passed** pill when the condition was true and a **blocked** pill when it was false. When it is false, the steps that depend on the gate do not run and the flow run still completes. See [Connecting Nodes: Gate branching](/docs/flows/connecting#gate-branching).

---

## Selector nodes (v2 editor)

A selector node picks one element from an array input at run time. See [Flows API: Selector nodes](/docs/api/rest/flows#selector-nodes).

Add one from the **+** menu and wire an upstream array output into its input handle.

| Control | Purpose |
|---------|---------|
| **field** | Array input key to read from. A dropdown of `{sourceNodeId}.{fieldKey}` options when upstream nodes are connected, otherwise a text input |
| **mode** | `first`, `last`, `index`, or `random` |
| **index** | Zero-based index. Shown when mode is `index` |

The runtime implements `first`, `last`, and `index`. With `random` it selects the first element.

Connect the selector's output handle to downstream steps.

---

## Merge nodes (v2 editor)

A merge node joins parallel branches. It runs when all of its upstream nodes have completed. See [Flows API: Merge nodes](/docs/api/rest/flows#merge-nodes).

Add one from the **+** menu and connect each branch to its input handle. The node shows how many inputs are wired in. Connect its output handle to the step that should run after all branches. See [Connecting Nodes: Merge synchronization](/docs/flows/connecting#merge-synchronization).

---

## Constant nodes (v2 editor)

A constant node outputs a fixed value at run time. It has an output handle and no input handle. See [Flows API: Constant nodes](/docs/api/rest/flows#constant-nodes).

Add one from the **+** menu, set **mode** to `fixed`, then set:

| Control | Purpose |
|---------|---------|
| **type** | `number`, `string`, or `boolean` |
| **value** | The value to emit |

The editor stores fixed values as `utility.preset: "constant"` with `utility.constant`. Connect the output handle to a downstream input.

The **mode** control also offers **random** with **min** and **max**. The editor writes `utility.random: true` with `utility.random_min` and `utility.random_max`. At run time the constant emits a random integer in `[min, max)` (defaults `0`–`1000000` when bounds are omitted). See [Flows API: Constant nodes](/docs/api/rest/flows#constant-nodes).

---

## Add an Output node

Every flow ends with an Output node.

Define what your flow returns.

In the v2 editor the output node is already on the canvas. Wire upstream nodes into it, then use the switch on each field to include it in the flow's output. Use the pencil icon to rename an output key.

---

## Connect the nodes

See [Connecting Nodes](/docs/flows/connecting).

---

## Run the flow

Click **Run** and provide the input.

Watch each step execute.

In the v2 editor, utility node borders follow run status: purple while ready or running, green when completed, red when failed or cancelled, grey when blocked. Constant and merge nodes show their value (for example `→ 42`) once it is available. App nodes show task status colours in output mode.

The output panel shows the flow's output when it arrives. If the run ends without output, it shows **no output yet** for a completed run, the error for a failed run, and **flow cancelled** for a cancelled run.

→ [Flow Execution](/docs/flows/overview#flow-execution)

---

## Next

→ [Connecting Nodes](/docs/flows/connecting)
