{ nodes, edges }. You assemble that graph in the visual editor, generate it from
a plain-language prompt, or extract it from an existing URL, then layer in
branching and side-effects. This page is the map of what the editor gives you and
how each capability behaves at runtime.
The mechanism matters because it explains the limits. The graph you draw is the
authoring graph, stored as the flow field (React Flow { nodes, edges, viewport }, including editor chrome). On every save the backend derives a second,
normalized runtime graph flowRuntime with chrome stripped and edges
validated. You only ever edit flow; the backend walks flowRuntime. At runtime,
once a user is eligible, the backend walks the runtime graph
edge by edge evaluating decisions, running actions, and (for guides) composing a
widget at the terminal node then pushes the finished result over Socket.IO. The
browser SDK is a passive consumer; nothing in authoring runs in
the browser.
Build the flow
Three entry points produce the sameflow JSON. Pick whichever gets you to a
working draft fastest, then refine in the editor they are not mutually
exclusive.
The visual flow editor is the canonical surface: drag nodes onto the canvas,
connect them with edges, and configure each node in its side panel. Which node
types appear is governed by the experience type a survey exposes question
nodes, a tour exposes message/card nodes, a guide exposes a single Result node.
See Flows & nodes for the full node registry.
AI generation turns a plain-language description into a complete flow,
streamed live as the graph builds. Describe the outcome (“a 3-question NPS survey
that thanks promoters and asks detractors what went wrong”) and FirstFlow lays out
the nodes and edges for you. It is the fastest way to a first draft of a multi-step
experience; you then tune wording,
branching, and targeting by hand.
Import from URL points at an existing help article or feature page and extracts
its content into a flow useful when you already have written documentation and
want it delivered in-chat as a guide rather than rewritten from scratch.
After a flow exists, the AI chat assistant edits it conversationally: ask for a
change (“add a follow-up question for detractors”, “make the CTA say ‘Start free
trial’”) and the assistant rewrites the graph in place, so you can iterate without
hand-wiring every edge.
Branch the flow
Branching is what makes an experience adaptive instead of linear. Two node types split the graph, and they differ in how the branch is chosen. A classify node branches with an LLM. You configure the provider and model, custom instructions, a confidence floor, which signals the model sees (the latest message, a conversation digest, metrics), a resolution mode (blocking waits for the verdict; optimistic proceeds and corrects), a TTL, and a fallback branch taken when confidence is below the floor or the call errors. Use it for intent-driven routing “send users asking about billing down the upgrade path”. A decision node branches with rules (legacy; hidden by default). Each branch is a set of conditions tested againsttraits.* and answers.*; conditions combine
with AND within a branch and OR across branches, and the first matching branch
wins. The operator vocabulary is shared with targeting see the
condition operators reference.
Both branch types are evaluated server-side as the backend walks the runtime
graph, so the browser never sees the branching logic or the data it tests against.
Run side-effects mid-flow
Action nodes let a flow do something in the outside world before it reaches its result fetch live data, notify a system, or message a channel. All run on the backend, so endpoints and credentials are never exposed to the browser.1
Fetch live data with an API Call node
An API Call node performs a server-side HTTP fetch
mid-flow and feeds the response into the flow context. Downstream nodes —
including a guide’s widget composition can reference that data, so a widget
can show the user’s real plan limits or order status.
2
Notify your systems with a Webhook node
A Webhook node sends an HTTP request to your endpoint
when the flow reaches it. Delivery is backed by an outbox table with a retry
worker and exponential backoff, so a transient failure on your side does not
drop the event.
3
Post to a channel with a Slack message node
A Slack node posts a message or DM for example,
alerting a sales channel when a high-value account triggers an experience.
Compose the widget (guides)
For guide experiences the flow has no authored UI its terminal Result node holds an instruction, not a layout. When the walk reaches it, the backend composes aWidgetTree
from the conversation context using Anthropic (claude-sonnet-4-6), then pushes
that tree over Socket.IO for the browser to render. This is why a guide’s output
adapts to the conversation while a tour’s stays fixed: the guide is composed
fresh at runtime, the tour is authored block-by-block.
Tours, surveys, and announcements are the opposite end you author each step
explicitly with message, card, and question nodes, and the runtime renders exactly
what you built. The block primitives those steps render into are documented in
Widgets & blocks.
Theme and preview
Style the widget with light/dark design tokens from the agent’s Appearance page; tokens are delivered over the realtime connection and applied with no code. You can override them per instance in code via thetheme prop on
FirstflowWidget see Theming for the full
token list.
Before publishing, test the experience in the preview simulator: it runs the
flow in a simulated chat so you can step through branches, answer questions, and
see the composed widget without affecting real users or analytics.
Eligibility which users see an experience and when is configured separately
from the flow, in the experience’s triggers and audience
settings, and is evaluated server-side. Authoring decides what the experience
is; targeting decides who gets it and when.