Onboarding Agent
The onboarding agent lives inside your product. It's a voice AI overlay that interviews new users, understands what they're trying to accomplish, and does the setup for them. Users achieve zero-touch onboarding and enter a workspace that's already configured for their goals, not an empty dashboard.
How it works
- New user signs up and lands on your product
- A collapsed Floe launcher appears, with an onboarding nudge by default
- The user opens it and the agent asks what they're trying to accomplish
- Based on their answers, the agent navigates your product, clicks, fills forms, and configures settings
- The user ends up in a workspace tailored to their stated goals
No tooltips. No product tours. No "click here, then click there." The agent does the work.
Integration
Load the SDK and initialize it. No mode flags — the in-product overlay is what you get with neither demoMode nor websiteAgent set.
<script src="https://cdn.floe.so/floe-sdk.iife.js" defer></script>
<script src="/floe-init.js" defer></script>
// floe-init.js — served from your own origin
const floe = Floe({
clientKey: "YOUR_CLIENT_KEY",
activation: "proactive",
userInfo: {
externalId: "YOUR_AUTHENTICATED_USER_ID",
email: "user@example.com",
name: "Ada Lovelace",
company: "Analytical Engines",
designation: "Workspace admin",
},
nudge: {
text: "Ready to set up your workspace?",
autoShow: true,
autoHideDelay: 10000,
},
launcher: { position: "bottom-right", inset: 24 },
enableAudio: true,
enableScreenCapture: true,
});
floe.ready.catch((error) => {
console.error("Floe failed to initialize", error);
});
// Keep the instance in your app integration. On logout or teardown:
// await floe.disconnect();
Your clientKey is in site settings, and on Onboarding Agent → Setup in the dashboard. Pass userInfo when the agent needs the signed-in user's name, company, role, or other non-secret context during this session. It is unverified browser input; Floe uses it for this session only, never as identity.
No API mapping is required for browser-driven workflows. The agent uses the same browser interface your users see; optional API execution is configured separately.
Both in-product postures start as a collapsed launcher and connect a session only after the user clicks. Explicit activation: "proactive" gives new users the onboarding posture: its nudge is on by default, and the panel opens with setup-oriented greeting and suggested questions. It does not start a session or use the microphone on page load.
Dashboard configuration
Open Onboarding Agent → Configure in the dashboard. The current page has one card:
- Personality & tone sets this agent's tone, identity, and answer length for onboarding and support sessions. Warm Guide with medium answers is the default, and it is the voice the agent has without any configuration; Witty Peer, Crisp Expert, or a custom tone change how it sounds, never what it does. A change applies from the next session. This agent has no pace or voice setting.
There is no video avatar for onboarding or support sessions. The live presenter is a Website Agent feature; onboarding and support run with voice and text.
Logo, accent color, and CTA are shared across agents and live in the site's Settings. Whether this embed behaves as onboarding or support is selected in code with activation; it is not a separate dashboard agent.
Configuration reference
clientKey(string, required): the public browser key from Onboarding Agent → Setup or site settings. It is meant for browser code; never expose the site's secret API key. A client key works from any site until it is restricted to your domains, which Floe does on request: send us each production app origin.activation("proactive" | "on_demand", default"proactive"): use"proactive"for onboarding. Unknown values fall back to"proactive". It is ignored ifdemoModeorwebsiteAgentis set.userInfo(object, optional): supplies current-session context. Supported fields areexternalId,email,name,company,designation, andmetadata. It is unverified browser input, not an authentication assertion. Never put access tokens or other secrets inmetadata.nudge(object): acceptstext,autoShow, andautoHideDelay.autoShowdefaults totrueunderproactive.autoHideDelayis milliseconds;0keeps the nudge open. Set the delay explicitly when customizing the nudge.launcher(object):{ position: "bottom-right" | "bottom-left", inset: number }. It defaults to bottom-right with a 24-pixel inset. Move it when another widget occupies that corner.enableAudio(boolean, defaulttrue): sets the initial microphone preference. Text remains available, and a user's remembered microphone preference can override the initial value.enableScreenCapture(boolean, defaulttrue): makes screen sharing and screenshot context available. The browser still requires a user gesture and permission before sharing a screen.debug(boolean, defaultfalse): enables verbose SDK logs while diagnosing an integration.apiUrl(string, advanced): overrides the Floe API endpoint. Leave it unset with the production CDN build.
Integrate with a coding agent
Copy this prompt into your coding agent from the root of your application repository:
Integrate Floe's onboarding agent into this application. Find the client-only root that mounts once after authentication resolves. Load https://cdn.floe.so/floe-sdk.iife.js exactly once and initialize it from /floe-init.js (or the framework's equivalent client-only lifecycle). Call Floe() exactly once with the public client key and activation: "proactive". If current-session personalization is useful, map only non-secret display context into userInfo; do not treat it as an identity or authorization assertion. Do not set demoMode, websiteAgent, or demoSiteId. Configure a setup-oriented nudge with explicit autoShow and autoHideDelay values. Store the returned instance, handle instance.ready, and call instance.disconnect() on logout or component teardown. Do not call init() yourself or call a destroy() method. Prevent duplicate initialization under React Strict Mode. Keep the client key in a public environment variable, never expose Floe's secret API key, and never put access tokens in userInfo.metadata. Preserve the application's existing authentication and client-side routing behavior.
Single-page apps
Client-side routing is supported. When the agent moves the user between screens it uses an in-page navigation your router can pick up, so a single-page app keeps its state; if the app does not settle on the target route, it falls back to a full page load.
React, Vue, Angular and Svelte all work. So does server-rendered HTML.
Helping the agent target your UI
The agent targets elements by their accessible names — the visible label, aria-label, or associated text. Almost every targeting problem traces back to that name being missing or ambiguous, so a little labelling hygiene is the highest-leverage thing you can do.
Give interactive elements distinct, stable names.
- An icon-only button with no
aria-labelhas nothing to match on. Add one. - Several controls sharing one label is the classic failure: a list of cards each with a Connect button gives the agent N identical targets and no way to tell them apart. Include the distinguishing text in the accessible name —
aria-label="Connect Salesforce"— rather than relying on position. - Labels that change with state (a spinner replacing the text mid-click) can move a target out from under the agent. Keep the accessible name stable while the control is live.
Associate inputs with their labels. Use <label for="..."> or aria-label. An input the agent can see but cannot name is one it will not confidently fill.
Don't hide interactive elements from accessibility. aria-hidden="true" or role="presentation" on a real control removes it from the agent's view as surely as it does a screen reader's.
None of this is Floe-specific — it is ordinary accessibility work, and it pays off twice. If a screen-reader user can operate your UI, so can the agent.
When the agent picks the wrong element
Give the element a more specific accessible name, or stop hiding it from accessibility.
Controlling when the agent starts
By default the agent is proactive. It still starts collapsed and waits for a launcher or nudge click before connecting a session. What makes it proactive is the invitation: its onboarding nudge auto-shows by default, and the conversation opens with setup-oriented copy after the click. This is the right posture immediately after signup, and activation: "proactive" is the default.
Past that first run, most products want the agent to wait to be asked. That is the support agent, the same overlay with one flag changed:
Floe({ clientKey: "YOUR_CLIENT_KEY", activation: "on_demand" });
Under on_demand the automatic nudge is off and the conversation opens by asking what the user needs. Like proactive onboarding, it starts no session until the user opens the launcher — a user who never opens it costs nothing. The nudge is a default rather than a restriction: pass nudge: { autoShow: true } if you do want the launcher to speak up.
Since the difference is per user, not per page, one embed usually covers both:
Floe({
clientKey: "YOUR_CLIENT_KEY",
activation: user.onboardingCompletedAt ? "on_demand" : "proactive",
});
Voice-first experience
Users talk to the agent naturally. "I need to set up weekly reports for my team." The agent understands the intent, navigates to the right screen, creates the report, configures the schedule, and adds the team members.
If the user has questions along the way, they ask. The agent answers in context while continuing the setup.
What the agent can do
- Create projects, workspaces, or initial records
- Invite team members
- Configure settings and preferences
- Fill out profile and organization information
- Set up integrations (by navigating to the integration page and walking through it)
- Import data (by guiding the user through the import flow)
The agent works within your existing UI. It doesn't need API access to be useful. It uses the same buttons and forms your users would.
Reviewing onboarding sessions
Open Onboarding Agent → Recordings to review session history. Each recording can include the current-session context supplied by your embed, start time, duration, voice-or-text mode, transcript, captured frames, and the on-page actions the agent took, when that data is available. Browser-supplied userInfo is shown as session context, not verified identity. Recordings require conversation access, which owners and admins have.
FAQ
Does the agent work on mobile? The overlay is currently optimized for desktop browsers.
Can I control when the agent appears?
Yes, two ways. activation decides whether the collapsed launcher auto-shows an onboarding nudge and which opening the agent uses after a click (see above). Where it appears is up to you — the overlay only mounts on pages where you call Floe(), so loading your init script on a subset of routes scopes it to those routes.
What if the user doesn't want to talk? The agent also supports text chat. Voice is the default but users can type instead.
Does the agent access user data? The agent sees what's on screen, the same as the user. It does not access your database or APIs directly unless Floe enables API execution for your site at your request.