Skip to main content
GET
Start an intake session and get the first question

Authorizations

Authorization
string
header
required

Per-client API key (M2M). Presented as Authorization: Bearer <key>.

Headers

X-Journey-Id
string

The patient's enrollment id (jny_...) — the resume channel. Send it on a return visit and the questionnaire resumes that patient's session with everything already answered applied; omit it and a new enrollment id is minted. A malformed value is ignored and treated as absent, never trusted.

Pattern: ^jny_[A-Za-z0-9][A-Za-z0-9_-]*$
X-Correlation-Id
string

An optional id you send to tie this request to your own logs. Send one and it is echoed back unchanged; omit it and one is assigned for you. Either way the id is returned in the X-Correlation-Id response header on every response, including errors, so you can match a response to the request that produced it.

Maximum string length: 128
Pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]*$
X-Brand-Id
string
required

Opaque brand id (brd_...). Validated to belong to the resolved client (§2).

Pattern: ^brd_[A-Za-z0-9][A-Za-z0-9_-]*$

Query Parameters

journey_id
string

an existing enrollment id (returning patient) as a query parameter — a compatibility channel. On the hosted platform this query parameter is not read: the enrollment id rides the X-Journey-Id request header, and that header is the resume mechanism. Absent both, a new enrollment id is minted.

Pattern: ^jny_[A-Za-z0-9][A-Za-z0-9_-]*$
phase
enum<string>

serve ONE tier of the instrument as an independent phase. qualification plays the pre-pay funnel-top tier and completes at the qualification terminal (the journey then hands to checkout); clinical plays the post-pay tier (re-resolved by the same enrollment id after checkout) and completes at the usual intake terminal. OMITTED ⇒ the continuous single-pass flow (unchanged): the whole instrument, one terminal. Requires a tier-aware bundle; an unknown value is rejected 400.

Available options:
qualification,
clinical
offering
string

preselect a catalog offering by STABLE ref (never a free-text product name). Resolvable only against the compiled bundle's declared offering refs; an unresolvable ref FAILS CLOSED to the generic flow. Effect is presentation-only narrowing of display-node offering_refs — EXCEPT for a brand configured with MORE THAN ONE enabled therapy, where this parameter is additionally REQUIRED and is a DECLARED RESOLUTION INPUT: it selects which of that brand's enabled therapies the session's questionnaire comes from. Omitting it, naming a ref that belongs to none of the brand's enabled therapies, or naming one that belongs to more than one, is REFUSED (422) — never guessed. For a brand with a single enabled therapy (and for a brand with none) the parameter does not change which SHARED questionnaire is served. SECOND DECLARED EFFECT — YOUR OWN QUALIFICATION QUESTIONS. On an entry that carries no journey (the direct-buy intake the site kit uses, where this endpoint is the op that mints the journey), this parameter ALSO selects WHICH of your brand's own qualification questions are composed onto the served plan, funnel-top: the ones you attached to the offering you name here. This applies only when your brand has declared its enabled therapies and the session resolved one of them; a brand that has declared none is served exactly as before. When the session's journey already recorded an offering, THAT offering wins and this parameter is not consulted for question selection. Naming an offering the platform's committed catalog does not bind, naming one you attached no questions to, or naming a malformed ref all FAIL CLOSED to the shared questionnaire with no error — the parameter can never conjure questions you did not author, and can never reach another brand's questions. THE TREATMENT-AGREEMENT RULE, and the one case that is REFUSED rather than ignored: the offering you name must belong to the SAME treatment the session resolved. Naming a real offering of a DIFFERENT treatment — even one your own brand sells — is refused with the 422 config-gap, not served: a patient must never be asked one treatment's questions while buying another, and answering them silently would be worse than refusing. The refusal is oracle-free: it is the same single answer every structural cause gives, and it names no offering, treatment or brand. An offering the platform cannot bind at all is NOT this case — it simply selects nothing and the shared questionnaire serves as before, so a stale or mistyped link degrades gently while a genuinely wrong-treatment link is caught.

Maximum string length: 128
Pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]*$
prefill_email
string

stage a contact-email prefill. Lands unverified: nothing is written until the patient acts at the confirm step (which ALWAYS renders — prefill is never silent acceptance); a confirm-as-is records method=patient_reported, never validated/patient_confirmed.

Maximum string length: 254
prefill_phone
string

same contract as prefill_email, for the contact phone.

Maximum string length: 32
promo
string

an opaque promo token, passed through unchanged to the completion hand-off. It is not interpreted here; validation, eligibility, and stacking are applied downstream.

Maximum string length: 256
redirect
string

post-completion return URL. Honored ONLY if it matches the brand config's redirect_allowlist (absolute https, exact origin + path-segment prefix); anything else is refused — open redirect barred, fail closed. Surfaces on the completion handoff.

Maximum string length: 2048
test
enum<string>

per-client test-mode flag; passed through unchanged.

Available options:
true,
false,
1,
0

Response

the minted/loaded session + the first node (or complete)

The result of a resolve, next, or abandon call — the session identity, the current question (or null when finished), the status, any flags (e.g. ship_state_mismatch), and any validation issues. On completion it may carry the entry-link hand-off.

journey_id
string
required
Pattern: ^jny_[A-Za-z0-9][A-Za-z0-9_-]*$
session_id
string
required
status
enum<string>
required

active (a node is presented), complete (server-authoritative completion), abandoned (patient drop-off), or blocked — a terminal, server-authoritative refusal to proceed (a required consent was declined or could not be affirmed). On blocked, node is null and blocked carries the honest stop-screen outcome.

Available options:
active,
complete,
abandoned,
blocked
blocked
object

The honest stop-screen outcome. Present only when status is blocked. Carries the machine-readable reason, the node at which the block occurred, the consent scopes that were not granted (codes, never patient data), and a support-routing hint. The stop-screen copy is a presentation concern (the intake kit renders it); no patient data ever rides here. No order lock ever forms without a positive affirmation where one is required.

flags
string[]
handoff
object

Post-completion hand-off carried when a session that began from an entry link completes. Present only when status is complete and the session carried a validated entry context. redirect holds a brand-allowlisted https URL; promo is an opaque pass-through token validated downstream; test is the per-client test-mode flag. Never carries patient data.

issues
object[]
node
object | null

A node as presented to the client — PRESENTATION ONLY. The client never owns the sequence, controls, or option order (those come from the compiled bundle; a brand theme cannot alter them). Brand theme/copy, when applied, ride alongside as presentation overlay.

progress
object

Server-computed progress metadata, present on every resolve/next step: computed from the live effective plan — never client-guessed. position_estimate is the honest fraction of the plan completed (0..1); display nodes participate in the fraction. Whether and how it renders (thin persistent bar, step ring, interstitial pacing, none) is brand-theme presentation.