Embed SDK v2
Show a published form on any website with one script tag. v1 options keep working.
<script src="https://YOUR_HOST/embed.js" async></script>
<div data-formflow="contact" data-mode="inline"></div>
<button data-formflow="feedback" data-mode="slider">Feedback</button>
<div data-formflow="nps" data-mode="popover" data-launcher-icon="chat"
data-launcher-tooltip="Got a minute?" data-trigger-exit-intent="true" data-trigger-scroll="50"></div>JavaScript API
FormFlow.open("demo", {
mode: "slider", // inline | popup | modal | drawer | slider | fullscreen | floating | popover
styles: { side: "right", width: 520 },
prefill: { email: "ada@example.com" },
prefillFromUrl: { plan: "utm_plan" }, // { fieldId: urlParam } | true | ["a","b"]
prefillFromDataLayer: { company: "user.company" },
transitiveSearchParams: ["utm_source", "utm_campaign"],
autoClose: 2500,
onSubmit(r) { console.log(r.submissionId); },
});
FormFlow.createWidget(document.body, "nps", {
mode: "popover",
launcher: { icon: "chat", tooltip: "Tell us what you think", color: "#4f46e5" },
trigger: { exitIntent: true, scrollPercent: 60, delay: 30, once: true },
});What is new
slider side panel; popover launcher chat bubble with custom icon (built-in or https image) and tooltip; triggers for exit intent, scroll depth and delay (once per session); prefill from the page URL or GTM dataLayer; autoClose after submit; transitiveSearchParams to forward UTM parameters; a loading skeleton in the form's own colors until it is ready.
Visual flags and the side tab
data-hide-header, data-hide-footer, data-transparent (transparent page background), data-loader-color (#hex skeleton colour) and data-auto-height="false"; as options: hideHeader, hideFooter, transparent, loaderColor, autoResize. New mode sidetab: a vertical tab on the screen edge (styles.side) that opens the slider. Per-platform steps for WordPress, Wix, Squarespace, Webflow, Shopify, Framer and Notion are in the embed guides; the WordPress plugin lives in integrations/wordpress.
oEmbed
GET /api/oembed?url=https://YOUR_HOST/f/SLUG&maxwidth=800&maxheight=600 returns an oEmbed 1.0 rich response (JSON only) with a responsive iframe, so pasting a form link works in editors that support oEmbed (WordPress, Notion alternatives, Ghost). Published form pages advertise it with a discovery link. Inside a form, the oembed page block shows videos, music, maps, designs and booking pages from YouTube, Vimeo, Loom, Spotify, Google Maps, Figma and Calendly only.
Protocol
The iframe posts { source: "formflow", type, data } messages (ready, resize, progress, submit, error, close) and the SDK accepts them only from its own frame and the configured origin. Unchanged from v1.
Password-protected forms
The unlock screen runs inside the frame. The unlock cookie is partitioned and needs third-party cookies; where blocked, link to the hosted URL.
Public endpoints
Custom frontends can use GET /api/v1/public/forms/:slug, POST .../unlock and POST .../submissions directly (CORS enabled for reads, rate limited per IP and form). Completion is validated again on the server.