Skip to main content
FirstFlow is the onboarding and activation layer for AI agent and chat products. You author experiences guides, tours, surveys, announcements that render inside the conversation, decide who sees them and when on the server, and ship them with two SDKs plus an MCP server. This page is the full catalog: read it top-to-bottom for the mental model, or jump to the category you need. The capabilities below are not independent toggles they form one runtime loop. Your server SDK observes a conversation turn and tags it; the backend evaluates eligibility and composes a widget; the browser SDK renders what arrives; user interaction flows back and drives the next step. Understanding that loop (the mechanism below) is what makes the rest of the catalog read as a system rather than a feature list.
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, Anthropic claude-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. Its type 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.
Tours, surveys, and announcements are authored step-by-step; only guides are AI-composed at runtime. See Experiences for the type model and statuses (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.
Classification and KPI scoring run on the AI provider you configure. Survey responses are analytics-only there is no separate transactional response store.

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:
The server SDK (@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:
Subpaths cover OpenAI, Anthropic, and any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio via @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.
Tag every observed call with all three of firstflowAgentId, sessionId, and userId. Partial tagging means the call passes through to your provider unobserved (with a one-time warning) so it never appears in targeting, sessions, or analytics.

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.

Next

If you are integrating, follow the Quickstart; if you want the model first, read How it works and Concepts, then dive into the Browser SDK or Server SDK.