Returns a client’s onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (Authorization: Bearer <key>) and X-Brand-Id set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same 404 as an id that does not exist, so the API never confirms whether another client’s onboarding exists. Platform staff can read any client’s progress. When the onboarding has a LegitScript step, legitscript_timeline lists each update’s date and what it means.
Your brand id (brd_...). It must be one of the brands your API key's account owns; with a publishable key it must be the one brand the key was issued for. A missing or malformed value is refused with 400, and an unknown or foreign brand with 404.
A client's onboarding progress in plain language: which step of how many, what is waiting on the client, and whether this is test mode. Presentation only; it never carries clinical data.
Present when the journey API composes the catalog certification read and the onboarding has the LegitScript step: the step's status timeline in plain words (no vendor codes, no staff details).
Show child attributes
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Purple Label MD","description":"Public API reference for building a patient storefront on the platform. Generated from the platform's own API contracts, and matches the newest staging release.","colors":{"primary":"#6D28D9","light":"#A78BFA","dark":"#5B21B6"},"logo":{"light":"https://mintcdn.com/purplelabelmd/1P9p4n7lsNL4z3Jc/logo/light.svg?fit=max\u0026auto=format\u0026n=1P9p4n7lsNL4z3Jc\u0026q=85\u0026s=3c0569e3f76e49e04d232187908c2e2e","dark":"https://mintcdn.com/purplelabelmd/1P9p4n7lsNL4z3Jc/logo/dark.svg?fit=max\u0026auto=format\u0026n=1P9p4n7lsNL4z3Jc\u0026q=85\u0026s=c11f42bb461c28528be896c7c1a80efa"},"favicon":"https://mintcdn.com/purplelabelmd/MUdvgTlYoCGY54e8/favicon.svg?fit=max\u0026auto=format\u0026n=MUdvgTlYoCGY54e8\u0026q=85\u0026s=3bd633ab20ff170e0ebebec0406e6972","footer":{"socials":{}},"fonts":{"heading":{"family":"Geist"},"body":{"family":"Geist"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"purplelabelmd","hasAudioNarration":false,"actualSubdomain":"purplelabelmd","customDomains":["docs.purplelabelmd.com"],"gitSource":{"type":"github","owner":"purple-label-md","repo":"purple-doc","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af545312fc9183f3253a260","clientVersion":"0.0.4111","searchFilterCounts":[{"language":"default","tag":"API reference","count":50},{"language":"default","tag":"Guides","count":21},{"language":"default","tag":"Offering configuration","count":18},{"language":"default","tag":"Integrate","count":16},{"language":"default","tag":"Brand configuration","count":9},{"language":"default","tag":"Webhooks","count":7},{"language":"default","tag":"Payments","count":4},{"language":"default","tag":"Intake","count":3},{"language":"default","tag":"Onboarding","count":3},{"language":"default","tag":"Sessions \u0026 authentication","count":3}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[{"filePath":"style.css","content":"@media (prefers-reduced-motion: no-preference){.plmd-logo{transform-origin:center;transition:transform 0.12s ease}.plmd-logo .plmd-mark path{transform-box:fill-box;transform-origin:center}.plmd-logo-link:active .plmd-logo{transform:scale(0.85)}.plmd-logo-link:hover .plmd-logo .plmd-mark path:last-child{animation:plmd-carrot-hop 0.55s ease}.plmd-logo-link:hover .plmd-logo .plmd-mark path:nth-child(-n+6){animation:plmd-carrot-twinkle 0.5s ease}.plmd-logo-link:hover .plmd-logo .plmd-mark path:nth-child(even){animation-delay:0.08s}}@keyframes plmd-carrot-hop{0%{transform:translateY(0) rotate(0)}30%{transform:translateY(-14%) rotate(-9deg)}55%{transform:translateY(0) rotate(6deg)}78%{transform:translateY(-5%) rotate(-2deg)}100%{transform:translateY(0) rotate(0)}}@keyframes plmd-carrot-twinkle{0%,100%{transform:scale(1);opacity:1}45%{transform:scale(1.6);opacity:0.7}}"}],"page":{"pagePath":"api-reference/onboarding/read-a-clients-onboarding-progress","slug":"/api-reference/onboarding/read-a-clients-onboarding-progress","pageMetadata":{"title":"Read a client's onboarding progress","description":"Returns a client's onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (`Authorization: Bearer \u003ckey>`) and `X-Brand-Id` set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same `404` as an id that does not exist, so the API never confirms whether another client's onboarding exists. Platform staff can read any client's progress. When the onboarding has a LegitScript step, `legitscript_timeline` lists each update's date and what it means.","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/onboardings/{onboarding_id}/progress","href":"/api-reference/onboarding/read-a-clients-onboarding-progress","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_components.p, {\n children: [\"Returns a client’s onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (\", _jsx(_components.code, {\n children: \"Authorization: Bearer \u003ckey>\"\n }), \") and \", _jsx(_components.code, {\n children: \"X-Brand-Id\"\n }), \" set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same \", _jsx(_components.code, {\n children: \"404\"\n }), \" as an id that does not exist, so the API never confirms whether another client’s onboarding exists. Platform staff can read any client’s progress. When the onboarding has a LegitScript step, \", _jsx(_components.code, {\n children: \"legitscript_timeline\"\n }), \" lists each update’s date and what it means.\"]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Read a client's onboarding progress","description":"Returns a client's onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (`Authorization: Bearer \u003ckey>`) and `X-Brand-Id` set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same `404` as an id that does not exist, so the API never confirms whether another client's onboarding exists. Platform staff can read any client's progress. When the onboarding has a LegitScript step, `legitscript_timeline` lists each update's date and what it means.","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/onboardings/{onboarding_id}/progress","href":"/api-reference/onboarding/read-a-clients-onboarding-progress","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/_mintlify/custom/purplelabelmd/3b4d4a495cd0c48d/brand.js"],"openApiReferenceData":{"operation":{"description":"Returns a client's onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (`Authorization: Bearer \u003ckey>`) and `X-Brand-Id` set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same `404` as an id that does not exist, so the API never confirms whether another client's onboarding exists. Platform staff can read any client's progress. When the onboarding has a LegitScript step, `legitscript_timeline` lists each update's date and what it means.","parameters":["7e894bf0-4c15-4195-8873-88ea3fa02041","46e4f8ef-6eac-4eb0-b6da-9e65c399416e"],"responses":{"200":"77ed6bc4-2644-4ec6-9524-a11350a4855e","400":"9d717e95-97a5-423f-ad9e-3db7353a8c7d","401":"30b8dd3c-9ae7-4052-835e-68e5b93d1f5a","404":"5a89449a-303a-4e14-a2b9-4f1bb7a3dc37","503":"8a614723-d40a-4da8-82ad-519989c8c97f"},"security":["25a67c6c-2c25-46c2-8d95-90f8b5786e7d"],"summary":"Read a client's onboarding progress","tags":["Onboarding"],"method":"get","type":"path","servers":["76f2c082-b62c-4aea-a087-a046f1378296"],"path":"/v1/onboardings/{onboarding_id}/progress","baseUrlOptions":["https://api.staging.purplelabelmd.com"],"title":"Read a client's onboarding progress","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"7e894bf0-4c15-4195-8873-88ea3fa02041":{"in":"path","name":"onboarding_id","required":true,"schema":{"pattern":"^onb_[A-Za-z0-9][A-Za-z0-9_-]*$","type":"string","isRequired":true,"uniqueKey":"","typeLabel":"string"}},"46e4f8ef-6eac-4eb0-b6da-9e65c399416e":{"description":"Your brand id (`brd_...`). It must be one of the brands your API key's account owns; with a publishable key it must be the one brand the key was issued for. A missing or malformed value is refused with `400`, and an unknown or foreign brand with `404`.","in":"header","name":"X-Brand-Id","required":true,"schema":{"pattern":"^brd_[A-Za-z0-9][A-Za-z0-9_-]*$","type":"string","isRequired":true,"description":"Your brand id (`brd_...`). It must be one of the brands your API key's account owns; with a publishable key it must be the one brand the key was issued for. A missing or malformed value is refused with `400`, and an unknown or foreign brand with `404`.","uniqueKey":"","typeLabel":"string"}}},"responses":{"77ed6bc4-2644-4ec6-9524-a11350a4855e":{"content":{"application/json":{"schema":{"description":"A client's onboarding progress in plain language: which step of how many, what is waiting on the client, and whether this is test mode. Presentation only; it never carries clinical data.","properties":{"blocked_on_client":{"description":"what we're currently waiting on the CLIENT for (plain-language)","items":{"type":"string","uniqueKey":"blocked_on_client.items.[INDEX]","typeLabel":"string"},"type":"array","isRequired":true,"uniqueKey":"blocked_on_client","typeLabel":"string[]"},"complete":{"type":"boolean","isRequired":true,"uniqueKey":"complete","typeLabel":"boolean"},"onboarding_id":{"pattern":"^onb_[A-Za-z0-9][A-Za-z0-9_-]*$","type":"string","isRequired":true,"uniqueKey":"onboarding_id","typeLabel":"string"},"plain_language":{"type":"string","isRequired":true,"uniqueKey":"plain_language","typeLabel":"string"},"step_number":{"type":"integer","isRequired":true,"uniqueKey":"step_number","typeLabel":"integer"},"test_mode":{"type":"boolean","isRequired":true,"uniqueKey":"test_mode","typeLabel":"boolean"},"total_steps":{"type":"integer","isRequired":true,"uniqueKey":"total_steps","typeLabel":"integer"},"legitscript_timeline":{"description":"Present when the journey API composes the catalog certification read and the onboarding has the LegitScript step: the step's status timeline in plain words (no vendor codes, no staff details).","properties":{"entries":{"items":{"additionalProperties":false,"properties":{"at":{"format":"date-time","type":"string","isRequired":true,"uniqueKey":"legitscript_timeline.entries.items.[INDEX].at","typeLabel":"string\u003cdate-time>"},"meaning":{"type":"string","isRequired":true,"uniqueKey":"legitscript_timeline.entries.items.[INDEX].meaning","typeLabel":"string"}},"required":["at","meaning"],"type":"object","uniqueKey":"legitscript_timeline.entries.items.[INDEX]","typeLabel":"object"},"type":"array","isRequired":true,"uniqueKey":"legitscript_timeline.entries","typeLabel":"object[]"},"state":{"enum":["ok","unavailable"],"type":"string","isRequired":true,"uniqueKey":"legitscript_timeline.state","typeLabel":"enum\u003cstring>"}},"required":["state","entries"],"type":"object","uniqueKey":"legitscript_timeline","typeLabel":"object"}},"required":["onboarding_id","step_number","total_steps","plain_language","blocked_on_client","test_mode","complete"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"blocked_on_client":["\u003cstring>"],"complete":true,"onboarding_id":"\u003cstring>","plain_language":"\u003cstring>","step_number":123,"test_mode":true,"total_steps":123,"legitscript_timeline":{"entries":[{"at":"2023-11-07T05:31:56Z","meaning":"\u003cstring>"}],"state":"ok"}}}},"exampleType":"generated"}},"description":"the client-visible progress","exampleType":"generated"},"9d717e95-97a5-423f-ad9e-3db7353a8c7d":{"content":{"application/problem+json":{"schema":{"description":"RFC 7807 problem+json error body. `code` is a machine-code extension member (the CatalogProblem precedent): a refusal that has a typed reason NAMES it, so a caller branches on a token instead of parsing prose. It is OPTIONAL because an absent code is honest — a validation 400 already names the exact offending field path in `detail`, and a token invented to cover several distinct causes would rebuild the ambiguity it claims to cure. Every code this fragment declares appears in the 4xx description of the op that can emit it.","properties":{"status":{"type":"integer","isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"title":{"type":"string","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"type":{"format":"uri-reference","type":"string","isRequired":true,"uniqueKey":"type","typeLabel":"string\u003curi-reference>"},"code":{"description":"machine-readable refusal token (SCREAMING_SNAKE) — ONE token per distinct cause. The step-action surface emits: ONBOARDING_NOT_FOUND · STEP_UNKNOWN (404) · STEP_ALREADY_DONE · ONBOARDING_CLOSED · IDEMPOTENCY_CONFLICT (409) · ACTION_NOT_APPLICABLE · GOLIVE_EVIDENCE_INCOMPLETE (422). The live-signal ingest emits IDEMPOTENCY_CONFLICT · LIVE_JOURNEY_TENANCY_CONFLICT; the kickoff emits IDEMPOTENCY_CONFLICT · ONBOARDING_EXISTS. The onboarding record operations add: RECORD_REQUEST_INVALID (422) on all three records; EXECUTED_ON_IN_FUTURE (422) · AGREEMENT_UNKNOWN (422) · AGREEMENT_ALREADY_EXECUTED (409) on the agreement record; PRACTICE_ORDER_ALREADY_PASSED (409) on the practice-order record; PRACTICE_ORDER_NOT_PASSED · CLIENT_APPROVAL_ALREADY_RECORDED (409) on the client-approval record.","type":"string","uniqueKey":"code","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"detail","typeLabel":"string"},"instance":{"description":"the request path the problem is about (RFC 7807 instance)","type":"string","uniqueKey":"instance","typeLabel":"string"},"reason":{"description":"Why an onboarding's state could not be read, on the 503 an onboarding read answers: timeout (no answer in time) or query_failed (the read itself failed). A fixed code, never an upstream error message. Absent on every other problem.","enum":["timeout","query_failed"],"type":"string","uniqueKey":"reason","typeLabel":"enum\u003cstring>"}},"required":["type","title","status"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"status":123,"title":"\u003cstring>","type":"\u003cstring>","code":"\u003cstring>","detail":"\u003cstring>","instance":"\u003cstring>","reason":"timeout"}}},"exampleType":"generated"}},"description":"`X-Brand-Id` is missing or malformed on a call made with an API key.","exampleType":"generated"},"30b8dd3c-9ae7-4052-835e-68e5b93d1f5a":{"content":{"application/problem+json":{"schema":{"description":"RFC 7807 problem+json error body. `code` is a machine-code extension member (the CatalogProblem precedent): a refusal that has a typed reason NAMES it, so a caller branches on a token instead of parsing prose. It is OPTIONAL because an absent code is honest — a validation 400 already names the exact offending field path in `detail`, and a token invented to cover several distinct causes would rebuild the ambiguity it claims to cure. Every code this fragment declares appears in the 4xx description of the op that can emit it.","properties":{"status":{"type":"integer","isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"title":{"type":"string","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"type":{"format":"uri-reference","type":"string","isRequired":true,"uniqueKey":"type","typeLabel":"string\u003curi-reference>"},"code":{"description":"machine-readable refusal token (SCREAMING_SNAKE) — ONE token per distinct cause. The step-action surface emits: ONBOARDING_NOT_FOUND · STEP_UNKNOWN (404) · STEP_ALREADY_DONE · ONBOARDING_CLOSED · IDEMPOTENCY_CONFLICT (409) · ACTION_NOT_APPLICABLE · GOLIVE_EVIDENCE_INCOMPLETE (422). The live-signal ingest emits IDEMPOTENCY_CONFLICT · LIVE_JOURNEY_TENANCY_CONFLICT; the kickoff emits IDEMPOTENCY_CONFLICT · ONBOARDING_EXISTS. The onboarding record operations add: RECORD_REQUEST_INVALID (422) on all three records; EXECUTED_ON_IN_FUTURE (422) · AGREEMENT_UNKNOWN (422) · AGREEMENT_ALREADY_EXECUTED (409) on the agreement record; PRACTICE_ORDER_ALREADY_PASSED (409) on the practice-order record; PRACTICE_ORDER_NOT_PASSED · CLIENT_APPROVAL_ALREADY_RECORDED (409) on the client-approval record.","type":"string","uniqueKey":"code","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"detail","typeLabel":"string"},"instance":{"description":"the request path the problem is about (RFC 7807 instance)","type":"string","uniqueKey":"instance","typeLabel":"string"},"reason":{"description":"Why an onboarding's state could not be read, on the 503 an onboarding read answers: timeout (no answer in time) or query_failed (the read itself failed). A fixed code, never an upstream error message. Absent on every other problem.","enum":["timeout","query_failed"],"type":"string","uniqueKey":"reason","typeLabel":"enum\u003cstring>"}},"required":["type","title","status"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"status":123,"title":"\u003cstring>","type":"\u003cstring>","code":"\u003cstring>","detail":"\u003cstring>","instance":"\u003cstring>","reason":"timeout"}}},"exampleType":"generated"}},"description":"No valid credential was presented: the API key is missing, unknown or revoked.","exampleType":"generated"},"5a89449a-303a-4e14-a2b9-4f1bb7a3dc37":{"content":{"application/problem+json":{"schema":{"description":"RFC 7807 problem+json error body. `code` is a machine-code extension member (the CatalogProblem precedent): a refusal that has a typed reason NAMES it, so a caller branches on a token instead of parsing prose. It is OPTIONAL because an absent code is honest — a validation 400 already names the exact offending field path in `detail`, and a token invented to cover several distinct causes would rebuild the ambiguity it claims to cure. Every code this fragment declares appears in the 4xx description of the op that can emit it.","properties":{"status":{"type":"integer","isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"title":{"type":"string","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"type":{"format":"uri-reference","type":"string","isRequired":true,"uniqueKey":"type","typeLabel":"string\u003curi-reference>"},"code":{"description":"machine-readable refusal token (SCREAMING_SNAKE) — ONE token per distinct cause. The step-action surface emits: ONBOARDING_NOT_FOUND · STEP_UNKNOWN (404) · STEP_ALREADY_DONE · ONBOARDING_CLOSED · IDEMPOTENCY_CONFLICT (409) · ACTION_NOT_APPLICABLE · GOLIVE_EVIDENCE_INCOMPLETE (422). The live-signal ingest emits IDEMPOTENCY_CONFLICT · LIVE_JOURNEY_TENANCY_CONFLICT; the kickoff emits IDEMPOTENCY_CONFLICT · ONBOARDING_EXISTS. The onboarding record operations add: RECORD_REQUEST_INVALID (422) on all three records; EXECUTED_ON_IN_FUTURE (422) · AGREEMENT_UNKNOWN (422) · AGREEMENT_ALREADY_EXECUTED (409) on the agreement record; PRACTICE_ORDER_ALREADY_PASSED (409) on the practice-order record; PRACTICE_ORDER_NOT_PASSED · CLIENT_APPROVAL_ALREADY_RECORDED (409) on the client-approval record.","type":"string","uniqueKey":"code","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"detail","typeLabel":"string"},"instance":{"description":"the request path the problem is about (RFC 7807 instance)","type":"string","uniqueKey":"instance","typeLabel":"string"},"reason":{"description":"Why an onboarding's state could not be read, on the 503 an onboarding read answers: timeout (no answer in time) or query_failed (the read itself failed). A fixed code, never an upstream error message. Absent on every other problem.","enum":["timeout","query_failed"],"type":"string","uniqueKey":"reason","typeLabel":"enum\u003cstring>"}},"required":["type","title","status"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"status":123,"title":"\u003cstring>","type":"\u003cstring>","code":"\u003cstring>","detail":"\u003cstring>","instance":"\u003cstring>","reason":"timeout"}}},"exampleType":"generated"}},"description":"The onboarding is not visible to you: it does not exist, its id is malformed, or it belongs to another client. All three answer this same response — the API never confirms whether another client's onboarding exists. An `X-Brand-Id` that is not one of your brands answers a 404 too.","exampleType":"generated"},"8a614723-d40a-4da8-82ad-519989c8c97f":{"content":{"application/problem+json":{"schema":{"description":"RFC 7807 problem+json error body. `code` is a machine-code extension member (the CatalogProblem precedent): a refusal that has a typed reason NAMES it, so a caller branches on a token instead of parsing prose. It is OPTIONAL because an absent code is honest — a validation 400 already names the exact offending field path in `detail`, and a token invented to cover several distinct causes would rebuild the ambiguity it claims to cure. Every code this fragment declares appears in the 4xx description of the op that can emit it.","properties":{"status":{"type":"integer","isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"title":{"type":"string","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"type":{"format":"uri-reference","type":"string","isRequired":true,"uniqueKey":"type","typeLabel":"string\u003curi-reference>"},"code":{"description":"machine-readable refusal token (SCREAMING_SNAKE) — ONE token per distinct cause. The step-action surface emits: ONBOARDING_NOT_FOUND · STEP_UNKNOWN (404) · STEP_ALREADY_DONE · ONBOARDING_CLOSED · IDEMPOTENCY_CONFLICT (409) · ACTION_NOT_APPLICABLE · GOLIVE_EVIDENCE_INCOMPLETE (422). The live-signal ingest emits IDEMPOTENCY_CONFLICT · LIVE_JOURNEY_TENANCY_CONFLICT; the kickoff emits IDEMPOTENCY_CONFLICT · ONBOARDING_EXISTS. The onboarding record operations add: RECORD_REQUEST_INVALID (422) on all three records; EXECUTED_ON_IN_FUTURE (422) · AGREEMENT_UNKNOWN (422) · AGREEMENT_ALREADY_EXECUTED (409) on the agreement record; PRACTICE_ORDER_ALREADY_PASSED (409) on the practice-order record; PRACTICE_ORDER_NOT_PASSED · CLIENT_APPROVAL_ALREADY_RECORDED (409) on the client-approval record.","type":"string","uniqueKey":"code","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"detail","typeLabel":"string"},"instance":{"description":"the request path the problem is about (RFC 7807 instance)","type":"string","uniqueKey":"instance","typeLabel":"string"},"reason":{"description":"Why an onboarding's state could not be read, on the 503 an onboarding read answers: timeout (no answer in time) or query_failed (the read itself failed). A fixed code, never an upstream error message. Absent on every other problem.","enum":["timeout","query_failed"],"type":"string","uniqueKey":"reason","typeLabel":"enum\u003cstring>"}},"required":["type","title","status"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"status":123,"title":"\u003cstring>","type":"\u003cstring>","code":"\u003cstring>","detail":"\u003cstring>","instance":"\u003cstring>","reason":"timeout"}}},"exampleType":"generated"}},"description":"Platform staff only: this onboarding's progress can't be read right now. The onboarding may still exist, so this is never \"no such onboarding\". Try again shortly. `reason` says why: timeout (no answer in time) or query_failed (the read itself failed). With an API key, an onboarding that can't be read right now answers the `404`, so the answer never reveals whether another client's onboarding exists; retry later if the onboarding is yours.","exampleType":"generated"}},"security":{"25a67c6c-2c25-46c2-8d95-90f8b5786e7d":{"apiKey":{"description":"Per-client API key (M2M). Presented as `Authorization: Bearer \u003ckey>`.","scheme":"bearer","type":"http","scopes":[],"schemeName":"apiKey"}}},"servers":{"76f2c082-b62c-4aea-a087-a046f1378296":{"url":"https://api.staging.purplelabelmd.com"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"description":"Per-client API key (M2M). Presented as `Authorization: Bearer \u003ckey>`.","scheme":"bearer","type":"http","scopes":[],"schemeName":"apiKey"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Per-client API key (M2M). Presented as `Authorization: Bearer \u003ckey>`.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"apiKey","name":"Authorization"}],"title":"apiKey"}]},"originalFileLocation":"openapi/public-openapi.json"},"subdomain":"purplelabelmd","siteName":"Purple Label MD","title":"Read a client's onboarding progress - Purple Label MD","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-12T04:48:53.112Z","originalFileLocation":"api-reference/onboarding/read-a-clients-onboarding-progress.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Returns a client\u0026#x27;s onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (Authorization: Bearer ) and X-Brand-Id set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same 404 as an id that does not exist, so the API never confirms whether another client\u0026#x27;s onboarding exists. Platform staff can read any client\u0026#x27;s progress. When the onboarding has a LegitScript step, legitscript_timeline lists each update\u0026#x27;s date and what it means.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Purple Label MD\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Read a client\u0026#x27;s onboarding progress - Purple Label MD\">\u003cmeta data-mint-head property=\"og:description\" content=\"Returns a client\u0026#x27;s onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (Authorization: Bearer ) and X-Brand-Id set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same 404 as an id that does not exist, so the API never confirms whether another client\u0026#x27;s onboarding exists. Platform staff can read any client\u0026#x27;s progress. When the onboarding has a LegitScript step, legitscript_timeline lists each update\u0026#x27;s date and what it means.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Purple Label MD\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://purplelabelmd.mintlify.site/_mintlify/api/og/v2?division=Onboarding\u0026amp;title=Read+a+client%27s+onboarding+progress\u0026amp;description=Returns+a+client%27s+onboarding+progress+in+plain+language+%E2%80%94+which+step+of+how+many%2C+and+what+is+currently+waiting+on+the+client.+Presentation+only%3B+it+never+carr\u0026amp;theme=1cfc55286f6f85a93657a32a\u0026amp;signature=e7ada1fe2536e643dcd2341ffba384a7ee213a7dfe62424f1f56749abc87982d\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Read a client\u0026#x27;s onboarding progress - Purple Label MD\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Returns a client\u0026#x27;s onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (Authorization: Bearer ) and X-Brand-Id set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same 404 as an id that does not exist, so the API never confirms whether another client\u0026#x27;s onboarding exists. Platform staff can read any client\u0026#x27;s progress. When the onboarding has a LegitScript step, legitscript_timeline lists each update\u0026#x27;s date and what it means.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://purplelabelmd.mintlify.site/_mintlify/api/og/v2?division=Onboarding\u0026amp;title=Read+a+client%27s+onboarding+progress\u0026amp;description=Returns+a+client%27s+onboarding+progress+in+plain+language+%E2%80%94+which+step+of+how+many%2C+and+what+is+currently+waiting+on+the+client.+Presentation+only%3B+it+never+carr\u0026amp;theme=1cfc55286f6f85a93657a32a\u0026amp;signature=e7ada1fe2536e643dcd2341ffba384a7ee213a7dfe62424f1f56749abc87982d\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/purplelabelmd/TU4Si8SnCOFGjzcC/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Purple Label MD\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#6D28D9\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/onboarding/read-a-clients-onboarding-progress.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.purplelabelmd.com/#organization\",\"name\":\"Purple Label MD\",\"url\":\"https://docs.purplelabelmd.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/purplelabelmd/1P9p4n7lsNL4z3Jc/logo/light.svg?fit=max\u0026auto=format\u0026n=1P9p4n7lsNL4z3Jc\u0026q=85\u0026s=3c0569e3f76e49e04d232187908c2e2e\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.purplelabelmd.com#website\",\"name\":\"Purple Label MD\",\"url\":\"https://docs.purplelabelmd.com\",\"publisher\":{\"@id\":\"https://docs.purplelabelmd.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress#webpage\",\"url\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress\",\"name\":\"Read a client's onboarding progress\",\"description\":\"Returns a client's onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (Authorization: Bearer ) and X-Brand-Id set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same 404 as an id that does not exist, so the API never confirms whether another client's onboarding exists. Platform staff can read any client's progress. When the onboarding has a LegitScript step, legitscript_timeline lists each update's date and what it means.\",\"dateModified\":\"2026-11-12T04:48:53.112Z\",\"isPartOf\":{\"@id\":\"https://docs.purplelabelmd.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Onboarding\",\"item\":\"https://docs.purplelabelmd.com/api-reference/onboarding/check-whether-your-brand-is-ready-to-sell\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Read a client's onboarding progress\",\"item\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress#apireference\",\"headline\":\"Read a client's onboarding progress\",\"name\":\"Read a client's onboarding progress\",\"description\":\"Returns a client's onboarding progress in plain language — which step of how many, and what is currently waiting on the client. Presentation only; it never carries clinical data. Call it with your API key (Authorization: Bearer ) and X-Brand-Id set to one of your brands, for an onboarding of your own client. An onboarding that belongs to another client answers the same 404 as an id that does not exist, so the API never confirms whether another client's onboarding exists. Platform staff can read any client's progress. When the onboarding has a LegitScript step, legitscript_timeline lists each update's date and what it means.\",\"url\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress\",\"mainEntityOfPage\":{\"@id\":\"https://docs.purplelabelmd.com/api-reference/onboarding/read-a-clients-onboarding-progress#webpage\"},\"dateModified\":\"2026-11-12T04:48:53.112Z\",\"publisher\":{\"@id\":\"https://docs.purplelabelmd.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.purplelabelmd.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Purple Label MD\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Purple Label MD\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/onboarding/read-a-clients-onboarding-progress.md","siteName":"Purple Label MD","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":"/pages/overview"}]},{"tab":"API reference","groups":[{"group":"Brand configuration","pages":[{"title":"Read back your brand's platform configuration","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/config","href":"/api-reference/brand-configuration/read-back-your-brands-platform-configuration"},{"title":"Set your brand's display identity","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/brands/{brand_id}/config","href":"/api-reference/brand-configuration/set-your-brands-display-identity"},{"title":"List your brand's custom domains","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/domains","href":"/api-reference/brand-configuration/list-your-brands-custom-domains"},{"title":"Read the browser origins your storefront may read this brand from","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/domains/member/browser-origins","href":"/api-reference/brand-configuration/read-the-browser-origins-your-storefront-may-read-this-brand-from"},{"title":"Replace the browser origins your storefront may read this brand from","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/brands/{brand_id}/domains/member/browser-origins","href":"/api-reference/brand-configuration/replace-the-browser-origins-your-storefront-may-read-this-brand-from"},{"title":"Read one custom-domain row","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/domains/{kind}","href":"/api-reference/brand-configuration/read-one-custom-domain-row"},{"title":"Choose a custom domain for a kind (client self-serve)","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/brands/{brand_id}/domains/{kind}","href":"/api-reference/brand-configuration/choose-a-custom-domain-for-a-kind-client-self-serve"},{"title":"Remove a custom domain (revert to the shared domain)","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json delete /v1/account/brands/{brand_id}/domains/{kind}","href":"/api-reference/brand-configuration/remove-a-custom-domain-revert-to-the-shared-domain"},{"title":"Verify a custom domain and advance provisioning","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/brands/{brand_id}/domains/{kind}/verify","href":"/api-reference/brand-configuration/verify-a-custom-domain-and-advance-provisioning"}]},{"group":"Offering configuration","pages":[{"title":"List your brand's enabled offerings","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/offerings","href":"/api-reference/offering-configuration/list-your-brands-enabled-offerings"},{"title":"Enable an offering for your brand","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/brands/{brand_id}/offerings","href":"/api-reference/offering-configuration/enable-an-offering-for-your-brand"},{"title":"Choose the billing cadence of an offering on your brand","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/brands/{brand_id}/offerings/{offering_ref}/billing-cadence","href":"/api-reference/offering-configuration/choose-the-billing-cadence-of-an-offering-on-your-brand"},{"title":"Set your brand's price for an offering","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/brands/{brand_id}/pricing","href":"/api-reference/offering-configuration/set-your-brands-price-for-an-offering"},{"title":"Adopt the starter merchandising pack for your brand","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/brands/{brand_id}/starter-merchandising","href":"/api-reference/offering-configuration/adopt-the-starter-merchandising-pack-for-your-brand"},{"title":"Read an offering's composed qualification questions","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/offerings/{offering_ref}/qualification","href":"/api-reference/offering-configuration/read-an-offerings-composed-qualification-questions"},{"title":"Add a library question to an offering","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/offerings/{offering_ref}/qualification","href":"/api-reference/offering-configuration/add-a-library-question-to-an-offering"},{"title":"Reorder an offering's qualification questions","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/offerings/{offering_ref}/qualification/order","href":"/api-reference/offering-configuration/reorder-an-offerings-qualification-questions"},{"title":"Publish an offering's qualification questions","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/offerings/{offering_ref}/qualification/publish","href":"/api-reference/offering-configuration/publish-an-offerings-qualification-questions"},{"title":"Remove an offering's qualification question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json delete /v1/account/offerings/{offering_ref}/qualification/questions/{question_id}","href":"/api-reference/offering-configuration/remove-an-offerings-qualification-question"},{"title":"Edit an offering's qualification question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json patch /v1/account/offerings/{offering_ref}/qualification/questions/{question_id}","href":"/api-reference/offering-configuration/edit-an-offerings-qualification-question"},{"title":"Set the display name and presentation copy for your offering","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json put /v1/account/offerings/{ref}/merchandising","href":"/api-reference/offering-configuration/set-the-display-name-and-presentation-copy-for-your-offering"},{"title":"List the facts a qualification question may bind","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/question-library/facts","href":"/api-reference/offering-configuration/list-the-facts-a-qualification-question-may-bind"},{"title":"Create a new screening fact for your brand","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/question-library/minted-facts","href":"/api-reference/offering-configuration/create-a-new-screening-fact-for-your-brand"},{"title":"List your brand's qualification question library","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/question-library/questions","href":"/api-reference/offering-configuration/list-your-brands-qualification-question-library"},{"title":"Create a qualification library question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/account/question-library/questions","href":"/api-reference/offering-configuration/create-a-qualification-library-question"},{"title":"Delete a qualification library question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json delete /v1/account/question-library/questions/{question_id}","href":"/api-reference/offering-configuration/delete-a-qualification-library-question"},{"title":"Edit a qualification library question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json patch /v1/account/question-library/questions/{question_id}","href":"/api-reference/offering-configuration/edit-a-qualification-library-question"}]},{"group":"Onboarding","pages":[{"title":"Check whether your brand is ready to sell","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/readiness","href":"/api-reference/onboarding/check-whether-your-brand-is-ready-to-sell"},{"title":"Read one offering's price and whether your brand can sell it","description":"Everything a storefront page needs before it renders a price: the current price and terms for one of your offerings, and your brand's readiness to sell it, in one request. The two travel together on purpose — a price on its own does not tell you whether a purchase would go through, and a page that shows one without the other can offer a customer something the checkout will refuse. The price is the same price the checkout charges, from the same source; this endpoint never computes a second one. Read price_status before the amount: pending means the terms are not fully set up yet, and no amount is shown rather than a guessed one. Read the readiness block before you render a buy control. You may ask about your own brands only; any other brand is not found. This read changes nothing. CALLING IT FROM A BROWSER: a web page may call this read directly. Present a publishable brand key — sent as `Authorization: Bearer pub_live_…`, or `pub_test_…` outside production — which is minted for a single brand, is read-only, and is meant to be shipped in page source. The key reaches only the operations its allowlist names: today that is this read and that brand's readiness read, and nothing else — every other operation, and every write, is refused. Because it is minted for one brand it may only ask about that brand — any other brand, a sibling brand on your own account included, answers the same not found as a brand that does not exist, and the refusal never tells you which of those it was. A cross-origin page must also have its exact origin registered on that brand's browser-origin allowlist, so publishing the key does not by itself open the read to any site. The server path is unchanged — call this endpoint from your own server with your secret API key exactly as before, and never put that secret key in page source.","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/brands/{brand_id}/storefront","href":"/api-reference/onboarding/read-one-offerings-price-and-whether-your-brand-can-sell-it"},{"title":"Read a client's onboarding progress","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/onboardings/{onboarding_id}/progress","href":"/api-reference/onboarding/read-a-clients-onboarding-progress"}]},{"group":"Payments","pages":[{"title":"List your orders across all your brands","description":"Lists your orders across all the brands your API key owns — the queryable backing read that makes your webhook stream reconcilable, so a missed, delayed, or replayed delivery always has an authoritative source to reconcile against. The results are scoped to the brands your key owns; you never supply a caller id, body, or query to widen that scope. Results are returned in a stable total order (updated_at ascending, then order_ref ascending): record the greatest updated_at you have processed, pass it as updated_since to fetch everything that changed after that watermark, and walk the opaque, scope-bound cursor to the end — so a caller who dropped a week of deliveries can reconcile completely from this endpoint alone. An optional brand_id narrows the results to one of your brands; a brand your key does not own is treated as not found (404, never 403, so existence is never revealed). Each row includes only the order reference, brand, offering, status, exact amount in minor units, currency, and timestamps — never patient identity or medical information. It reports your orders; it never moves money.","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/orders","href":"/api-reference/payments/list-your-orders-across-all-your-brands"},{"title":"Read one of your orders by reference","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/account/orders/{order_ref}","href":"/api-reference/payments/read-one-of-your-orders-by-reference"},{"title":"Start a checkout session and get a token to collect payment","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/payments/checkout-sessions","href":"/api-reference/payments/start-a-checkout-session-and-get-a-token-to-collect-payment"},{"title":"Read the payment status of an order","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/payments/{order_ref}/status","href":"/api-reference/payments/read-the-payment-status-of-an-order"}]},{"group":"Sessions \u0026 authentication","pages":[{"title":"Complete login and start the patient session","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/auth/callback","href":"/api-reference/sessions-\u0026-authentication/complete-login-and-start-the-patient-session"},{"title":"Begin Universal Login and redirect to the login page","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/auth/login","href":"/api-reference/sessions-\u0026-authentication/begin-universal-login-and-redirect-to-the-login-page"},{"title":"Log out and end the patient's session","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/auth/logout","href":"/api-reference/sessions-\u0026-authentication/log-out-and-end-the-patients-session"}]},{"group":"Intake","pages":[{"title":"Record that your patient dropped off the questionnaire","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/instrument/abandon","href":"/api-reference/intake/record-that-your-patient-dropped-off-the-questionnaire"},{"title":"Submit an answer and get the next question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/instrument/next","href":"/api-reference/intake/submit-an-answer-and-get-the-next-question"},{"title":"Start an intake session and get the first question","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/instrument/resolve","href":"/api-reference/intake/start-an-intake-session-and-get-the-first-question"}]},{"group":"Addresses","pages":[{"title":"Resolve a selected address suggestion to a full address","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/instrument/address/retrieve","href":"/api-reference/addresses/resolve-a-selected-address-suggestion-to-a-full-address"},{"title":"Suggest addresses as your patient types","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/instrument/address/suggest","href":"/api-reference/addresses/suggest-addresses-as-your-patient-types"}]},{"group":"Enrollment","pages":[{"title":"Read a patient's public enrollment status","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/journeys/{journey_id}/status","href":"/api-reference/enrollment/read-a-patients-public-enrollment-status"}]},{"group":"Webhooks","pages":[{"title":"List the webhook event types you can subscribe to","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/webhooks/event-types","href":"/api-reference/webhooks/list-the-webhook-event-types-you-can-subscribe-to"},{"title":"List your webhook registrations","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/webhooks/registrations","href":"/api-reference/webhooks/list-your-webhook-registrations"},{"title":"Register a webhook endpoint (signing secret shown once)","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/webhooks/registrations","href":"/api-reference/webhooks/register-a-webhook-endpoint-signing-secret-shown-once"},{"title":"Read one of your webhook registrations","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json get /v1/webhooks/registrations/{registration_id}","href":"/api-reference/webhooks/read-one-of-your-webhook-registrations"},{"title":"Delete a webhook registration","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json delete /v1/webhooks/registrations/{registration_id}","href":"/api-reference/webhooks/delete-a-webhook-registration"},{"title":"Update a registration's URL, events, or enabled flag","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json patch /v1/webhooks/registrations/{registration_id}","href":"/api-reference/webhooks/update-a-registrations-url-events-or-enabled-flag"},{"title":"Send a test event to a registration","deprecated":null,"version":null,"openapi":"/openapi/public-openapi.json post /v1/webhooks/registrations/{registration_id}/test","href":"/api-reference/webhooks/send-a-test-event-to-a-registration"}]}]}]},"basePath":"","title":"Read a client's onboarding progress - Purple Label MD","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-CybtLBIt.js","utils-BMLj2fvV.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-B6In562Y.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-Dr8Mfhp9.js","snippetPresets-2rmQvMVl.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-WMqJYdZj.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CJ-MlPHu.js","shallow-dY3TMRCk.js","getApiPlaygroundDisplay-v-1B2bKm.js","CodeSnippet-BDhiTB7U.js","CodeSnippets-D9hnzQcS.js","Page-C4GwDT3_.js","getPastedJson-Th2V45jI.js","icon-BQXch1W9.js","MethodPill-BCqUneP3.js","DuplicateIcon-Q_-bhurZ.js","createIcon-DUjLHRqp.js","DynamicMarkdown-B-f2cqXQ.js","SectionHeading-Da5NsV4v.js","axios-vUo_bRtp.js","Markdown-D13FWkIM.js","clsx-D3Isdib3.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-C-XZBk9h.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink--qIqmmVG.js"]}