# Flows

> Flows chain multiple apps together.

**URL:** https://inference.sh/docs/concepts/flows
**Last updated:** 2026-09-20

---

Flows chain multiple apps together.

---

## Why flows?

Some tasks need multiple steps:

```
Generate image → Upscale → Remove background → Resize
```

Instead of running each manually, create a flow that does all four.

---

## How flows work

```
Input → App A → App B → App C → Output
```

Each app's output becomes the next app's input. The runtime runs steps in order; when a step fails, the flow stops and the run is marked failed.

Besides app nodes, a flow can contain utility nodes. The flow runtime evaluates them inline and they create no task:

- **Gate**: lets downstream nodes run only when a condition is true. A false condition blocks the nodes that depend on the gate and does not fail the run. See [Flows API: Gate nodes](/docs/api/rest/flows#gate-nodes).
- **Selector**: picks one element from an array input. See [Flows API: Selector nodes](/docs/api/rest/flows#selector-nodes).
- **Merge**: joins parallel branches. It runs when all of its upstream nodes have completed. See [Flows API: Merge nodes](/docs/api/rest/flows#merge-nodes).
- **Constant**: emits a fixed value. See [Flows API: Constant nodes](/docs/api/rest/flows#constant-nodes).
- **Utility**: evaluates a custom CEL expression against its inputs. See [Flows API: Utility nodes](/docs/api/rest/flows#utility-nodes-custom-cel).

---

## Flow runs and tasks

Every flow run creates a **parent task** that tracks the full execution — inputs, per-step progress, final output, and status.

| Trigger | What you see in Tasks |
|---------|------------------------|
| Run from the workspace | One task for the flow; step status in the task detail view |
| Agent calls a flow as a tool | One task for that flow invocation |
| `POST /run` on a deployed flow app | One task; optional `webhook` fires when the parent task completes |

Individual app steps execute inside the flow run. You do not manage each step as a separate top-level task from the API.

`POST /flowruns` and `belt flow run` run the flow's published version when one exists, and the draft otherwise. The run's `flow_version_id` identifies the version that ran.

→ [Tasks](/docs/concepts/tasks) — status, cancellation, cost, and completion webhooks  
→ [Flows API](/docs/api/rest/flows) — create, edit, duplicate, and deploy flow definitions  
→ [Flow Runs API](/docs/api/rest/flow-runs) — `POST /flowruns`, list, cancel, and SSE streams

---

## Creating flows

Use the visual editor:

1. Drag apps onto the canvas
2. Connect outputs to inputs
3. Run the whole thing

→ [Creating a Flow](/docs/flows/creating) — editor walkthrough, including [gate](/docs/flows/creating#gate-nodes-v2-editor), [selector](/docs/flows/creating#selector-nodes-v2-editor), [merge](/docs/flows/creating#merge-nodes-v2-editor), and [constant](/docs/flows/creating#constant-nodes-v2-editor) nodes  
→ [Connecting Nodes](/docs/flows/connecting) — mapping data between steps

---

## Flows as tools

Once created, a flow can be:

- Run directly from the workspace
- Added as an **agent tool** (the agent sees one tool; the runtime runs every step)
- Deployed as a standalone app with its own `POST /run` endpoint

When an agent invokes a flow, the parent agent turn waits for the flow task to finish (same join behavior as app tools and sub-agents in a parallel turn).

→ [Flows guide](/docs/flows/overview) — agent tools, deploy-as-app, execution UI

---

## Next

→ [Agents](/docs/concepts/agents)  
→ [Tasks](/docs/concepts/tasks)
