# FloatMessage - Full Documentation > FloatMessage is the all-in-one engagement layer for any website: live chat with AI auto-reply, AI-generated landing pages, popups (18 templates), contact forms, surveys, exit-intent offers, push notifications, self-service appointment booking, and built-in ticketing. One drop-in script tag, smart targeting on every message, install as a PWA. ## Product Overview FloatMessage gives any website a complete engagement layer: live chat (with optional AI auto-reply trained on your own knowledge base), an AI-driven landing-page builder hosted on a branded subdomain, plus floating messages (popups, banners, modals, notification cards, contact forms, cookie consent bars, story carousels, appointment bookers). Messages render inside Shadow DOM so they never conflict with your site's styles. ### How It Works 1. **Sign up** - Google login or email/password, no credit card required 2. **Design** - Pick a template and customize visually, or write custom HTML/CSS 3. **Embed** - Copy a single script tag and paste it before your closing `` tag 4. **Choose plan** - Wizard ends at `/signup/plan` with three cards (Pro / Enterprise / Free Trial). Paid plans go straight to Stripe hosted checkout, then back to `/signup/done` with a personalized welcome. ### Pricing - **Free Trial**: 30 days, full access, no credit card required - **Pro**: $10/month or $100/year (save 17% on yearly) - Unlimited floating messages, live chat with AI auto-reply, multi-model AI, push notifications - AI Landing Pages with branded subdomain - All 18 templates including Story Carousel + Book Appointment - Smart targeting: URL, geo, device, schedule, exit intent, visit count - Custom CSS & HTML, analytics, priority support - 1 domain workspace - **Enterprise**: $99/month or $999/year (save 17% on yearly) - Everything in Pro - Team management with roles (owner, admin, editor, viewer) - Up to 20 domain workspaces - Shared workspace for messages and chat - Domain selector in dashboard - Dedicated support Access check: `plan === "PRO" || plan === "ENTERPRISE" || isTrialActive(trialEndsAt)` Stripe checkout endpoint: `POST /api/checkout` with `{ plan: "PRO" | "ENTERPRISE", billing: "monthly" | "yearly", source?: "signup" | "pricing" }` returns `{ url }` to redirect to Stripe-hosted checkout. The `source: "signup"` flag changes the success_url to land back inside the wizard at `/signup/done?checkout=success&plan=&cycle=` instead of the dashboard. Webhook: `POST /api/webhooks/stripe` listens for `checkout.session.completed` (sets `users.plan`, `users.stripeCustomerId`, `users.stripeSubscriptionId`) and `customer.subscription.deleted` (reverts to FREE). --- ## Embed Integration ### Drop-In Script The single recommended way to embed FloatMessage. Loads every active floating message and the live chat widget for your account from one tag: ```html ``` ### Enterprise Domain-Specific On the Enterprise plan you can manage multiple websites as separate workspaces. Pass `data-domain` to scope which workspace's messages should load: ```html ``` The embed script auto-detects `window.location.hostname` if `data-domain` is not set. ### Script Behavior 1. Detects `data-user` (plus optional `data-domain` and `data-api`) attributes 2. Generates a persistent visitor ID (`fm_vid` in localStorage) 3. Fetches all active messages from `/api/embed/user?userId=X&domain=Y` 4. For each message: checks targetUrls, blockedUrls, schedule, geo, dismiss 5. Renders passing messages inside Shadow DOM with animation 6. Initializes chat widget if enabled via `/api/chat/config` 7. Auto-registers visitor on page load for proactive messaging 8. Tracks analytics events (impression, click, dismiss, chat_open, chat_message) 9. Handles contact form and survey submissions via `/api/forms/submit` and `/api/surveys/submit` --- ## Templates (18) | ID | Name | Description | |----|------|-------------| | banner | Welcome Banner | Gradient banner with heading, text, and CTA | | notification | Social Proof | Compact notification card with icon | | newsletter | Newsletter CTA | Email signup form | | square | Square Card | Centered card with badge, price, CTA, timer | | image-message | Image Message | Card with hero image and button | | center-modal | Center Modal | Full-width modal with backdrop | | blur-overlay | Blur Overlay | Glassmorphism overlay card | | sticky-footer | Sticky Footer Bar | Full-width bar at bottom | | top-banner | Sticky Top Banner | Full-width bar at top | | image-bg | Image Background | Card with full background image | | modal-image | Modal with Image | Side-by-side image and content | | image-only | Image Only | Clickable image with optional link | | story | Story Carousel | Instagram-style vertical story with slides | | cookie-banner | Cookie Banner | GDPR consent bar with accept/decline | | chat-cta | Chat CTA | Prompt that opens live chat on click | | contact-form | Contact Form | Form with configurable fields, submissions stored and forwarded | | survey | Survey | All-in-one survey builder: NPS, ratings, multi-choice, text, multi-step | | book-appointment | Book Appointment | Self-service slot picker with .ics confirmation, race-resolved booking, Google / Outlook deep links, custom intake fields, owner-defined hours | ### Special Template Behaviors - **cookie-banner**: Accept button has `fm-cta` class (fires cta:click event), Decline has `fm-close` (just dismisses). Use `FloatMessage.on("cta:click")` to load GTM after consent. - **chat-cta**: CTA button uses `onclick="FloatMessage.openChat()"` in Shadow DOM. Requires JS API enabled. - **contact-form**: Submit button has `fm-form-submit` class. Collects all `fm-form-input` elements by name attribute. POSTs to `/api/forms/submit`. Shows `fm-form-success` element on success. - **survey**: Driven entirely by `surveyConfig` JSON on the message (not raw HTML). Steps support types `nps`, `rating`, `single_choice`, `multi_choice`, `short_text`, `long_text`. Multi-step with Back/Next, progress dots, validation. Submits to `/api/surveys/submit`. Responses appear under Dashboard → Surveys with NPS/rating/choice aggregations. --- ## JavaScript API Available globally after embed script loads. `on()` and `off()` always available. Chat methods require JS API enabled in settings. ### Methods | Method | Description | |--------|-------------| | `FloatMessage.on(event, callback)` | Listen for events | | `FloatMessage.off(event, callback)` | Remove listener | | `FloatMessage.showChat()` | Show chat bubble | | `FloatMessage.hideChat()` | Hide chat bubble and panel | | `FloatMessage.openChat()` | Open chat panel | | `FloatMessage.closeChat()` | Close chat panel | | `FloatMessage.toggleChat()` | Toggle panel | | `FloatMessage.setCustomData(data)` | Send custom visitor data | ### Events | Event | Detail | Trigger | |-------|--------|---------| | `cta:click` | `{ messageId, template }` | Visitor clicks element with `fm-cta` class | --- ## Live Chat ### Conversation Flow 1. Embed script loads → visitor auto-registered on page load 2. Visitor appears in dashboard Visitors panel with page, country, city 3. Visitor or owner sends first message → conversation created 4. Messages delivered via polling (every 5s) or SSE (dashboard) 5. AI auto-reply triggers if enabled and admin hasn't taken over 6. Push notification sent to owner on visitor message ### Multi-Model AI Supports 7 models across 3 providers - bring your own API key: | Model | Provider | |-------|----------| | gemini-2.5-flash-lite | Google Gemini | | gemini-2.5-flash | Google Gemini | | gemini-2.5-pro | Google Gemini | | gpt-4o-mini | OpenAI | | gpt-4o | OpenAI | | claude-haiku-4-5 | Anthropic | | claude-sonnet-4-5 | Anthropic | ### AI Knowledge Base Per-domain library of content that the AI agent uses as context for every reply. Three item types in one list at **Live Chat → Knowledge**: | Type | Use it for | |------|------------| | URL | Any public page (pricing, FAQ, docs). Auto-refreshed every 24h. | | Note | Free-text snippets you write directly (refund policy, holiday hours, escalation rules). | | File | PDF, DOCX, TXT, or Markdown upload (max 5 MB). Browser parses the text before upload. | **Auto-bootstrap**: When you add a domain, FloatMessage scrapes its front page and asks Claude to summarize it into 3-5 starter notes - the AI starts smart on day one. You can re-trigger from the dashboard with **✨ Auto-generate from my site**. **Plan limits**: 10 items per domain (FREE), 30 (PRO), 100 (ENTERPRISE). **Per-item controls**: enable/disable (keep without sending to AI), edit, delete, force re-scrape (URLs only). **Agent Instruction Wizard**: Pick one of 15 agent presets (Customer Support, Lead Gen, Promotion, Bookings, etc.) and FloatMessage customizes the placeholders with content from your own site so you don't have to write a system prompt from scratch. ### AI Instruction Modes - **Static**: Use instructions from settings - **Webhook**: Fetch dynamic instructions per conversation from your server - **Both**: Try webhook, fall back to static ### Template Variables Built-in: `${country}`, `${city}`, `${pageUrl}`, `${userAgent}`, `${visitorName}`, `${visitorEmail}` Custom: Collect from visitor's page via JS paths (e.g., `window.userPlan` → `${userPlan}`) ### Proactive Messaging - **Visitors panel**: See all visitors with online status, page, country - **Direct message**: Click visitor → send message → preview bubble appears on their site - **Broadcast**: Send to all online visitors at once - **Message preview bubble**: Shows near chat icon for 15s, click to open chat ### Notification Rules Configure in Chat Settings → Notifications: | Rule | Example | |------|---------| | Visitor is on page | `/pricing*` | | Visitor from country | `US` | | Visit count >= | `3` | | New visitor | - | ### Chat Targeting - **Allowed URLs**: Show chat only on matching pages (wildcard support) - **Blocked URLs**: Hide chat on matching pages (takes priority) - **Allowed Countries**: Show chat only to visitors from these countries (server-side) - **Blocked Countries**: Hide chat from these countries (server-side, takes priority) - **Device targeting**: Show or hide chat per device class (desktop, tablet, mobile) using UA + viewport detection - **Schedule windows**: Day-of-week + time-of-day in the visitor's local timezone, plus optional date range ### Pre-Chat Form Optionally collect visitor name and/or email before the chat starts. Configure in **Chat Settings -> Pre-Chat Form** (`collectName`, `collectEmail` toggles). When enabled, the chat panel opens to a form first; submission persists to localStorage so the form only shows once per browser. The captured values write to `chat_visitors.name` / `.email` so they appear in the dashboard inbox. **Auto-translation**: The embed reads `navigator.language`, calls `GET /api/chat/form/translation?lang={code}&country={ISO}` and swaps the form text into the visitor's language. 19 languages baked in: en, es, fr, de, it, pt, nl, pl, ru, tr, ar, he, ja, zh, ko, hi, id, vi, th. RTL flip is automatic for `ar` and `he`. Falls back to English silently if the request fails or the language isn't supported. Country-IP is a tie-breaker when the browser is en-default but the IP suggests a non-English language. Translations are pre-baked at build time via `npm run i18n:prechat` (Gemini 2.5 Flash) into `src/lib/chat/prechat-translations.json`; the endpoint serves from disk with 24h edge cache. --- ## Analytics Events tracked via `POST /api/embed/events` with client-side batching: | Event | When | |-------|------| | impression | Message shown on page | | click | fm-cta element clicked | | dismiss | Message closed | | chat_open | Chat panel opened | | chat_message | Visitor sends chat message | Stored in `analytics_event` table with indexes on userId and messageId. Dashboard shows last 30 days with legacy fallback. --- ## Contact Form Submissions - Stored against the message that produced them (field data, page URL, country) - Viewable in Dashboard → Submissions with CSV export - Webhook forwarding: POST to configured URL with field data, pageUrl, country, timestamp --- ## Survey Responses - Stored per visitor with the question snapshot so editing the survey later doesn't break historical data - Viewable in Dashboard → Surveys with per-survey aggregation cards (NPS score, rating average, choice distribution, recent text answers) and CSV export - Webhook forwarding reuses the message's webhook URL - payload is `{ messageId, type: "survey_response", answers, pageUrl, country, submittedAt }` - Step types: `nps` (0–10), `rating` (1–N stars), `single_choice`, `multi_choice`, `short_text`, `long_text` with multi-step support --- ## Ticketing - Create from chat conversations or form submissions - Status: New → In Progress → Closed - Internal notes per ticket - Media attachments (images, PDF, TXT, CSV, DOC up to 5 MB) - 3-dot action menu in chat header: Create Ticket, Archive --- ## Enterprise Features ### Team Management - Create organization (Enterprise plan required) - Invite members by email with roles: owner, admin, editor, viewer - Role permissions: owner manages all, admin manages members/settings, editor creates content, viewer reads - Members auto-linked if they have existing accounts ### Domain Management - Add website domains as separate workspaces - Domain selector dropdown in sidebar switches entire dashboard context - Messages, chat, submissions, tickets filter by selected domain - Embed script passes `data-domain` (or auto-detects hostname) - API filters messages by domainId for Enterprise users --- ## Authentication - **Providers**: Google OAuth or email/password - **Session**: 30-day persistent session - **Signup**: POST /api/auth/signup (email, password, name) - **GTM events**: `signup` on registration, `purchase` on checkout success --- ## API Endpoints ### Public (CORS enabled) | Method | Path | Purpose | |--------|------|---------| | GET | /api/embed?id={id} | Message config | | GET | /api/embed/user?userId={id}&domain={d} | All active messages | | POST | /api/embed/events | Batch analytics | | POST | /api/embed/click?id={id} | Legacy click tracking | | GET | /api/chat/config?userId={id}&domain={d} | Chat widget config | | GET | /api/chat/form/translation?lang={code}&country={ISO} | Pre-Chat Form translated strings (19 languages, edge-cached 24h) | | POST | /api/chat/visitor | Register/update visitor (accepts name + email from Pre-Chat Form) | | POST | /api/chat/presence | Poll for new messages | | GET | /api/chat/sse | SSE real-time updates | | POST | /api/forms/submit | Form submission | | GET | /api/push/vapid-public-key | VAPID public key | | GET | /api/wp-status?userId={id} | WordPress plugin status | | GET | /api/wp-update | WordPress plugin update check | ### Authenticated (session required) | Method | Path | Purpose | |--------|------|---------| | GET/POST/PUT/DELETE | /api/messages | Message CRUD | | GET/PUT | /api/chat/settings | Chat settings | | GET | /api/chat/conversations | List conversations | | GET/POST | /api/chat/messages | Chat messages | | POST | /api/chat/broadcast | Send to all online visitors | | GET | /api/chat/visitors | List online visitors | | GET/POST/PUT/DELETE | /api/tickets | Ticket CRUD | | POST | /api/tickets/upload | Upload ticket attachment | | GET | /api/forms | List form submissions | | GET/POST/PUT/DELETE | /api/domains | Domain CRUD | | GET/POST/PUT | /api/organization | Organization CRUD | | GET/POST/PUT/DELETE | /api/organization/members | Team members | | GET / POST | /api/knowledge | List / create knowledge items | | GET / PATCH / DELETE | /api/knowledge/{id} | Inspect, edit, or remove a knowledge item | | POST | /api/knowledge/{id}/refresh | Force re-scrape of a single URL item | | POST | /api/knowledge/refresh-all | Re-scrape every URL item for the current domain | | POST | /api/knowledge/upload | Upload a knowledge file (PDF, DOCX, TXT, MD) | | POST | /api/knowledge/auto-generate | Bootstrap 3-5 notes from the domain's front page | | GET/PUT | /api/account | User account | | POST | /api/checkout | Stripe checkout | | POST | /api/billing-portal | Stripe customer portal | | POST | /api/push/subscribe | Push subscription | | POST | /api/push/unsubscribe | Remove push subscription | --- ## AI Landing Pages For visitors who don't have a website yet, FloatMessage's AI landing-page builder generates a polished page on a branded subdomain in 60 seconds. ### Generation Flow 1. Pick one of 8 starter templates: SaaS, Local Business, Coming Soon, Event, Portfolio, Restaurant, Online Course, Lead Magnet. 2. Describe the business in 2-4 sentences (who you serve, what you do, what makes you different). Pick a color theme. 3. Claude writes the copy from the description; Gemini generates matching images per template slot. Final images are auto-converted to WebP for fast loads. Output is a structured JSON document that the renderer maps to the chosen template. 4. Every section has Regenerate. Hero and CTA accept Upload from computer too. 5. Publish - the page goes live immediately at three URLs: the canonical `/p/`, the shared `lps.floatmessage.com/`, and (optionally) a branded `.floatmessage.com` subdomain. Wildcard SSL is automatic. ### Hosting Details - **Lighthouse target**: Performance >= 95, SEO = 100, Accessibility >= 95 - Inline critical CSS, zero client JS for the page itself (the FloatMessage embed loads with `defer`) - WebP images with intrinsic sizes, hero preload via `` - Edge-cached worldwide - Canonical tag auto-points at the branded subdomain when claimed - JSON-LD per template: `LocalBusiness`, `Event`, `Person`, `Course`, `Product`, plus `WebSite` baseline - OpenGraph + Twitter cards generated from the description - Sitemap inclusion automatic for published, non-noindex'd, non-archived pages past the 24h dwell window (anti-spam quality gate) ### Engagement Preinstalled Every landing page ships with the full FloatMessage engagement layer: live chat widget (with optional AI auto-reply), popups, contact form, appointment booking, surveys. No separate setup - all powered by the same account. ### Per-Page Limits - FREE: 1 landing page - PRO: 5 landing pages - ENTERPRISE: unlimited Each page only counts when published; archived pages free up the slot. ### Endpoints (authenticated) | Method | Path | Purpose | |--------|------|---------| | GET / POST / PUT / DELETE | /api/landing-pages | Landing page CRUD | | POST | /api/landing-pages/generate | Run the AI generation pipeline | | POST | /api/landing-pages/{id}/regenerate-section | Regenerate one section | | POST | /api/landing-pages/upload-image | Upload a custom hero / CTA image (replaces the generated one) | | GET | /p/{slug} | Public canonical landing page render | --- ## Audience Pages Two top-of-funnel marketing pages frame the product for different starting points: | Path | Audience | Pitch | |------|----------|-------| | /for/website-owners | People who already have a website | The complete engagement layer added with one drop-in script: live chat, popups, surveys, contact forms, exit-intent, push notifications. Six independent targeting layers (URL, geo, device, schedule, exit intent, dismiss behaviors) that stack. | | /for/small-business | People who don't have a website yet | A polished landing page in 60 seconds via the AI generator, hosted on a branded subdomain with HTTPS. Lead capture and live chat built in. | Both pages funnel into the same `/signup` wizard, which ends at `/signup/plan` for plan selection (Pro / Enterprise / Free Trial). Pro and Enterprise route into Stripe-hosted checkout via `/api/checkout`; Trial skips Stripe and finishes the wizard. --- ## Signup Wizard Sequential steps live under `/signup/*`. Each step is a server component that auth-gates and redirects on either no-session or already-onboarded. | Step | Path | Purpose | |------|------|---------| | 1 | /signup | Account creation (Google OAuth or email/password) | | 2 | /signup/website | Branch: existing site vs new landing page | | 2 | /signup/landing | New landing-page generator wizard (sub-flow) | | 2 | /signup/embed | Existing-site embed snippet copy step | | 2 | /signup/domain | Optional second domain setup | | 3 | /signup/features | Toggle live chat / welcome banner / contact form | | 4 | /signup/plan | Choose Pro / Enterprise (Stripe checkout) or Free Trial | | 5 | /signup/done | Welcome page (personalized when ?checkout=success&plan=&cycle=) | The plan-selection step calls `/api/checkout` with `source: "signup"` so Stripe's `success_url` lands back on `/signup/done?checkout=success&plan=&cycle=`. Trial skips Stripe entirely. The Stripe webhook (`/api/webhooks/stripe`) provisions the subscription async; the user reads the welcome page while the DB catches up. --- ## Why FloatMessage - **One drop-in script** is the entire engagement layer: live chat, popups, surveys, forms, push, ticketing, and self-service appointment booking - **AI built in** - landing-page generator, chat auto-reply trained on your knowledge base, multi-language pre-chat form - **Bring your own AI key** - Gemini, OpenAI, or Anthropic. Costs stay transparent, no markup. - **Smart targeting on every message** - URL, geo, device class, schedule, visit count, exit intent. Six layers that stack. - **Per-domain workspaces** - Enterprise customers manage up to 20 sites from a single dashboard with role-based access - **Shadow DOM rendering** - zero CSS conflicts with the host website - **Installable as a PWA** with native push notifications - **Free 30-day trial** - full access, no credit card required --- ## Links - Website: https://floatmessage.com - Dashboard: https://floatmessage.com/dashboard - Pricing: https://floatmessage.com/pricing - Documentation: https://floatmessage.com/docs - Guides: https://floatmessage.com/guides - Terms: https://floatmessage.com/terms - Privacy: https://floatmessage.com/privacy - WordPress Plugin (docs): https://floatmessage.com/docs/wordpress - WordPress Plugin (wp.org): https://wordpress.org/plugins/floatmessage-live-chat/ - Summary: https://floatmessage.com/llms.txt