Concepts

Intake & provider approval

An embeddable per-product questionnaire, evaluated deterministically to a verdict, then reviewed by a licensed provider — and only an approved intake lets an order proceed.

Before a compounded drug ships, someone has to establish that it's appropriate for this patient. neolife makes that a first-class object: a versioned questionnaire the patient answers, a deterministic verdict derived from those answers, and a licensed provider's approval on top. An order can't be submitted until an intake has been approved — the rail enforces the clinical gate, so your integration doesn't have to.

The shape of an intake#

An intake questionnaire is a versioned document tied to a product (or product family). Each version has:

  • A stable key (e.g. glp-weightloss) and a version plus an effectiveDate.
  • A list of questions — text, numeric, single/multi choice, consent blocks, uploads, and display-only info.
  • Rules the engine runs over the answers: conditional visibility, disqualifying answers, computed values (e.g. BMI from height + weight), and product/dose routing.

You author and publish versions through the API; publishing a change mints a new immutable version. Every submission is pinned to the exact version it was answered against, which is what makes a verdict reproducible later — store the version pin and the answers, and the verdict can always be re-derived.

Submitting an intake#

There are two ways answers reach the rail, and they resolve to the same evaluation and the same object.

In-app — your staff (or your own patient-facing UI) submits answers through the authenticated API on a patient's behalf. This is a normal Bearer-authenticated call. See /api/intake.

The public embed widget — a drop-in questionnaire the patient completes directly, hosted at /public/intake. It authenticates with a per-tenant embed key (not your secret API key), is origin-locked to your domains, and returns a patient-safe response — verdict and certificate only, never the internal rule detail or the provider packet. This is the surface to use when the patient fills out the form themselves, on your storefront:

<div id="neolife-intake"></div>
<script
  src="https://api.neolife.health/embed/intake.js"
  data-embed-key="pk_embed_…"
  data-questionnaire="glp-weightloss"
  data-target="#neolife-intake"></script>

Both paths accept an Idempotency-Key so a retried submission is never counted twice.

The verdict#

Evaluation is a pure function of (questionnaire version, answers) — no model sits in the eligibility path. The engine returns one of three verdicts:

Verdict Meaning What happens next
eligible Complete, and no disqualifying answer. Enters provider review (pending_review).
disqualified A disqualifying answer or a rule guard hit. Hard stop — no provider can override it into an order.
incomplete A required, visible question is unanswered. Nothing ships; finish the missing answers.

Because it's deterministic, the same answers always yield the same verdict. A disqualification is decisive even when other answers are missing — a hard stop is a hard stop.

The certificate#

An eligible submission is issued a certificate: a tamper-evident record binding the questionnaire key + version, the answers, the verdict, and the timestamp under a single hash. It's the durable proof that this patient answered this version of the questions and cleared the deterministic gate.

{
  "submissionId": "sub_…",
  "verdict": "eligible",
  "certificate": {
    "hash": "…",
    "questionnaire": { "key": "glp-weightloss", "version": "3", "effectiveDate": "2026-05-01" },
    "submittedAt": "2026-07-06T14:20:00Z"
  }
}

The certificate is PHI-free by construction — a hash and version pins, no names or answers — so it travels safely through your logs and over events.

Provider approval gates the order#

The verdict says the answers cleared the rules. It does not authorize a prescription. Only a licensed provider — a reviewer with prescribing licensure (an NPI) — can review an eligible submission and approve or reject it. That review is a licensure act, gated exactly like order approval: an eligible intake sits in pending_review until a provider decides.

Approval is what unlocks the order:

  1. Patient submits an intake → verdict eligible → certificate issued → status pending_review.
  2. A licensed provider reviews the submission and approves it.
  3. The order the intake is bound to becomes eligible for submission.

Skip or fail any step and the rail refuses. An unapproved order returns order_not_approved on submit — the API will not ship an order that no provider has stood behind. See how that constraint lands on the order lifecycle in Orders.

Each stage emits a PHI-free event (intake.certificate.issued, intake.review.approved, intake.review.rejected) carrying ids, verdicts, and the certificate hash — never answers or patient identity. That's why your webhook endpoint stays outside PHI scope; the details on that split live in The PHI boundary.

Next steps#

  • Intake API — publish versions, submit answers, review submissions.
  • Orders — how approval gates the order lifecycle.
  • The PHI boundary — why certificates and events carry no patient data.