> ## Documentation Index
> Fetch the complete documentation index at: https://docs.purplelabelmd.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

> The three sockets your storefront connects to, and why the platform owns the questionnaire.

You build the storefront your patients see; the platform runs the questionnaire, the sign-in, and
the enrollment behind it. Your integration touches the platform through **three sockets** — send a
patient in, sign the patient in, and observe progress. Everything clinical stays on our side of the
API, so your surface stays small on purpose.

## 1. Send a patient in

There are two ways to start a patient, and they meet at the same place.

* **An entry link** is a URL contract. You direct a patient to a link that carries an **offering
  reference** and, optionally, a return URL, a pass-through promo token, a contact prefill, and a
  test-mode flag. The link is a contract over those parameters — it makes no assumption about a
  hosted page on our side; your storefront owns the presentation.
* **Headless** is the same start, driven by your code. Call `GET /v1/instrument/resolve` to begin
  an intake session and receive the first question, then `POST /v1/instrument/next` to submit an
  answer and receive the next one. `POST /v1/instrument/abandon` records a drop-off when a patient
  leaves early, and `GET /v1/instrument/address/suggest` powers an as-you-type address picker.

A question can capture a file — a photo or a short video — as part of the flow. The bytes upload
directly to storage through a short-lived upload URL, and the answer carries only an **opaque
upload reference**, never the file itself.

### The platform owns the sequence

The order of questions, the branching, and when the questionnaire is finished are computed per
patient and owned by the server. Your storefront **presents** each question; it never decides what
comes next. A patient cannot skip a required question, reorder the flow, or declare themselves
finished — `POST /v1/instrument/next` advances exactly one step, re-validates every answer on the
server, and returns `status: complete` only once every required answer is in. Decisions pin a
versioned copy of the questionnaire, so a patient always finishes the same questionnaire they
started.

### Two kinds of question, one hard line

* **Marketing and qualification screens** are yours to shape — the copy, the theme, and the order
  of your own pre-questionnaire steps. This is the flexible surface.
* **The medical questionnaire** is governed by the physician side. Its questions, their sequence,
  and their branching are never editable from your storefront, and a brand theme can restyle a
  question but can never alter it.

The platform holds these two apart when it compiles the questionnaire, so the flexible part and the
governed part can never be mixed. That separation is the product: you get to brand and arrange the
front of the funnel while the clinical intake stays correct by construction.

## 2. Sign the patient in

Authentication is passwordless by default. Send the patient to `GET /v1/auth/login`, scoped to your
brand — the patient signs in with an emailed code, Google, or Apple, never a password.
`GET /v1/auth/callback` completes the sign-in and starts an encrypted, HttpOnly session cookie for
the patient's browser. `GET /v1/auth/logout` ends the session. Return URLs are honored only when
they are on your brand's allowlist.

## 3. Observe progress

You watch enrollment through **webhooks** plus two read endpoints.

* **Register an endpoint** with `POST /v1/webhooks/registrations`. The response returns an HMAC
  **signing secret one time only** — store it right then, because it is held on our side and never
  returned again. `GET /v1/webhooks/event-types` lists the event types you can subscribe to;
  `GET /v1/webhooks/registrations` lists what you have registered.
* **Test before you go live** with `POST /v1/webhooks/registrations/{registration_id}/test`, which
  sends one clearly-marked test event through the real delivery and signing path.
* **Deliveries are reference-only.** Each delivery carries identifiers and the event type; you fetch
  the full detail through the authorized read for that resource. Failed deliveries are retried
  automatically; once retries are exhausted, the platform's operators handle the dead-lettered
  delivery — it is not a self-serve read on your side.
* **Read status directly** with `GET /v1/journeys/{journey_id}/status` for a patient's public
  enrollment status and `GET /v1/onboardings/{onboarding_id}/progress` for your own onboarding
  progress. Both are read-only and carry identifiers and status values only — never patient data.
  The enrollment read does not always have a status to give you: it may return
  [no status yet](/pages/integrate/the-patient-flow#when-a-status-is-not-yet-reportable) — a
  documented outcome to handle alongside the usual authentication and not-found refusals, not a
  failure.

An enrollment status like `IN_REVIEW` or `ACTION_NEEDED` reflects where the patient actually is. Your
storefront surfaces the platform's decision after it is made — it never tells a patient the outcome
before the review returns it.

## Where payment fits

A patient's enrollment includes a payment step, and it runs in test mode until you go live. By
default it sits between finishing the questionnaire and the clinical review; programs can instead
be configured **pay-first**, collecting payment before the questionnaire begins — the ordering is
a per-program setting, fixed for each enrollment at its start, and the clinical safeguards are
identical either way (see [the ordering note](/pages/integrate/the-patient-flow#where-the-payment-step-sits)).
The payment endpoints are published: see
[Identifiers and error types](/pages/integrate/identifiers-and-error-types) for the checkout and
payment-status calls and their responses, and [The checkout door](/pages/integrate/the-checkout-door)
for how a patient reaches the hosted payment page.

Ready to make the calls? Continue to the [Walkthrough](/pages/integrate/walkthrough).
