Every capability on this page is included in both FirstFlow Cloud and the
open-source self-hosted build no edition split, no feature gating, no usage
limits. See Self-hosting.
Where most people start
Pick the entry point that matches what you are doing right now. Everything else on this page is reachable through inline links in the relevant section.Quickstart
Wrap your LLM client, mount the provider, and see a widget in minutes.
How it works
The server-decides / browser-renders runtime loop, end to end.
Browser SDK
@firstflow/react render pushed experiences in your chat UI.Server SDK
@firstflow/sdk wrap your LLM client to observe and power targeting.How the pieces fit
Eligibility triggers, audience, schedule, frequency, and the LLM classifier is evaluated server-side. When a user qualifies, FirstFlow composes the widget (for guides, Anthropicclaude-sonnet-4-6 renders a WidgetTree) and pushes the
finished tree over Socket.IO. The browser SDK is a passive consumer: it renders
what arrives and reports activity back. You cannot trigger a widget purely from the
client your server SDK observes the turn, and the server decides.
The diagram below traces one turn from the user’s message to a rendered widget and
back. Note that flow navigation (flow.next / flow.back) is resolved on the
server too the browser only emits the intent.
This is why instrumentation matters: the server can only target and analyze what
it observes. Tag every observed LLM call with all three identifiers
(firstflowAgentId, sessionId, userId) or the call passes through unobserved.
The rest of this catalog is the surface area on top of that loop.
In-chat experiences
An experience is one thing you deliver to users inside the chat no popups, no second surface to maintain. Itstype is chosen at creation
and is immutable, and it determines both how the experience renders and which node
types the editor offers. There are four:
- Guide a single AI-composed widget. The backend walks a flow graph to a result node, then composes a rich widget from the live conversation context. Best for in-context answers, dynamic CTAs, and walkthroughs that adapt to the user.
- Tour a multi-step authored sequence of styled message cards, for guided feature walkthroughs.
- Survey structured data collection answered natively in chat: NPS, opinion scales, multiple choice, checklists, and open questions.
- Announcement a one-shot in-chat notification or feature banner.
draft / active / paused).
Two cross-cutting capabilities sit alongside the four types. Slash
commands are agent-configured shortcuts a user runs from the
composer each command either triggers an experience (the backend pushes it) or
emits an app action your code handles. The renderable surface itself is the
WidgetTree: a small declarative document of block
primitives layout (stack, row, card), content (title, text, media),
interactive (button, text_input, slider, rating), and compound (carousel,
checklist). Text and inputs bind to widget state with a ref, and buttons fire
local, host, or remote actions.
A command is just data on the agent, read from useFirstflow().commands:
Authoring
You build the flow behind an experience three ways: by hand in the visual editor, by AI generation (describe it in plain language and FirstFlow generates the flow, streamed live as it builds), or by importing from a URL (point at a help article or feature page and FirstFlow extracts it into a flow). All three produce the same artifact a{ nodes, edges } graph the backend
walks at runtime.
A flow branches and acts. Classify nodes route the flow with an LLM, using a
provider/model, custom instructions, a confidence floor, a resolution mode, and a
fallback branch for low confidence or errors. Decision nodes branch on rules
against traits.* and answers.* (AND within a branch, OR across branches; first
match wins). Action nodes call external systems mid-flow see
API calls, Webhooks, and
Slack. For guides, a terminal Result node holds the
instruction the backend composes into a widget.
The editor graph you touch is flow (it carries UI chrome). On every save the
backend derives a normalized flowRuntime from it chrome stripped, edges
validated and that is what runs. You only ever edit flow. Match the widget to
your product with design tokens in Theming.
Targeting
Triggers and audience decide when an experience appears and who sees it both evaluated entirely server-side, so the browser cannot force a widget to show. Triggers are events:chat_open,
after_user_message, after_idle, on_custom_event, and the LLM
conversation_classifier gate (with guides also supporting
after_user_and_agent_message). A classifier trigger runs an LLM gate before
showing you configure instructions, provider/model, a confidence floor, a TTL, a
resolution mode, the context window, and signal masking for intent-driven
experiences like “offer help when the user seems stuck.”
Audience decides who is eligible: all users, or only those
in a named segment computed from trait rules. Targeting needs data to match
against, so pass user traits via the browser user prop or the
server identify() helper. Experience settings also carry
schedule (start/expire), frequency (once, limited, or always guides default
to always), priority when multiple experiences qualify, device, and placement.
Analytics & sessions
Once your conversations are observed by the server SDK, the dashboard turns them into product understanding see Analytics & sessions. The richer your instrumentation (observe() and trace()), the more these
surfaces can show.
- Conversation analytics volume, generations, total cost, latency, and error rate over a date range.
- Sessions every conversation’s full transcript side-by-side with the LLM trace waterfall (model, tokens, latency, cost), plus tags and notes for review.
- Session KPIs LLM-graded quality evaluators scored per session: task completion, user friction, agent confusion, response quality, and user satisfaction, plus your own custom evaluators.
- Topics & sentiment automatic topic, intent, and sentiment classification against a taxonomy you curate.
Developer platform
FirstFlow ships two SDKs, a realtime widget, and an MCP server. The browser SDK (@firstflow/react) opens the realtime connection,
renders pushed widgets, and handles end-user identity, client analytics, slash
commands, and theming. Mount the provider once and drop in the
widget:
@firstflow/sdk) wraps your existing LLM client
so every turn, trace, token count, and cost flows to FirstFlow which is also what
powers user-message triggers and classifier context. Wrap once and tag each call
with the three required identifiers; the wrapper strips them before the request
reaches OpenAI or Anthropic:
@firstflow/sdk/aiclient), plus LangChain / LangGraph. The
fire-and-forget helpers observe(),
trace(), outcome(), and
track() / identify() never throw and never block the
request. For Next.js, @firstflow/nextjs re-exports the React
client and exposes /server subpaths.
Beyond the SDKs, AI Connect (MCP) lets any MCP-compatible coding
agent Claude Code, Cursor, Claude Desktop read your product context and build
experiences as tools, over OAuth 2.0 + PKCE. The realtime
widget is the server-pushed surface itself, authenticated with a
browser-safe publishable key.
Integrations
Flows reach outside FirstFlow through action nodes, and the platform connects to LLM providers and your tools:- Slack post messages and DMs from a flow.
- Webhooks deliver flow events to your endpoints, signed and retried with exponential backoff.
- API calls fetch external data inside a flow and feed it to downstream nodes.
- AI providers Anthropic, OpenAI, Cloudflare Workers AI, or any OpenAI-compatible endpoint; assign which model powers each AI feature.
Open source & self-hosting
The entire platform dashboard, API, and SDKs is MIT licensed and self-hostable on your own infrastructure with no lock-in; start at Self-hosting. When you read or write these docs with a coding agent, the AI-friendly docs (llms.txt, per-page
Markdown, and Ask-AI) keep your agent grounded in current API surface.