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/resolveto begin an intake session and receive the first question, thenPOST /v1/instrument/nextto submit an answer and receive the next one.POST /v1/instrument/abandonrecords a drop-off when a patient leaves early, andGET /v1/instrument/address/suggestpowers an as-you-type address picker.
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.
2. Sign the patient in
Authentication is passwordless by default. Send the patient toGET /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-typeslists the event types you can subscribe to;GET /v1/webhooks/registrationslists 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}/statusfor a patient’s public enrollment status andGET /v1/onboardings/{onboarding_id}/progressfor 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 — a documented outcome to handle alongside the usual authentication and not-found refusals, not a failure.
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.