Skip to main content
FlowFn
IntegrationsTemplatesPricingDocsBlogSign inStart free
All posts
workflowstutorialgetting-startedautomation

Building Your First FlowFn Workflow: A Visual Tour of Every Node Type

How to turn an inbound lead into a scored, routed, human‑approved pipeline — and meet all eleven workflow node types along the way.

F

FlowFn Team · Product

13 Jul 2026 · 12 min read

Most "automation" tutorials stop at "when X happens, send a Slack message." Real business processes are messier: something arrives, an AI reads it, a decision splits the path, data gets written somewhere, a human signs off, and only then does the email go out.

FlowFn workflows are built for exactly that. A workflow is a visual graph of nodes — a trigger that starts the run, and a chain of tasks that each do one job and pass their results to the next. There are eleven task types plus triggers, and by the end of this guide you'll have seen every single one in context.

We'll build one realistic workflow end to end: Lead Qualification & Routing. A lead lands via webhook, an AI model scores it, a condition splits hot from cold, hot leads get written to a CRM sheet + a Slack alert + a manager's approval before a discount email goes out, and cold leads drop into a nurture email. Then we'll tour the remaining nodes (Code, Loop, Parallel, Data Visualizer) that power heavier flows.

Every screenshot below is the real FlowFn builder.


Where workflows live

Workflows are one of the artifacts your App owns. From the dashboard, open Workflows to see everything you've built, each card showing its status and the mix of node types inside it.

The FlowFn workflows list

Hit New workflow, give it a name, and you land in the builder — an infinite canvas with an Add Node button in the top‑left and Test Run / Save in the top‑right.


The anatomy of a workflow

Here's the finished flow we're about to build. Read it left to right:

The full Lead Qualification & Routing workflow on the canvas

Three things to notice:

  • Triggers sit on the left (the ⚡ nodes). This workflow has two — a Webhook for real‑time leads and a Scheduled trigger to re‑score stale ones nightly. Both flow into the same first task via a Start edge.
  • Tasks are the coloured cards. Each shows its title, its type, and its reference code (the handle other tasks use to read its output).
  • Edges carry the run from one node to the next: a normal Next edge, or — from the orange Condition node — a green Yes branch and a red No branch.

That branching is the whole point. Let's build it.


Step 1 — Start with a Trigger

A Trigger is the entry point. It defines how a run starts and hands the incoming payload to everything downstream as {{$trigger…}} references. Click Add Node → Trigger and you get a picker with seven kinds:

The trigger editor: seven trigger types and the webhook configuration

Trigger Fires when…
Webhook an external system POSTs a JSON payload to a public FlowFn URL (signature‑verified)
Scheduled a repeating interval or specific UTC time is reached
API your own backend calls the FlowFn API with the configured HTTP verb
Form a published FlowFn form is submitted
Playground a button @key in a playground fires
Workflow another workflow completes
Agent an AI agent calls this workflow as a tool

We pick Webhook. FlowFn generates a public POST endpoint you point your lead source at (a landing‑page form, Typeform, HubSpot, Stripe…). Paste the provider's signing secret and FlowFn verifies every delivery; paste one real payload as the sample and it derives the field paths (data.object.email, company, …) that show up in the reference picker downstream.

Tip: A workflow can hold several triggers. We added a second Scheduled trigger so the same pipeline can also run as a nightly batch — no duplicate logic.


Step 2 — Normalize with Trigger Inputs

The moment you have more than one trigger, their raw field names diverge — a form calls it email, a webhook calls it contact.email. The Trigger Inputs node fixes that. It defines one unified set of output keys, then lets you map each trigger's raw fields into them, so every task downstream reads one stable shape.

The Trigger Inputs node: unified outputs plus per-trigger mapping

Here we declare three unified outputs — email, company, budget — and map both the Webhook and the Scheduled trigger into them. It must be the workflow's start node, and it only unlocks once you have two or more triggers (it's meaningless with one).


Meet the node palette

Click Add Node and you see the full toolbox, grouped into Trigger, Action, and Logic:

The Add Node palette showing all node types

That's the entire vocabulary of a FlowFn workflow:

  • Action nodes do something — call an AI, hit an integration, run code, render text, read/write data, append to a chart, pause for a human.
  • Logic nodes control the flow — branch, loop, or fan out.

We'll use most of them right now, then cover the rest in the tour.


Step 3 — Score the lead with an AI Model

The AI Model node runs one LLM call. You pick a provider registry (e.g. OpenAI / Anthropic / Gemini, in a text or structured flavor), pick a model, and write an instruction. FlowFn automatically injects the trigger inputs and every earlier task's outputs as context, so the model already "sees" the lead.

The AI Model node configured with provider and model

The real power is structured output: define output fields like score (number), summary (text), and segment (text), and a structured registry forces the model to return valid, typed JSON. Those become {{$task.<ref>.outputs.score}} for the next node.

Runs use FlowFn's platform AI key when your plan allows, or your own key (BYOK) via a team connection — the amber "no connections" hint just means you haven't linked one yet.


Step 4 — Branch with a Condition

The Condition node is FlowFn's fork. It evaluates a single expression — a left value, an operator, and (for binary operators) a right value — and routes the run down exactly one of two wired paths.

The Condition node: operator, operands, and Yes/No branches

Here: openai.outputs.score greater than 80. Operators cover both comparison (equals, not equals, greater, less, contains) and inspection (is empty, is not empty). It's fully deterministic and rule‑based — no AI is involved in the decision. A Condition has no ordinary "Next"; the only way forward is the green If true → run branch (here, Add to CRM) or the red If false → run branch (here, Nurture email).


Step 5 — Persist to a Data Sheet

Hot leads should land in your CRM. Data Sheets are FlowFn's built‑in tabular store (Database → Sheet → rows). The Data Sheet node reads or writes rows as a workflow step.

The Data Sheet node set to Create against the CRM → Leads sheet

Pick an operationRead (query), Fetch last, Fetch Nth, Create, Edit, Upsert, or Delete — then pin a database and sheet. We use Create on CRM → Leads and map the cells from trigger and AI outputs. Edit/Upsert/Delete locate a row via a match filter ({ "email": "{{$trigger.email}}" }); upsert inserts when nothing matches.


Step 6 — Notify with a Platform Tool

Platform Tool nodes run a single action on a third‑party integration — Slack, HubSpot, Gmail, Stripe, Jira, custom webhooks, and more.

The Platform Tool node running Slack → Post a message to a channel

Pick the platform (Slack), pick one of its actions (Post a message to a channel), and bind the team connection whose OAuth/API credentials get injected at run time — you never paste secrets into the node. Fill the action's inputs with literals or {{ }} references (the channel, and a message wired from the lead's data). Behind the scenes FlowFn checks your plan can use the tool and that any paid integration has an active subscription.


Step 7 — Gate it with an Approval

Before a discount goes out, a human should sign off. The Approval node is a human‑in‑the‑loop gate: when the run reaches it, FlowFn pauses the run, emails your chosen approvers an approve/reject link, and waits.

The Approval node with two approvers, a threshold, and a templated email

Choose approvers from your team, set a minimum approvals threshold, and customize the email — the Subject and Message accept {{ }} placeholders so reviewers see real context (Approve 15% discount for {{$task.openai.outputs.summary}}). Approvers can decide on a sign‑in‑free public page (authorized by a signed link) or on the dashboard. The run resumes once the threshold is met; enough rejections fail it. The approver list is snapshotted when the email sends, so editing the workflow later won't disturb in‑flight approvals.


Step 8 — Compose the email with a Template

Finally, render the outbound email. The Template node builds text, HTML, or JSON from a body of {{ }} placeholders — no code required.

The Template node rendering an HTML offer email

Pick an output type (Text / HTML / JSON) and write the body, pulling in data with {{$trigger.…}} and {{$task.…}} references. Beyond simple substitution, Template supports path‑based blocks — {{ff-if …}}…{{/ff-if}} and {{ff-each item in …}}…{{/ff-each}} — for conditional and repeating sections. The rendered string is exposed downstream as content, ready to feed a Platform Tool that actually sends it.

That's the full hot‑lead path — and the cold path is just a second Template node for the nurture email. Eight node types, one coherent flow.


The rest of the toolbox

Four node types didn't fit our lead flow but are essential for heavier workflows. Here's each one.

Code — your escape hatch

When no pre‑built node expresses the transform you need, the Code node runs a snippet of JavaScript in a locked‑down sandbox and hands its return value on as the task's outputs.

The Code node with an AI-generate panel and a JS editor

It's a real V8 sandbox (30‑second timeout, 128 MB cap) — not Node.js: no require, fetch, process, or filesystem (use a Platform Tool for HTTP). Any {{ }} placeholders in your code are resolved to real literals before it runs, so you can pull in trigger data, prior outputs, and loop counters type‑safely. Declare your output fields, and whatever you return is validated against them. There's even a Generate with AI panel that writes the JavaScript from a plain‑English description.

Loop — repeat a stretch

The Loop node repeats a segment of your flow a fixed number of times, with an optional pause between passes.

The Loop node with max iterations and delay

Despite the palette subtitle, it isn't a classic for‑each — there's no array source. It's a fixed‑count repeater (1–20 iterations, plus a 0–60000 ms delay). You place the Loop node at the end of the stretch you want to repeat and drag its top handle back to the first task of that stretch. Body tasks can read {{$loop.iteration}} and {{$loop.max_iterations}} to vary behavior per pass — perfect for rate‑limited retries or paged fetches.

Parallel — fan out and join

The Parallel node fans a single flow into several branch tasks, then waits for all of them before continuing.

The Parallel node with two branches

Point it at a set of existing tasks (here Ship item and Update dashboard); when the run hits the node, every branch executes and the node succeeds only once all finish — an implicit "wait‑for‑all" join, after which the flow resumes from the Parallel node's own Next. (Accuracy note: branches run one after another in list order under the hood, so a later branch can read an earlier one's output — but the join always waits for the whole set.)

Data Visualizer — feed a live chart

The Data Visualizer node appends one row per run to an existing Visualizer, so your workflow's results show up as a live chart or table.

The Data Visualizer node selecting a target visualizer

Point it at a pre‑built Visualizer in the same App and map its fields to your task outputs. It's a terminal node — it writes a row and exposes nothing useful downstream — so build the Visualizer (and its columns) first, then let every run drop in a fresh data point.


Test it before you ship

Don't publish blind. Hit Test Run to open the test drawer, choose which trigger to simulate, paste a sample payload, and run the whole flow once end to end.

The Test Run drawer with a webhook payload editor

You'll get a full run record — each task's inputs, outputs, and timing — so you can confirm the AI scored correctly, the condition branched the right way, and the approval email would fire, all before a single real lead is touched. When it's green, Save and activate.


The eleven node types at a glance

Group Node What it does
Trigger Trigger Starts the run (webhook / scheduled / API / form / playground / workflow / agent)
Action AI Model Calls an LLM for text or schema‑validated JSON
Platform Tool Runs one action on an integration (Slack, HubSpot, Gmail…)
Code Runs your JavaScript in a sandbox
Template Renders text / HTML / JSON from {{ }} placeholders
Data Sheet Reads/writes rows in a FlowFn Data Sheet
Data Visualizer Appends a row to a Visualizer chart/table
Trigger Inputs Unifies multiple triggers into one shared input shape
Approval Pauses for human sign‑off
Logic Condition Branches yes/no on an expression
Loop Repeats a segment a fixed number of times
Parallel Fans out to branches and joins

Wrap‑up

The pattern that makes FlowFn click: triggers bring data in, action nodes do the work, logic nodes shape the path, and {{ }} references thread the outputs from one node into the next. Our lead‑qualification flow used eight of the eleven node types without a line of glue code — and the remaining three (Code, Loop, Parallel) are there the moment you outgrow the pre‑built ones.

Start small: a trigger, an AI Model, and a Condition already give you an intelligent, branching automation. Then grow it — add a Data Sheet to remember, a Platform Tool to act, an Approval to stay in control. Test Run early and often, and ship when it's green.

Build your first one, and tell us what you automated.

Build your first workflow today

Start free — connect your apps, add AI, and ship an automation you can actually maintain. No credit card required.

Get started free