Skip to content

Onboarding Funnels

Onboarding funnels let an operator configure a Character or General journey in Flank and publish it at Brisket’s /f/{funnel-id} URL. Character funnels use pinned recipe steps; General funnels use custom steps followed by native signup without a recipe. Both support optional Step Studio interactions and shared saved revisions. Sirloin stores each funnel’s draft, published snapshot, status and counters.

After authentication, Character funnels validate saved progress at /hop and reach Explore until their separate character adapter is installed. General funnels also pass through /hop when saved inputs are usable: it binds them to the signed-in account before following the configured Explore destination or existing RI/VI character chooser. Generic inputs are never applied to character creation. New character-creation deep links belong to V3. The existing main-layout welcome quiz gate still applies to eligible visitors and preserves the destination in its safe return URL. Sources: continuation routes, session departure.

For how recipe sources become pinned steps and published visitor definitions, see Funnel recipe parser architecture. The interactive HTML guide combines these instructions, prompt internals, route walkthroughs and an offline source browser.

  1. Open Funnels in Flank and create a Character or General funnel. Your editor account needs FUNNEL_EDITOR, ADMIN, or ROOT; FUNNEL_EDITOR is sufficient without granting general admin access.
  2. For a Character funnel, choose RI only, VI only, or Both. RI means a real character; VI means a virtual character. Both provides a visitor choice between the two paths. General funnels skip recipe setup.
  3. For a Character funnel, select the recipe source for each character type. For a recipe family, choose which selectors are fixed and which the visitor answers.
  4. Rebuild Character steps from the selected sources. Rebuilding discards existing step edits, so finish source selection before customizing them.
  5. Edit supported copy and presentation, enable or disable optional native steps, arrange unlocked steps, and add custom interactions with Create custom step. Character funnels support recipe-free interactions before character selection and interactions inside a selected branch. General funnels have an ordered custom-step list. Review mobile/desktop and light/dark previews; previewing does not submit a visitor signup.
  6. Choose Explore or Character creation as the intended destination after signup, save the draft, and publish when the journey is ready. Arbitrary redirect URLs are no longer configurable.

Funnel names accept up to 200 Unicode code points, including non-ASCII letters and emoji. The create form, publishing checks and server enforce the same limit.

The builder derives the steps from recipe sources; it does not permit arbitrary changes to their recipe semantics. The public link serves the published snapshot, so saving draft edits alone does not update the visitor experience. Sources: builder, previews, and publication validation.

Choose Create custom step to open the library picker, then Use as base or Start from scratch. Choose Open Studio on an existing custom card to edit it. Describe any interaction, or use the input, wheel and landing starter ideas for inspiration. Input steps can collect a promo code or other generic value; code redemption, discounts and payments are outside this contract. A wheel inside a Character branch may use that branch’s declared non-photo recipe choices. Studio receives those fields automatically from the branch; there is no separate attach control. General funnels and steps before character selection have no recipe fields. A landing can use finalized author images or videos and motion that respects reduced-motion preferences.

Use Components to choose which supported Foxy DS components the generator may import; the catalog lists all 33 public component groups with rendered examples and 11 selected by default. Search by name or description; filtering keeps your selections. The selected APIs, recipe fields, author media, per-instance settings and bounded conversation are sent to generation. Visitor photos are never included. Flank builds the result before presenting it. Fix preview error makes an explicit repair request; it does not change a published step by itself.

For the exact provider messages and DS update rules, see what goes to OpenRouter and DS integration. Adding a new DS component requires Studio registration; existing component prop changes enter future prompts after a DS rebuild and Flank deployment.

Settings contains layout controls, available recipe fields and the author-media upload list. Put configuration values, including JSON, directly in the prompt. Existing instance settings remain compatible. Upload JPEG, PNG, WebP, AVIF, MP4 or WebM files of at most 50 MiB each. Generation accepts up to 12 assets. Uploads are finalized into stable references before use, and previews receive fresh signed URLs. Reusing a shared library revision retains its finalized assets even when another editor created them.

Under Settings → Layout, Hide Back, Hide progress and Hide Skip hide those host controls for this step. When off, the funnel’s navigation settings apply. Full screen removes the host title and content padding so the generated step fills the viewport. Skip stays visible unless Hide Skip is enabled. Failed steps still skip automatically. Layout defaults are off.

Use Edit text, choose a pencil beside visible text, then Apply or Reset. Changes appear immediately without a generation request. HTML and SVG text are editable; text baked into images, videos or canvas is not. Regeneration can change the text or its location, so an old edit applies only where both still match. Review the result after generating again. Source: text editor.

The library picker shows rendered previews of saved steps. Save to library stores a built step independently of the funnel draft. Studio autosaves every three minutes and shows its save status at the top right. Closing with unsaved changes offers Save and close, Discard and close, or Keep editing. Each Studio opening starts a fresh conversation; there is no saved-conversation browser.

Generating or repairing creates a durable job: status reads wait three seconds between responses, the whole job has a ten-minute deadline, and compilation repairs use at most three model attempts. A worker has a 90-second lease with 30-second renewal. A failed attempt preserves the last working result in the open conversation.

If a generation response or polling connection is lost, keep Studio open and use Reconnect generation to recover the same request. Reconnecting does not start another generation. Finish reconnecting before closing Studio to choose another step. Closing or refreshing ends this conversation; reopening does not recover its unfinished work. Wait for an upload to finish before closing Studio.

Choose a library revision to reuse it, or refine it and save a new revision. If another funnel references the item, Studio shows a notice and saving creates a separate library item. Otherwise, saving adds a revision to the same item. Deletion is blocked while any draft, published version or retained history references it. Add to funnel draft or Update draft step saves the library pin, settings, layout and text edits into the draft. Library saves include layout, settings and text edits as defaults for new uses. Existing instances keep their own values and pinned revisions. Each use has its own instance ID and local answers. Existing uses of an older revision remain pinned. Saving a library revision or adding it to a draft does not publish: review the draft and use Publish separately. Source: Studio UI, session persistence, generation jobs.

The builder card renders the actual pinned revision with this instance’s settings and copy. Cards load near the viewport and do not submit answers or analytics. Click a card to edit it in Studio. Older saved artifacts support these previews and text edits without regeneration. Source: card preview.

Custom steps are optional for visitors. The component renders its primary action and calls complete; the host validates the values and advances. The host owns Back and Skip; Back follows the funnel’s setting. If an artifact cannot load, become ready or execute successfully, the visitor continues past the step and the host records an error/skip. Native signup and recipe photo handling remain outside generated code. Preview each selected revision in its destination branch before publishing because declared recipe fields must be available in that branch.

Strict mode is enabled by default and applies only to RI character creation. The Face & Chest photo step remains available. Other RI character settings and photo steps remain visible in the builder but are disabled for visitors and locked against enabling, editing and reordering. VI character steps, routing and signup remain available.

The yellow Strict mode — RI character creation notice appears for RI-only and Both funnels. Disable unlocks RI configuration; save and publish to apply that choice to the public journey. Strict mode preserves the saved step configuration and order rather than deleting them. The server also enforces RI edit locks and excludes restricted RI steps from the public definition. Sources: builder controls and server strict-mode rules.

Action Operator and visitor result
Save draft Keeps edits for further work; the current publication stays unchanged.
Publish Copies the draft to a new published version and makes the public link available.
Unpublish Returns the funnel to draft status and disables its public link.
Archive Keeps the funnel and its history, disables its public link, and makes the editor read-only. Use the Archived list filter to find it.
Reactivate Returns an archived funnel to draft status. Review and publish again to restore the public link.

Funnels are archived instead of permanently deleted. The legacy delete operation also archives. A missing, unpublished or archived public funnel falls back to the app home page, preserving its query parameters. Sources: lifecycle operations, public entry, and fallback policy.

The funnel table shows recipe status only when the saved draft has an outdated or unavailable source, with an Edit source action. Current recipes, loading, missing sources and failed checks have no table chip; the editor summary shows all statuses. Recipe is up to date is green only when every source is current. Recipe has updates and Recipe unavailable are red; unavailable can mean deleted, unpublished or invalid. Loading, missing sources and failed checks use neutral labels. A failed check never appears as a current recipe.

Open Recipe details to inspect status and diagnostics, recheck sources, or choose Edit source. Source editing uses the existing explicit rebuild, which discards step customizations; it does not merge source changes into edited steps. There is no refresh preview, apply-refresh action or refresh undo. Updating a draft does not update the live publication. The public-funnel link remains in the table. Sources: editor summary, table, source details, and source rebuild.

Use the Viewing dropdown at the top right of the editor to choose Draft or a published version. The separate Published version column, between Status and Recipe, shows the live publication number. Unpublished or archived funnels show the last publication marked Not live; new funnels show Not published. Unpublished edits do not receive a publication number. A published version fills the main editor in read-only mode: steps cannot be edited or reordered, and navigation and quick links are hidden. Browsing does not change the draft; Back to draft returns to your unsaved edits.

The bottom panel offers Restore version to draft. Restoring replaces the whole draft, including saved and unsaved unpublished edits, after confirmation. It keeps that version’s recipe pins and destination rather than reparsing today’s source. The current public version stays live until another publish.

For example, restore v1 while v3 is live, then publish: the new publication is v4. Versions 1–3 are unchanged. Archived funnels allow history browsing; reactivate before restoring, and publish separately to reopen the public link. Source: history service.

Open Events from a funnel’s table row. It uses the live publication when published; otherwise it shows the current draft. Draft filters omit the publication version until one is assigned. This is an event reference, not live activity, and opening it does not fire visitor events.

Copy dashboard instructions copies an LLM prompt with this definition’s eligible steps, exact event filters and safe answer choices. Paste it into a PostHog-connected assistant to build a dashboard. It requests a vertical step-impressions column chart with every eligible step in journey order, unique-user counts and zero-count steps retained, plus an ordered funnel showing drop-off counts and percentages. Branch paths and versions stay separate. It also requests answer distributions and photo/skip counts. Drafts produce a template without an invented publication number; the assistant must verify the project, environment and available data. Source: dashboard instructions.

The dialog lists Step viewed, Step completed, and custom-step Step skipped, Step error and declared interactions, with copyable filters for each step. Titles are labels; they never become event names. Events carry funnel_id, string funnel_version and step_id. Recipe-branch steps also carry branch_id, so identical field IDs in different branches can be filtered separately. Entry and signup steps have no branch filter. Select the intended environment in PostHog.

Event When it fires Additional properties
funnel_step_viewed The visitor reaches the step. Local photo checking and email verification do not add views. None.
funnel_step_completed A valid answer or optional skip advances to the next step, including automatic advance after selecting an option. answer for selected recipe option/boolean values; photo_count for photo steps; skipped: true for an unanswered optional step.
funnel_step_skipped A custom step is skipped explicitly or after failure; this is not completion. reason is visitor or runtime.
funnel_step_error A custom artifact fails to load, become ready or execute. Bounded error code, without raw exceptions or source.
funnel_step_event A custom step sends an interaction declared by its manifest. Declared interaction name only.

Custom steps count as viewed only after the isolated frame is ready. Their completion uses an answers map containing only declared fixed-choice values; free text, promo codes and generic values without fixed choices stay in the browser. Unchanged custom completions are deduplicated, while separate uses of one library revision remain distinct through their instance IDs. Skips and errors do not imply successful completion. Keep optional custom steps out of required conversion milestones.

Answers retain declared recipe option values as primitives or arrays, including booleans. Object-shaped option payloads are omitted. Typed text, image content, filenames, URLs from uploads and signup credentials are not sent. Photo completion means the visitor continued past the photo step, not that a server upload or generation succeeded. Signup has a viewed event only; auth attempts and server conversions remain separate.

Visitors follow only their selected path and eligible conditional steps. Dropped and RI strict-mode-disabled steps are omitted. Views are deduplicated by branch and step within the mounted renderer; a reload can count again. Completing a native step again after going back emits another completion with the current answer. Invalid answers, restoring saved progress, going back and photo scanning do not emit completion events. Use unique users for drop-off comparisons rather than comparing raw event totals.

These events replace funnel_screen_viewed and its internal screen states. Existing PostHog reports using that event must switch to the new names. They do not prove signup completion or guarantee analytics delivery. Sources: view capture and step transitions.

Metric Meaning
Impressions Recorded public-funnel openings, not unique visitors. A new opening can count again; retries of the same opening event do not.
Conversions Eligible new signups attributed to this funnel. A user is attributed once; repeated requests and later sign-ins do not add conversions or overwrite attribution.
Conversion rate Conversions divided by recorded impressions. It does not measure payment or character completion.
Last impression Server time of the most recently recorded new opening.

Conversion requires a recorded impression and a verified account creation time at or after that visit, within seven days of it. Signing in to an account that existed before the visit is not a conversion. Attribution sets users.profile.funnel_id and increments the counter together. A valid signup from a previously recorded visit can still be attributed after the funnel is archived; archival prevents new impressions. Counters are per funnel, not per published version, and are not unique-visitor or character-creation counts. Sources: opening events, server signup attribution, and tracking transaction rules.

V2 retains the schema-2 browser record and adds optional customInputs[instanceId]. Generic interaction values remain scoped to that instance; accepted recipe writes still use the original stage/field keys. A General funnel stores no recipe snapshot or visitor photos. Signed author-media URLs, model prompts and source code are not visitor answers. Publication compatibility, seven-day expiry, account ownership and write-token checks still protect local progress. General navigation reaches the configured existing chooser or Explore even if local persistence fails; it does not depend on a character adapter.

The following Character-flow behavior preserves the existing native recipe and photo path. Visitors already signed in when they open a funnel go directly to Explore (/), before funnel data, local progress or opening events load. A visitor who starts anonymously and then signs up keeps the save-before-departure flow through /hop; that transition does not erase the saved character inputs.

Answers, selected photo files and the resolved recipe snapshot are retained in the visitor’s browser using IndexedDB, with a seven-day expiry. This is local progress, not a pre-signup user or character record. The saved record includes RI/VI, gender when known, and original recipe stage/field keys. Changing the publication never moves old answers into a new recipe. On anonymous entry, unusable anonymous progress from an older publication, an expired record or a recognized older format is cleared automatically so the current funnel can start fresh. Valid progress resumes normally. Account-owned records, unknown future formats and records newer than the loaded publication are preserved. If progress cannot be restored, the funnel starts with empty inputs automatically, without a recovery screen. Background save failures do not add a banner; the next change retries saving. If the final signup save fails, signup continues without saved inputs. Character uses Explore; General keeps its configured destination. The main-layout quiz gate can still apply. /hop retains incompatible data and falls back to Explore. Sources: progress storage and recipe resolution.

Photo requirements come from the pinned recipe: accepted file types, byte size, minimum dimensions, pixel count and photo count. The browser reuses character-creation metadata and dimension checks. Missing or unsafe upload policies block selection instead of silently substituting guessed limits. HEIC/HEIF and AVIF are offered when the recipe accepts JPEG; WebP is converted only when the recipe excludes WebP but accepts JPEG. Brisket shares the Create flow’s browser converter, using the browser codec first and a dynamically loaded HEIC decoder as fallback. Conversion input has a 10 MiB safety ceiling; the converted JPEG must satisfy the recipe’s byte and dimension limits. WebP stays unchanged when the recipe allows it. No fixed 10 MB allowance overrides a stricter recipe limit.

A spinner covers the selected photo during local conversion and preview loading. Scanning starts only after the validated previews are decoded and visible. The success state and Continue appear together after the scan; preview failures allow another selection.

The funnel does not upload those photos to create a character, and its checking/accepted UI is not server-side identity or likeness approval. Signup waits for the latest browser save, then continues to /hop before the main-layout quiz gate runs. A failed save continues signup without saved inputs: Character uses Explore and General keeps its configured destination. The main-layout quiz gate can still apply. The saved recipe is not automatically applied to character creation. Use the separate character creation flow for the full creation process. Sources: photo checks, funnel state machine, and signup completion.

Signup departure, account initialization and /hop show the same centered Foxy logo and spinner as the app loader. The normal transition has no intermediate status text or funnel skeleton; account initialization timeouts and transient failures silently continue to Explore; local progress failures continue without saved inputs. In /hop, unavailable authentication after ten seconds or an unexpected continuation error returns to foxy.ai without showing a recovery screen. Authenticated timeouts still continue to Explore.

Before leaving for signup, the server attempts to store the recorded visit in an HTTP-only cookie. If preparation fails after its retries, departure reports a best-effort funnel_signup_preparation_failed browser telemetry warning and continues signup or sign-in. Saved inputs keep the /hop destination; failed local saving uses Explore for Character or the configured destination for General. No departure retry screen is shown, and reporting failure cannot block continuation. Cancellation still stops the old session, and actual authentication errors remain visible. After authentication, server initialization attributes the app profile before returning the app or authenticated API data. PostHog reads this saved value; analytics availability does not determine whether attribution is written. A failed attribution request can be retried without counting another conversion. A timeout or transient failure at the initialization boundary logs a funnel_initialization_failed warning to Axiom and clears the pending cookie before redirecting to Explore. No retry screen is shown. The failed attempt may leave conversion attribution unrecorded; it must not block account access. Existing-account sign-ins and permanently ineligible visits clear the cookie without preventing sign-in. Selections and photos remain in the existing browser IndexedDB draft; this change does not upload photos or start character creation automatically.

Sources: signup preparation and server attribution.

Ordinary signup and existing character creation

Section titled “Ordinary signup and existing character creation”

Until funnels launch, the main layout keeps the existing welcome redirect for signed-in users without a subscription or completed quiz. Ordinary and funnel signups, and returning sign-ins who have not finished onboarding, see one simplified quiz and its skippable paywall. skip-post-signup-quiz ON skips it; OFF, or an unavailable flag after the loading grace period, keeps it. Authentication routes remain unchanged. The gate preserves the current app path and query in a safe return_to, so paywall close or flag bypass resumes that destination. /hop resolves before this gate; its resulting funnel reference is retained in the return URL. Bypassing does not mark the quiz complete or consume saved inputs. See signup destinations for routing and removal points.

The app tour remains wired to its existing character-completion and first-purchase entry points through ?guide=true; signup and funnel continuation do not automatically start it. Existing character-creation rollout flags, payment checks, credits, KYC and the Explore RI/VI chooser remain in place. The chooser can still let someone change their mind; matching or discarding funnel prefills there belongs to the separate character adapter, not this release.

The browser record is claimed by the signed-in account before use. Other accounts cannot resume its contents. A stale tab cannot overwrite a newer save or delete it after transfer. The seven-day expiry advances on edits, not reads. The architecture reference describes the exact shape and reader API.

Expose funnel links only after characters-v2 reaches 100% rollout. This release retains General’s configurable Explore/Character creation destination. The launch condition is operational; it is not enforced by a new funnel flag check. Character-prefill transfer remains separate work. See the app handoff matrix.

For V2, apply 189_funnel_studio.sql after main’s migrations through 188, then deploy the matching Sirloin contract before Flank and Brisket. Studio requires FLANK_OPENROUTER_API_KEY on the Flank server; FLANK_STEP_STUDIO_MODEL optionally overrides the configured model. No browser credential is used. Drain older instances and reload editor/preview tabs before creating new pins or General funnels. Keep revision and retained-asset readers when rolling back behavior: existing publications must remain readable. See Step Studio architecture.

First remove legacy refresh controls from Flank before retiring their Sirloin endpoints. For the new funnel controls, deploy Sirloin before the matching Flank and Brisket releases, then reload old editor tabs before authoring or distributing links. New Flank clients call history and source-inspection RPCs that older Sirloin instances do not implement. Once a draft has a continuation destination, Sirloin rejects saves from older editors that omit it with “Reload the editor before saving this funnel.” Destination editing, version restoration and public funnel loading work without a rollout flag. The unused capability fields have been removed from API responses.

Drain older service instances and reload authoring and public-preview tabs before using funnels. Once new definition fields or schema-2 progress exist, rollbacks must retain readers and preservation for them. Do not revert to a Phase 1 binary, discard unknown JSON globally or rewrite immutable publications. See the compatibility rules.