Skip to content

The Shape of a Flow

Every flow file has the same skeleton. Most blocks are optional — a one-step flow only needs steps:.

version: "1.0.0"
status: active
environment: my-env
using:
- zenvara/http
- zenvara/jira
input:
city: !str Berlin
output:
temperature: !float
steps:
- $weather:
invoke: http.get
with:
Url: "https://api.example.com/weather?city=${city}"
- return:
temperature: "${weather.body.temp}"

Read top to bottom: declare what the flow imports, what it accepts, what it produces, and how to get from one to the other.

BlockRequired?Purpose
version:optionalFlow-format version for forward-compat; only the major is checked at load.
status:optionalactive or inactive. An inactive flow will not invoke.
environment:optionalDefault environment this flow runs against (overridable at invocation).
using:optionalImports operator families and/or bare connections (see Connections).
input:optionalThe typed input signature. Tag + optional default.
output:required where the flow returnsThe typed output contract — both docs and a runtime check.
let: / vars: / persist:optionalState blocks — see State.
triggers:optionalWhat fires the flow — see Triggers.
steps:requiredThe pipeline itself.

Inputs are declared with a type tag; the value after the tag is the default. Omit the value to make the field required.

input:
city: !str Berlin # optional, defaults to "Berlin"
limit: !int # required — no default
verbose: !bool false
tags: !str-list

Common tags: !str, !int, !float, !bool, !obj, !str-list, !obj-list. The full tag set is in the flow language reference.

The rest of this section walks each part in depth: