Flows

Build a funnel

A step-by-step walkthrough — pick a template, describe your program to the AI, edit the presentation copy and theme, get a provider to approve the clinical plane, publish, and hand a qualified patient off to checkout.

This is the whole path for building a flow — neolife's patient-acquisition funnel — from an empty Funnels section to a published, hosted quiz → intake → checkout that feeds real orders into the fulfillment rail. Every step here runs in NEOLIFE_MODE=demo with synthetic patients, so you can author and publish the full funnel before any patient traffic is live.

If you haven't yet, read Flows first — the two-plane model it describes is the thing that makes every step below safe. In short: you and the AI freely author the presentation plane (landing copy, theme, marketing quiz, A/B variants); the clinical plane (medical questions, disqualifiers, consent) comes only from neolife's certified questionnaire corpus, and a licensed provider approves it before publish. AI drafts, a licensed provider signs.

What you're building#

A flow is a single funnel a patient walks: a marketing landing step, an optional marketing quiz, the certified medical intake, and a handoff to checkout. Building one is five moves:

  1. Start from a template — the entire certified questionnaire corpus, wrapped as ready-to-run funnels.
  2. Describe your program and let the AI match it to a certified questionnaire and draft the copy + theme.
  3. Edit the presentation plane — copy, brand theme tokens, step order, checkout handoff — in a form-based editor.
  4. Get a provider to approve and publish — a licensure-gated act that records a flow approval certificate.
  5. Ship the hosted page or embed snippet, and let a qualified patient hand off to your store with the certificate token attached.

You never author a live clinical screen, and you never approve the clinical plane yourself — a licensed provider does, and the rail refuses to publish a flow whose clinical plane no provider has stood behind.

1. Start from a template#

Open the Funnels section in the clinic console. Every one of the certified questionnaires ships as a ready funnel in the template picker — pick the program you're selling (weight management, TRT, hair, HRT, and the rest of the corpus) and the builder clones it into a draft flow. The clinical plane arrives pre-wired and locked: the medical questions, disqualifiers, and consent steps are the certified version, not something you or the AI hand-edit.

The template is the clinical plane. Choosing a template is how you get certified medical questions into a funnel. You can restyle and rewrite everything around them; you cannot rewrite them.

Creating and editing flows needs the FLOWS_MANAGE role. Seeing the list and its analytics needs FLOWS_VIEW / FLOWS_ANALYTICS_VIEW. See Roles & flags for the full split.

2. Describe your program (AI generation)#

Instead of starting from a bare template, you can describe the program in plain language and let the AI assemble the draft. "Describe your program" calls POST /flows/ai/generate; the model classifies your description, matches it to a certified questionnaire, and writes the landing copy, outcome copy, and a brand theme around it. The clinical steps are injected verbatim from the corpus and stay locked — the AI writes the marketing, never the medicine.

curl -X POST https://api.neolife.health/v1/flows/ai/generate \
  -H "Authorization: Bearer $NEOLIFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "A membership for men starting testosterone therapy, plain and clinical, no hype.",
    "brand": { "url": "https://clinic.example", "name": "Example Clinic" }
  }'

The prompt carries program and brand info only — no PHI ever reaches the model, so this runs on an ordinary API key, and it runs offline against a deterministic stub in demo. The result is a draft flow you edit in the next step; nothing is live yet.

When the corpus doesn't cover the product#

If your program has no certified questionnaire behind it, the AI can draft a new questionnaire in the certified schema via POST /intake/questionnaires/ai-draft. This is the one place AI touches clinical content, so it's fenced hard: it's gated by the counsel-gated flow_ai_freeform_medical flag, a deterministic validator gates the draft, and — same rule as everything else — a licensed provider must approve it before it can be used:

curl -X POST https://api.neolife.health/v1/intake/questionnaires/dq_123/approve \
  -H "Authorization: Bearer $NEOLIFE_API_KEY"

Once approved, it becomes a usable certified tenant questionnaire and shows up in the template picker like any other. A draft that a provider never approves can never gate a live flow. See Intake & provider approval for what "certified" means and why the verdict engine is deterministic.

3. Edit the presentation plane#

The editor is a form, not a free canvas. You edit the presentation plane — everything a patient sees around the medical questions:

  • Copy — landing headline and body, per-step marketing text, the outcome/confirmation screen.
  • Theme — brand tokens exposed as --nl-flow-* CSS variables (color, type, logo), so the flow matches your site.
  • Step order — reorder the presentation steps; the certified clinical steps stay in their certified sequence.
  • Checkout handoff — the URL of your own store's checkout, where a qualified patient lands with the certificate token attached (see step 6).

Autosave persists your draft as you go:

curl -X PATCH https://api.neolife.health/v1/flows/flow_123/draft \
  -H "Authorization: Bearer $NEOLIFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "revision": 7, "presentation": { "landing": { "headline": "Start TRT with a real provider" } } }'

Pass the current revision for optimistic concurrency — an edit against a stale revision returns a conflict, so two editors never clobber each other. Nothing you do here can reach the clinical plane: the editor won't let you add, remove, or reword a medical question, a disqualifier, or a consent block. That's the point.

Rule: the editor can restyle and re-sequence the funnel, but the certified medical steps are read-only. If you need different medical questions, you need a different (certified, provider-approved) questionnaire — not an edit.

4. Add A/B variants (optional)#

If you want to test the funnel, add a presentation-plane experiment. A variant can change any marketing copy, the theme, or the presentation step order — it cannot touch a clinical question, a disqualifier, or a consent step. Because every arm runs the identical certified clinical plane, the certificate a patient earns is identical across variants, and the qualify decision is never a function of which arm they saw.

Assignment is deterministic and sticky server-side, so a returning patient always sees the same arm, and the console shows live control-vs-variant qualify rates. Experiments need the flow_experiments flag (open, Growth tier and up).

5. Publish — a provider approves the clinical plane#

Publishing is not a deploy button; it's a licensure act. The publish gate compares the flow's clinical plane against its certified source and requires a licensed provider (or medical-director role) to approve before it can go live. On publish, the rail records a flow approval certificate — the flow version, a hash of the clinical plane (clinicalPlaneHash), the approving provider's NPI, and a timestamp — as durable proof of who stood behind this funnel.

Publishing requires the FLOWS_PUBLISH role, which is distinct from FLOWS_MANAGE precisely because publish is a clinical decision and editing copy is not. A flow whose clinical plane doesn't match an approved questionnaire version cannot transition to published — it's enforced server-side, not by convention.

AI drafts, a licensed provider signs. No flow reaches a patient without a provider approving its clinical plane on publish. This is the E&O / certificate posture — never describe it as "insured" or "coverage."

Patient-facing publish also stays behind the platform's existing PHI-readiness gate. In demo you can publish and walk the whole funnel end to end; turning it on for real patient traffic is a deployment/config step, not a code change.

6. Ship the hosted page or embed snippet#

Publishing gives you two ways to put the flow in front of patients, both served from neolife's BAA-covered API surface (never from your marketing host):

A hosted page at /f/:embedKey — a self-contained URL you can link to directly or point a custom domain at.

An embed snippet — a one-line loader for flow.js that renders the flow inline on your own page, themed through the same --nl-flow-* tokens:

<div id="neolife-flow"></div>
<script
  src="https://api.neolife.health/embed/v1/flow.js"
  data-embed-key="pk_flow_…"
  data-target="#neolife-flow"></script>

The renderer authenticates with a per-tenant embed key (not your secret API key) and is origin-locked to your domains. Under the hood the patient runtime is a small set of public, embed-key-authenticated routes:

Route What it does
GET /public/flows/:embedKey The patient-safe flow definition (and the assigned A/B variant).
POST /public/flows/:embedKey/sessions Start a session.
POST .../sessions/:id/steps Partial save as the patient answers (also powers drop-off analytics).
POST .../sessions/:id/submit Submit — delegates to the deterministic intake engine.
POST .../sessions/:id/events A PHI-free analytics beacon (views, step transitions).

The full request/response detail is in the Flows API. You normally don't call these yourself — the hosted page and flow.js do — but they're documented so you can build your own renderer if you need to.

7. What happens on submit — and the checkout handoff#

When a patient submits, the runtime hands the answers to the same deterministic intake engine the rest of the platform uses. That yields a verdict: an eligible submission is issued a PHI-free certificate, dropped into the provider review queue, and set up for pharmacy routing; a disqualified submission is a hard stop no one can override.

Checkout is a handoff, not a step neolife runs. A qualified patient is redirected to your own store's checkout carrying the certificate token — neolife never holds patient money, because a prescription can't run on Stripe. Your store reads the token to confirm the patient cleared the gate before it takes payment. This is "gate the prescription, not the cart": PathwAI gets the patient to your door; neolife gets the medication to theirs.

// The qualified handoff carries the certificate token, never clinical detail.
{
  "verdict": "eligible",
  "certificateToken": "cert_…",
  "checkoutUrl": "https://store.clinic.example/cart?nl_cert=cert_…"
}

From here the patient is on the existing rail: provider review → approval → pharmacy routing → shipment, all of which you can drive and reconcile with the platform APIs and PHI-free webhooks (flow.published, flow.session.qualified, flow.session.completed, flow.checkout.completed). See Orders & fulfillment and Handling webhooks.

Recap#

  • Templates are how certified medical questions enter a funnel; the clinical plane is locked.
  • AI matches your program to a certified questionnaire and writes the marketing — never the medicine; PHI never reaches the model.
  • The editor touches the presentation plane only; the certified steps are read-only.
  • Publish is a licensure act — a provider approves the clinical plane and the rail records a flow approval certificate.
  • A qualified patient hands off to your checkout with the certificate token; neolife never holds the money.