> For the complete documentation index, see [llms.txt](https://tinyhumans.gitbook.io/openhuman/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tinyhumans.gitbook.io/openhuman/features/workflows.md).

# Workflows

<figure><img src="/files/lQkaydQOHvTroinFWQwC" alt=""><figcaption><p>A workflow on the visual canvas. The agent proposes the graph; you review each step and save.</p></figcaption></figure>

Chat is great for one-off asks. **Workflows** are for the things you want done *every time*: triage every new support email, file every Linear ticket that mentions your team, post a digest every Monday at 9. Heavily inspired by [n8n](https://n8n.io) and [Zapier](https://zapier.com), a workflow is a saved, typed graph of steps you can see on a canvas and that runs without you. It is backed by the open-source [tinyflows](https://github.com/tinyhumansai/tinyflows) engine and the same trust and approval machinery as the rest of OpenHuman. The difference from n8n and Zapier: you don't build the graph, the agent does.

## The agent builds it, you approve it

You don't drag boxes to get started. Describe the automation in chat, for example *"whenever a new email arrives from a customer, summarize it and post to my Slack"*, and the agent uses its `propose_workflow` tool to draft a complete workflow graph. The proposal shows up in chat as a **Workflow Proposal Card** with a plain-English summary of every step.

Two design guarantees make this safe:

* The `propose_workflow` tool **only validates and describes** a candidate graph. It can never create or enable a flow by itself.
* The **only** path from a proposal to a saved workflow is you clicking **Save & enable** on the card. That calls the `flows_create` RPC directly from the app, not from the agent.

## What a workflow is made of

A workflow graph is composed of **12 node kinds**: exactly one `trigger`, plus any mix of `agent` (a full agent turn with tools), `tool_call`, `http_request`, `code` (JavaScript or Python), `condition`, `switch`, `transform`, `split_out`, `merge`, `output_parser`, and `sub_workflow`.

Triggers come in several kinds. The ones live today:

* **Schedule**: cron-backed; the flow fires on its schedule and re-registers itself on every app boot.
* **App event**: a live [trigger](/openhuman/features/integrations/triggers.md) from a connected integration (a new Gmail thread, a Notion change, a Linear ticket) matched by toolkit + trigger slug.
* **Manual**: a Run button on the Workflows page or the `flows_run` RPC.
* **Resume**: continuing a run that paused at an approval gate.

A per-flow dispatch lock means a schedule burst can never run the same flow twice concurrently.

## Trust, approvals, and human-in-the-loop

Every flow run executes under a dedicated trust origin (`TrustedAutomation → Workflow`). The reasoning: the flow's *actions* (which tools it calls, which URLs it hits) are static graph configuration you approved at save time. The runtime trigger payload (a webhook body, an inbound event) stays **untrusted**: it can feed arguments into those pre-declared actions, but it can never introduce a new action.

On top of that, each flow has a **"Require approval for outbound actions"** switch. With it on, every external-effect tool or HTTP call in the run parks at the [approval gate](/openhuman/features/approval-gate.md) and waits for a real decision. The run's trust root does not auto-allow anything.

When a run pauses, you get a **Flow Approval Card** in your notifications naming the flow and the pending steps. Approve resumes the run (via `flows_resume`) exactly where it stopped. Runs are durable and checkpointed, so "later today" is fine.

## Watching it run

* **`/flows`**: the Workflows hub, showing every flow with its enabled toggle, last-run status (`completed` / `pending approval` / `failed`), and a Run button.
* **`/flows/:id`**: a read-only **canvas view** of the workflow graph, rendered as nodes and edges so you can see exactly what you approved.
* **Run Inspector**: a drawer showing each run step by step (node label, emitted output, and final status), live-polling every 2 seconds until the run finishes.
* Full **run history** is persisted per flow: status, start/finish times, pending approvals, errors, and reconstructed per-step output.

## RPC surface (for developers)

The `flows` domain (`src/openhuman/flows/`) exposes ten controllers under `openhuman.flows_*`: `create`, `get`, `list`, `update`, `delete`, `set_enabled`, `run`, `resume`, `list_runs`, `get_run`. See the [Agent Harness](/openhuman/developing/architecture/agent-harness.md) page for how flow runs share the tinyagents execution stack.

## See also

* [Triggers](/openhuman/features/integrations/triggers.md): the live app events that fire `app_event` workflows.
* [Approval Gate](/openhuman/features/approval-gate.md): how pending approvals are surfaced and expire.
* [Cron & Scheduling](/openhuman/features/native-tools/cron.md): one-shot and recurring agent jobs (workflows are the structured, multi-step upgrade).
* [Subconscious Loop](/openhuman/features/subconscious.md): the background awareness layer that complements event-driven workflows.
