Onboarding AgentCopy link to this section
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 worksCopy link to this section
- 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.
IntegrationCopy link to this section
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 the Onboarding Agent home 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 configurationCopy link to this section
Open Onboarding Agent → Configure in the dashboard. The current page has one card:
- Persona & tone saves this agent's identity, tone, answer length, pace, and voice choices. These are saved but not yet applied to live onboarding or support sessions.
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 referenceCopy link to this section
clientKey(string, required): the public browser key from the Onboarding Agent home or site settings. It is safe to expose in browser code; never expose the site's secret API key. Authorize each production app origin in the site's allowed domains.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 agentCopy link to this section
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 appsCopy link to this section
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 UICopy link to this section
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 elementCopy link to this section
Give the element a more specific accessible name, or stop hiding it from accessibility.
Controlling when the agent startsCopy link to this section
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 experienceCopy link to this section
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 doCopy link to this section
- 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 sessionsCopy link to this section
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 event details when that data is available. Browser-supplied userInfo is shown as session context, not verified identity.
FAQCopy link to this section
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 you enable API execution.