flowwork is a single static binary (the engine + REST API) plus flowctl, the
command-line client you use to register and drive workflows. This page gets both running and
takes a workflow from a file to a finished run.
1. Install and start flowwork
Download flowwork for your platform, set your license key (from your account page), and run it:
export FLOWWORK_LICENSE_KEY=FW-XXXXX-XXXXX-XXXXX
flowwork # starts the engine + API on :9010
That’s the whole setup. The binary brings up its own local database, applies migrations,
generates its encryption key, and seeds a default workspace — so the first command just works,
with nothing else to install. The engine serves the REST API under /api and health probes at
/health, and binds a machine slot automatically on first start. Leave it running in this
terminal.
flowctl is configured by flags or env vars — FLOWCTL_SERVER (default
http://localhost:9010/api), FLOWCTL_WORKSPACE (1),
FLOWCTL_USER (1). Add -o json for machine-readable output
and -q to print only the resulting id.
With flowwork running, open http://localhost:9010
in your browser — the built-in console lists your runs and workflows, shows each workflow’s
script and graph, and is where you connect accounts for Composio connectors.
2. Run your first workflow
Here is the smallest possible workflow — one step that returns a greeting:
// hello.js — the smallest possible workflow: one start step, then end.
function greet(ctx) {
return { greeted: true, greeting: "Hello, " + (ctx.vars.name || "world") + "!" };
}
workflow({
name: "Hello",
version: "1",
description: "Minimal one-step workflow.",
initial: { name: "world" }, // --input is merged over this at start
triggers: [apiTrigger("run")],
steps: [
step("greet", { start: true, next: "end", label: "Greet" }, greet),
],
});
Register it, start a run, and read the result:
flowctl def create --file hello.js # register the definition
flowctl run start --workflow Hello --input '{"name":"Ada"}' -q
flowctl run vars <exec> # { name: "Ada", greeted: true, greeting: "Hello, Ada!" }
run start prints the execution id (<exec>); pass it to run vars, run status, or
run watch <exec> to follow a run to completion.
Every workflow is one call to workflow({ … }) with a unique
name, at least one trigger, and a list of steps — exactly one of which has
start: true. Each step’s handler returns an object that is merged into
ctx.vars.
3. Where to next
- Tutorial: an approval workflow — add a human-in-the-loop form and watch a run park and resume.
- DSL cheatsheet — every builder, option, and condition on one page.
- Author with Claude Code — install the flowwork skill (
flowctl skill install) and set up Claude Code channels so the agent writes, runs, and drives workflows for you.