Everything you receive when your integration is provisioned, and the two secrets you hold.
When your integration is provisioned, your onboarding contact hands you a welcome pack. This page
lists exactly what is in it, what comes with it, and the two secrets you hold. The other
integration pages use the same names.
Every endpoint on this site is called on one origin. The pack names it PURPLE_API_BASE:
https://api.<env>.purplelabelmd.com
Use the value your pack states: it is the base of the environment your key was issued for, and
your key works only there. Before go-live that is the test environment, whose hosts are listed on
Environments. The base is an origin only. The /v1 prefix is written into
every path on this site, so a full request URL is always $PURPLE_API_BASE/v1/.... Never add /v1
to the base itself. The API reference is written the same way: its server is the origin, the test
environment’s API base, and every path in it starts with /v1. The production base is a later,
separately-gated hand-off at go-live.Every curl example on this site uses two environment variables: $PURPLE_API_BASE and
$PURPLE_API_KEY.
The brand: its name and its brand id (brd_...). The brand id rides every request in the
X-Brand-Id header. One client can hold several brands, and each call names exactly one.
Site settings: a paste-ready block of environment variables.
Variable
What it holds
PURPLE_BRAND_ID
Your brand id, filled in.
PURPLE_API_BASE
The API origin above, filled in.
PURPLE_API_KEY
Named only. The key value is given to you once, separately (see below).
PURPLE_SUPPORT_EMAIL
Left for you to fill in: the support address your storefront shows.
There is no payment-provider key in the block, and you do not need one. The hosted checkout
runs on the payment provider’s own key (see the checkout door).
Member portal address: the hostname of your brand’s member portal, for example
member.example.com. It is where your patients sign in, check out, see their orders and
complete the identity step. Until the address is set up the pack reads “Not recorded”, and no
checkout can run. Ask your onboarding contact before you build against it.
Sign-in link: the member portal’s own sign-in route on that address.
Link every “Sign in” or “My account” control to this URL. It signs the patient in to the member
portal. Do not use the API’s /v1/auth/login for this (see
Login URLs and domains). If your brand also has an
active custom sign-in domain, the pack shows that host as well.
Offerings: each offering enabled for your brand, as its offering reference
(offering_ref, the readable code such as SEMA-1M) and its offering id (sku_id, shaped
sku_...), in columns headed “Offering reference” and “Offering id”. For example:
Offering reference (offering_ref)
Offering id (sku_id)
SEMA-1M
sku_b7945bba07e4
A checkout-first link also carries the offering’s therapy (for this example, weight_loss).
You do not compose it: the pack issues each offering’s exact checkout link (next item). Where a
call asks for the offering code,
as the price write’s sku field does, send the offering_ref (SEMA-1M), never the sku_id.
See
Identifiers and error types for which call takes
which id.
Entry mode and checkout link: one row per enabled offering, with:
its entry mode, Questions-first or Checkout-first. The mode decides how your storefront
starts a patient (see
which way in);
which setting decided it: “Set for this offering”, “The account’s setting”, or “No mode set,
so the platform default”;
the exact checkout link to build. A checkout-first link carries offering_ref, sku_id
and therapy. A questions-first link carries offering_ref and journey_id only. Your
storefront does not open a questions-first link itself: it hands the patient to the checkout
door with a form POST, and the door sends the patient to this link with their journey_id
filled in. Take the offering_ref for that form from the link. See
handing the patient to checkout.
Where a row shows no link, it says why. Ask your onboarding contact to resolve it before you
build against that offering.Your server can read the same facts, and keep them current as offerings are added, with
GET /v1/account/brands/{brand_id}/offerings: each
offering’s offering_ref, sku_id, therapy, entry mode and checkout link, with its price and
readiness.
Starter merchandising step: the call that adopts the starter product copy for the brand,
POST /v1/account/brands/{brand_id}/starter-merchandising with pack_version3 (see
before a price is payable).
Consent and identity held by the platform: Yes / No: whether the platform holds your patients’
consent and identity records for this brand. The pack reads “Can’t tell yet” when it could not
check. Whether your checkout consent documents are configured is a separate question, answered
by GET /v1/account/brands/{brand_id}/readiness.
Payment stays locked until those documents are configured.
Your display name (display.display_name), with your logo and theme if you want them. It is
always required: patients see it on every platform page.
Who holds your consent documents (consent_holder). There is no default: until it is chosen,
your brand is not ready for patients. See
who holds your consent documents.
Your legal document links, when you hold your consent documents (consent_holderclient): your terms of service, privacy policy and telehealth informed consent
(legal_documents.terms, legal_documents.privacy and legal_documents.telehealth), each an
absolute https URL. Set every one your questionnaires link to. When the platform holds them,
you skip this step: the platform’s own documents apply by default. Until the platform’s legal
pages are published, patients see a “not available” notice in place of those links.
To check what is still missing, read the patient_readiness report beside data on your
configuration readback, or on an intake resolve (GET /v1/instrument/resolve): it lists each missing
item and how to set it. See
is your brand ready for patients?.
Your publishable brand key, if you asked for browser reads. It is optional; see
your credentials.
An onboarding id (onb_...): the reference for your onboarding. Quote it when you ask your
onboarding contact where things stand, or read your progress yourself with your API key. See the
Onboarding timeline.
Two of the values you hold are secrets. Each is shown to you exactly once and then held only by
you. The platform never shows either again.
Your API key (PURPLE_API_KEY) is issued by your onboarding team when your account is set
up. There is no self-serve key generation. You receive it once, at issue: store it in your
secret manager right away. Treat it as server-side only, and never put it in browser code or a
public repository. To replace one, ask your onboarding contact to rotate it.
Your webhook signing secret is the one you create yourself: it is generated when you call
POST /v1/webhooks/registrations and returned exactly once in that response. The platform
holds it after that and never returns it again. Store it the moment you receive it: it is what
you verify delivery signatures with. If you lose it, register a new endpoint to mint a fresh one.
Keeping the secrets on your side is the point: no one, including us, can read your signing secret
back out, so a delivery you accept is a delivery only you could have verified. For how each secret
is issued, why it is shown once, and how rotation works, see
Your credentials.
An offering can be enabled for your brand and still not be ready to sell. Before a patient can pay
for it, four things must be in place. Your storefront can check the result itself: the
storefront read
answers price_status: available with a list_price once the offering’s price and billing terms
are set (items 1 to 3). Item 4 is separate: until your consent documents are configured, the
hosted checkout keeps payment locked even when the price is available.
Product copy. Each offering needs a display name and description for your brand. The
platform’s starter copy fills every offering that has none yet, in one call, the step your
welcome pack shows:
POST /v1/account/brands/{brand_id}/starter-merchandising.
Send the current starter pack version, 3, as pack_version. Adoption only fills offerings
that have no copy yet. An offering that already has copy is skipped and listed as skipped in the
response. A 400 naming a different version means the pack
has moved on: the refusal’s detail states the version the platform serves now. A 404 means
the brand in the path is not one of yours, and nothing was adopted. A 404 with the generic
not-found type means the request did not reach the call at all (see
Reading a 404).
A price. See Pricing. Until a price is set, the storefront read
answers 404 with type commerce/merchandising/not-configured.
Billing terms. How often the price bills and how often the product ships. You choose the
billing cadence for each offering, monthly (a charge every month of the medication’s supply)
or upfront (one charge for the whole term), with
PUT /v1/account/brands/{brand_id}/offerings/{offering_ref}/billing-cadence
and the body {"billing": "monthly"} or {"billing": "upfront"}. Only a cadence that suits the
offering’s supply is accepted. A 422 explains why a cadence was refused and lists the ones you
can choose in compatible_billing. You never set the shipping cadence: it always follows the
offering’s supply, and a body that names one is refused. When only one billing cadence suits an
offering, the platform sets it for you when the offering is enabled and already has its copy,
or when its copy is adopted, whichever comes first, so you need the call only when you have a
choice. Your
readiness report shows a
cadence_compatible check for every offering, and it names this step while a choice is still
yours to make. Until billing terms are set, the storefront read answers price_status: pending
and the hosted checkout does not take payment.
You are ready once you have your API key, your brand id, your member portal address and at least
one offering. From there, the Walkthrough takes you from your
first call to your first received event, and
Connect a Lovable storefront takes you to a first test order.
{"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":"pages/integrate/welcome-kit","slug":"/pages/integrate/welcome-kit","pageMetadata":{"title":"Welcome kit","description":"Everything you receive when your integration is provisioned, and the two secrets you hold.","api_refs":["POST /v1/webhooks/registrations","GET /v1/account/brands/{brand_id}/readiness","GET /v1/account/brands/{brand_id}/config","GET /v1/account/brands/{brand_id}/offerings","PUT /v1/account/brands/{brand_id}/config","GET /v1/instrument/resolve"],"href":"/pages/integrate/welcome-kit"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Everything you receive when your integration is provisioned, and the two secrets you hold.\"\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,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`When your integration is provisioned, your onboarding contact hands you a welcome pack. This page\nlists exactly what is in it, what comes with it, and the two secrets you hold. The other\nintegration pages use the same names.`}),`\n`,_jsx(Heading,{level:`2`,id:`your-api-base-stated-once`,children:`Your API base, stated once`}),`\n`,_jsxs(_components.p,{children:[`Every endpoint on this site is called on one origin. The pack names it `,_jsx(_components.code,{children:`PURPLE_API_BASE`}),`:`]}),`\n`,_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`https://api.\u003cenv>.purplelabelmd.com`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Use the value your pack states: it is the base of the environment your key was issued for, and\nyour key works only there. Before go-live that is the test environment, whose hosts are listed on\n`,_jsx(_components.a,{href:`/pages/environments`,children:`Environments`}),`. The base is an origin only. The `,_jsx(_components.code,{children:`/v1`}),` prefix is written into\nevery path on this site, so a full request URL is always `,_jsx(_components.code,{children:`$PURPLE_API_BASE/v1/...`}),`. Never add `,_jsx(_components.code,{children:`/v1`}),`\nto the base itself. The API reference is written the same way: its server is the origin, the test\nenvironment’s API base, and every path in it starts with `,_jsx(_components.code,{children:`/v1`}),`. The production base is a later,\nseparately-gated hand-off at go-live.`]}),`\n`,_jsxs(_components.p,{children:[`Every curl example on this site uses two environment variables: `,_jsx(_components.code,{children:`$PURPLE_API_BASE`}),` and\n`,_jsx(_components.code,{children:`$PURPLE_API_KEY`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-the-welcome-pack-contains`,children:`What the welcome pack contains`}),`\n`,_jsx(_components.p,{children:`For each of your brands, the pack shows:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The brand`}),`: its name and its brand id (`,_jsx(_components.code,{children:`brd_...`}),`). The brand id rides every request in the\n`,_jsx(_components.code,{children:`X-Brand-Id`}),` header. One client can hold several brands, and each call names exactly one.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Site settings`}),`: a paste-ready block of environment variables.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Variable`}),_jsx(_components.th,{children:`What it holds`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`PURPLE_BRAND_ID`})}),_jsx(_components.td,{children:`Your brand id, filled in.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`PURPLE_API_BASE`})}),_jsx(_components.td,{children:`The API origin above, filled in.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`PURPLE_API_KEY`})}),_jsx(_components.td,{children:`Named only. The key value is given to you once, separately (see below).`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`PURPLE_SUPPORT_EMAIL`})}),_jsx(_components.td,{children:`Left for you to fill in: the support address your storefront shows.`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`There is no payment-provider key in the block, and you do not need one. The hosted checkout\nruns on the payment provider’s own key (see `,_jsx(_components.a,{href:`/pages/integrate/the-checkout-door`,children:`the checkout door`}),`).`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Member portal address`}),`: the hostname of your brand’s member portal, for example\n`,_jsx(_components.code,{children:`member.example.com`}),`. It is where your patients sign in, check out, see their orders and\ncomplete the identity step. Until the address is set up the pack reads “Not recorded”, and no\ncheckout can run. Ask your onboarding contact before you build against it.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Sign-in link`}),`: the member portal’s own sign-in route on that address.`]}),`\n`,_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`https://\u003cmember portal address>/auth/login?returnTo=/home`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Link every “Sign in” or “My account” control to this URL. It signs the patient in to the member\nportal. Do not use the API’s `,_jsx(_components.code,{children:`/v1/auth/login`}),` for this (see\n`,_jsx(_components.a,{href:`/pages/integrate/login-urls-and-domains`,children:`Login URLs and domains`}),`). If your brand also has an\nactive custom sign-in domain, the pack shows that host as well.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Offerings`}),`: each offering enabled for your brand, as its `,_jsx(_components.strong,{children:`offering reference`}),`\n(`,_jsx(_components.code,{children:`offering_ref`}),`, the readable code such as `,_jsx(_components.code,{children:`SEMA-1M`}),`) and its `,_jsx(_components.strong,{children:`offering id`}),` (`,_jsx(_components.code,{children:`sku_id`}),`, shaped\n`,_jsx(_components.code,{children:`sku_...`}),`), in columns headed “Offering reference” and “Offering id”. For example:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsxs(_components.th,{children:[`Offering reference (`,_jsx(_components.code,{children:`offering_ref`}),`)`]}),_jsxs(_components.th,{children:[`Offering id (`,_jsx(_components.code,{children:`sku_id`}),`)`]})]})}),_jsx(_components.tbody,{children:_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`SEMA-1M`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`sku_b7945bba07e4`})})]})})]}),`\n`,_jsxs(_components.p,{children:[`A checkout-first link also carries the offering’s therapy (for this example, `,_jsx(_components.code,{children:`weight_loss`}),`).\nYou do not compose it: the pack issues each offering’s exact checkout link (next item). Where a\ncall asks for the offering code,\nas the price write’s `,_jsx(_components.code,{children:`sku`}),` field does, send the `,_jsx(_components.code,{children:`offering_ref`}),` (`,_jsx(_components.code,{children:`SEMA-1M`}),`), never the `,_jsx(_components.code,{children:`sku_id`}),`.\nSee\n`,_jsx(_components.a,{href:`/pages/integrate/identifiers-and-error-types`,children:`Identifiers and error types`}),` for which call takes\nwhich id.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Entry mode and checkout link`}),`: one row per enabled offering, with:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`its `,_jsx(_components.strong,{children:`entry mode`}),`, Questions-first or Checkout-first. The mode decides how your storefront\nstarts a patient (see\n`,_jsx(_components.a,{href:`/pages/integrate/lovable-storefront#which-way-in-your-entry-mode`,children:`which way in`}),`);`]}),`\n`,_jsx(_components.li,{children:`which setting decided it: “Set for this offering”, “The account’s setting”, or “No mode set,\nso the platform default”;`}),`\n`,_jsxs(_components.li,{children:[`the exact `,_jsx(_components.strong,{children:`checkout link`}),` to build. A checkout-first link carries `,_jsx(_components.code,{children:`offering_ref`}),`, `,_jsx(_components.code,{children:`sku_id`}),`\nand `,_jsx(_components.code,{children:`therapy`}),`. A questions-first link carries `,_jsx(_components.code,{children:`offering_ref`}),` and `,_jsx(_components.code,{children:`journey_id`}),` only. Your\nstorefront does not open a questions-first link itself: it hands the patient to the checkout\ndoor with a form POST, and the door sends the patient to this link with their `,_jsx(_components.code,{children:`journey_id`}),`\nfilled in. Take the `,_jsx(_components.code,{children:`offering_ref`}),` for that form from the link. See\n`,_jsx(_components.a,{href:`/pages/integrate/lovable-storefront#handing-the-patient-to-checkout`,children:`handing the patient to checkout`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Where a row shows no link, it says why. Ask your onboarding contact to resolve it before you\nbuild against that offering.`}),`\n`,_jsxs(_components.p,{children:[`Your server can read the same facts, and keep them current as offerings are added, with\n`,_jsx(_components.a,{href:`/pages/integrate/your-offerings`,children:_jsx(_components.code,{children:`GET /v1/account/brands/{brand_id}/offerings`})}),`: each\noffering’s `,_jsx(_components.code,{children:`offering_ref`}),`, `,_jsx(_components.code,{children:`sku_id`}),`, therapy, entry mode and checkout link, with its price and\nreadiness.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Starter merchandising step`}),`: the call that adopts the starter product copy for the brand,\n`,_jsx(_components.code,{children:`POST /v1/account/brands/{brand_id}/starter-merchandising`}),` with `,_jsx(_components.code,{children:`pack_version`}),` `,_jsx(_components.code,{children:`3`}),` (see\n`,_jsx(_components.a,{href:`#before-a-price-is-payable`,children:`before a price is payable`}),`).`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Consent and identity held by the platform: Yes / No`}),`: whether the platform holds your patients’\nconsent and identity records for this brand. The pack reads “Can’t tell yet” when it could not\ncheck. Whether your checkout consent documents are configured is a separate question, answered\nby `,_jsx(_components.a,{href:`/api-reference/onboarding/check-whether-your-brand-is-ready-to-sell`,children:_jsx(_components.code,{children:`GET /v1/account/brands/{brand_id}/readiness`})}),`.\nPayment stays locked until those documents are configured.`]}),`\n`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`your-own-steps-before-patients-arrive`,children:`Your own steps before patients arrive`}),`\n`,_jsxs(_components.p,{children:[`Three settings are yours to make with your own key, in one call,\n`,_jsx(_components.a,{href:`/pages/integrate/brand-configuration`,children:_jsx(_components.code,{children:`PUT /v1/account/brands/{brand_id}/config`})}),`:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your display name`}),` (`,_jsx(_components.code,{children:`display.display_name`}),`), with your logo and theme if you want them. It is\nalways required: patients see it on every platform page.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Who holds your consent documents`}),` (`,_jsx(_components.code,{children:`consent_holder`}),`). There is no default: until it is chosen,\nyour brand is not ready for patients. See\n`,_jsx(_components.a,{href:`/pages/integrate/brand-configuration#who-holds-your-consent-documents`,children:`who holds your consent documents`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your legal document links`}),`, when you hold your consent documents (`,_jsx(_components.code,{children:`consent_holder`}),`\n`,_jsx(_components.code,{children:`client`}),`): your terms of service, privacy policy and telehealth informed consent\n(`,_jsx(_components.code,{children:`legal_documents.terms`}),`, `,_jsx(_components.code,{children:`legal_documents.privacy`}),` and `,_jsx(_components.code,{children:`legal_documents.telehealth`}),`), each an\nabsolute `,_jsx(_components.code,{children:`https`}),` URL. Set every one your questionnaires link to. When the platform holds them,\nyou skip this step: the platform’s own documents apply by default. Until the platform’s legal\npages are published, patients see a “not available” notice in place of those links.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`To check what is still missing, read the `,_jsx(_components.code,{children:`patient_readiness`}),` report beside `,_jsx(_components.code,{children:`data`}),` on your\nconfiguration readback, or on an intake resolve (`,_jsx(_components.code,{children:`GET /v1/instrument/resolve`}),`): it lists each missing\nitem and how to set it. See\n`,_jsx(_components.a,{href:`/pages/integrate/brand-configuration#is-your-brand-ready-for-patients`,children:`is your brand ready for patients?`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-comes-with-the-pack`,children:`What comes with the pack`}),`\n`,_jsx(_components.p,{children:`Your onboarding contact also gives you:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your API key value`}),`, once (see below).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your publishable brand key`}),`, if you asked for browser reads. It is optional; see\n`,_jsx(_components.a,{href:`/pages/integrate/your-credentials`,children:`your credentials`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`An onboarding id`}),` (`,_jsx(_components.code,{children:`onb_...`}),`): the reference for your onboarding. Quote it when you ask your\nonboarding contact where things stand, or read your progress yourself with your API key. See the\n`,_jsx(_components.a,{href:`/pages/integrate/onboarding-timeline`,children:`Onboarding timeline`}),`.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`You can read your brand configuration back yourself at any time with\n`,_jsx(_components.a,{href:`/pages/integrate/brand-configuration`,children:_jsx(_components.code,{children:`GET /v1/account/brands/{brand_id}/config`})}),`. Your offerings\nare not part of that configuration: list them with\n`,_jsx(_components.a,{href:`/pages/integrate/your-offerings`,children:_jsx(_components.code,{children:`GET /v1/account/brands/{brand_id}/offerings`})}),`.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Use only invented test patients whose names include the uppercase word `,_jsx(_components.code,{children:`TEST`}),`; test mode never charges a real card.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`the-two-secrets-you-hold`,children:`The two secrets you hold`}),`\n`,_jsxs(_components.p,{children:[`Two of the values you hold are secrets. Each is shown to you `,_jsx(_components.strong,{children:`exactly once`}),` and then held only by\nyou. The platform never shows either again.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your API key`}),` (`,_jsx(_components.code,{children:`PURPLE_API_KEY`}),`) is issued by your onboarding team when your account is set\nup. There is no self-serve key generation. You receive it once, at issue: store it in your\nsecret manager right away. Treat it as server-side only, and never put it in browser code or a\npublic repository. To replace one, ask your onboarding contact to rotate it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your webhook signing secret`}),` is the one you create yourself: it is generated when you call\n`,_jsx(_components.code,{children:`POST /v1/webhooks/registrations`}),` and returned `,_jsx(_components.strong,{children:`exactly once`}),` in that response. The platform\nholds it after that and never returns it again. Store it the moment you receive it: it is what\nyou verify delivery signatures with. If you lose it, register a new endpoint to mint a fresh one.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Keeping the secrets on your side is the point: no one, including us, can read your signing secret\nback out, so a delivery you accept is a delivery only you could have verified. For how each secret\nis issued, why it is shown once, and how rotation works, see\n`,_jsx(_components.a,{href:`/pages/integrate/your-credentials`,children:`Your credentials`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`before-a-price-is-payable`,children:`Before a price is payable`}),`\n`,_jsxs(_components.p,{children:[`An offering can be enabled for your brand and still not be ready to sell. Before a patient can pay\nfor it, four things must be in place. Your storefront can check the result itself: the\n`,_jsx(_components.a,{href:`/api-reference/onboarding/read-one-offerings-price-and-whether-your-brand-can-sell-it`,children:`storefront read`}),`\nanswers `,_jsx(_components.code,{children:`price_status: available`}),` with a `,_jsx(_components.code,{children:`list_price`}),` once the offering’s price and billing terms\nare set (items 1 to 3). Item 4 is separate: until your consent documents are configured, the\nhosted checkout keeps payment locked even when the price is available.`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Product copy.`}),` Each offering needs a display name and description for your brand. The\nplatform’s starter copy fills every offering that has none yet, in one call, the step your\nwelcome pack shows:\n`,_jsx(_components.a,{href:`/api-reference/offering-configuration/adopt-the-starter-merchandising-pack-for-your-brand`,children:_jsx(_components.code,{children:`POST /v1/account/brands/{brand_id}/starter-merchandising`})}),`.\nSend the current starter pack version, `,_jsx(_components.strong,{children:_jsx(_components.code,{children:`3`})}),`, as `,_jsx(_components.code,{children:`pack_version`}),`. Adoption only fills offerings\nthat have no copy yet. An offering that already has copy is skipped and listed as skipped in the\nresponse. A `,_jsx(_components.code,{children:`400`}),` naming a different version means the pack\nhas moved on: the refusal’s `,_jsx(_components.code,{children:`detail`}),` states the version the platform serves now. A `,_jsx(_components.code,{children:`404`}),` means\nthe brand in the path is not one of yours, and nothing was adopted. A `,_jsx(_components.code,{children:`404`}),` with the generic\nnot-found type means the request did not reach the call at all (see\n`,_jsx(_components.a,{href:`/pages/integrate/identifiers-and-error-types#reading-a-404`,children:`Reading a 404`}),`).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A price.`}),` See `,_jsx(_components.a,{href:`/pages/integrate/pricing`,children:`Pricing`}),`. Until a price is set, the storefront read\nanswers `,_jsx(_components.code,{children:`404`}),` with type `,_jsx(_components.code,{children:`commerce/merchandising/not-configured`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Billing terms.`}),` How often the price bills and how often the product ships. You choose the\nbilling cadence for each offering, `,_jsx(_components.code,{children:`monthly`}),` (a charge every month of the medication’s supply)\nor `,_jsx(_components.code,{children:`upfront`}),` (one charge for the whole term), with\n`,_jsx(_components.a,{href:`/api-reference/offering-configuration/choose-the-billing-cadence-of-an-offering-on-your-brand`,children:_jsx(_components.code,{children:`PUT /v1/account/brands/{brand_id}/offerings/{offering_ref}/billing-cadence`})}),`\nand the body `,_jsx(_components.code,{children:`{\"billing\": \"monthly\"}`}),` or `,_jsx(_components.code,{children:`{\"billing\": \"upfront\"}`}),`. Only a cadence that suits the\noffering’s supply is accepted. A `,_jsx(_components.code,{children:`422`}),` explains why a cadence was refused and lists the ones you\ncan choose in `,_jsx(_components.code,{children:`compatible_billing`}),`. You never set the shipping cadence: it always follows the\noffering’s supply, and a body that names one is refused. When only one billing cadence suits an\noffering, the platform sets it for you when the offering is enabled and already has its copy,\nor when its copy is adopted, whichever comes first, so you need the call only when you have a\nchoice. Your\n`,_jsx(_components.a,{href:`/api-reference/onboarding/check-whether-your-brand-is-ready-to-sell`,children:`readiness report`}),` shows a\n`,_jsx(_components.code,{children:`cadence_compatible`}),` check for every offering, and it names this step while a choice is still\nyours to make. Until billing terms are set, the storefront read answers `,_jsx(_components.code,{children:`price_status: pending`}),`\nand the hosted checkout does not take payment.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your checkout consent documents.`}),` Payment stays locked until they are configured.\n`,_jsx(_components.a,{href:`/api-reference/onboarding/check-whether-your-brand-is-ready-to-sell`,children:_jsx(_components.code,{children:`GET /v1/account/brands/{brand_id}/readiness`})}),`\nreports whether they are.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`before-you-make-your-first-call`,children:`Before you make your first call`}),`\n`,_jsxs(_components.p,{children:[`You are ready once you have your API key, your brand id, your member portal address and at least\none offering. From there, the `,_jsx(_components.a,{href:`/pages/integrate/walkthrough`,children:`Walkthrough`}),` takes you from your\nfirst call to your first received event, and\n`,_jsx(_components.a,{href:`/pages/integrate/lovable-storefront`,children:`Connect a Lovable storefront`}),` takes you to a first test order.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Welcome kit","description":"Everything you receive when your integration is provisioned, and the two secrets you hold.","api_refs":["POST /v1/webhooks/registrations","GET /v1/account/brands/{brand_id}/readiness","GET /v1/account/brands/{brand_id}/config","GET /v1/account/brands/{brand_id}/offerings","PUT /v1/account/brands/{brand_id}/config","GET /v1/instrument/resolve"],"href":"/pages/integrate/welcome-kit"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Your API base, stated once","slug":"your-api-base-stated-once","depth":2,"children":[]},{"title":"What the welcome pack contains","slug":"what-the-welcome-pack-contains","depth":2,"children":[]},{"title":"Your own steps before patients arrive","slug":"your-own-steps-before-patients-arrive","depth":2,"children":[]},{"title":"What comes with the pack","slug":"what-comes-with-the-pack","depth":2,"children":[]},{"title":"The two secrets you hold","slug":"the-two-secrets-you-hold","depth":2,"children":[]},{"title":"Before a price is payable","slug":"before-a-price-is-payable","depth":2,"children":[]},{"title":"Before you make your first call","slug":"before-you-make-your-first-call","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/purplelabelmd/3b4d4a495cd0c48d/brand.js"],"subdomain":"purplelabelmd","siteName":"Purple Label MD","title":"Welcome kit - Purple Label MD","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-12T04:48:54.897Z","originalFileLocation":"pages/integrate/welcome-kit.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=\"Everything you receive when your integration is provisioned, and the two secrets you hold.\">\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=\"Welcome kit - Purple Label MD\">\u003cmeta data-mint-head property=\"og:description\" content=\"Everything you receive when your integration is provisioned, and the two secrets you hold.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Purple Label MD\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit\">\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=Integrate\u0026amp;title=Welcome+kit\u0026amp;description=Everything+you+receive+when+your+integration+is+provisioned%2C+and+the+two+secrets+you+hold.\u0026amp;theme=1cfc55286f6f85a93657a32a\u0026amp;signature=206acd6f28e3a4b63bb9c45566f4d500dab540b3f6241118a7958589dffc79a7\">\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=\"Welcome kit - Purple Label MD\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Everything you receive when your integration is provisioned, and the two secrets you hold.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://purplelabelmd.mintlify.site/_mintlify/api/og/v2?division=Integrate\u0026amp;title=Welcome+kit\u0026amp;description=Everything+you+receive+when+your+integration+is+provisioned%2C+and+the+two+secrets+you+hold.\u0026amp;theme=1cfc55286f6f85a93657a32a\u0026amp;signature=206acd6f28e3a4b63bb9c45566f4d500dab540b3f6241118a7958589dffc79a7\">\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/pages/integrate/welcome-kit\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/pages/integrate/welcome-kit.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/pages/integrate/welcome-kit#webpage\",\"url\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit\",\"name\":\"Welcome kit\",\"description\":\"Everything you receive when your integration is provisioned, and the two secrets you hold.\",\"dateModified\":\"2026-11-12T04:48:54.897Z\",\"isPartOf\":{\"@id\":\"https://docs.purplelabelmd.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Integrate\",\"item\":\"https://docs.purplelabelmd.com/pages/integrate/how-it-works\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Welcome kit\",\"item\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit#article\",\"headline\":\"Welcome kit\",\"name\":\"Welcome kit\",\"description\":\"Everything you receive when your integration is provisioned, and the two secrets you hold.\",\"url\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit\",\"mainEntityOfPage\":{\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/welcome-kit#webpage\"},\"dateModified\":\"2026-11-12T04:48:54.897Z\",\"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":"/pages/integrate/welcome-kit.md","siteName":"Purple Label MD","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Overview","href":"/pages/overview"},{"title":"CHANGELOG","href":"/pages/api-changes"},{"title":"Quickstart","href":"/pages/quickstart"},{"title":"Authentication","href":"/pages/authentication"},{"title":"Environments","href":"/pages/environments"},{"group":"Integrate","pages":[{"title":"How it works","href":"/pages/integrate/how-it-works"},{"title":"Walkthrough","href":"/pages/integrate/walkthrough"},{"title":"The patient flow","href":"/pages/integrate/the-patient-flow"},{"title":"How intake serving works","href":"/pages/integrate/how-serving-works"},{"title":"How questions work","href":"/pages/integrate/how-questions-work"},{"title":"The checkout door","href":"/pages/integrate/the-checkout-door"},{"title":"Pricing","href":"/pages/integrate/pricing"},{"title":"Identifiers and error types","href":"/pages/integrate/identifiers-and-error-types"},{"title":"The identity handoff","href":"/pages/integrate/the-identity-handoff"},{"title":"Brand configuration","href":"/pages/integrate/brand-configuration"},{"title":"List your offerings","href":"/pages/integrate/your-offerings"},{"title":"Login URLs and domains","description":"How to build your patients' sign-in link, what the member portal origin is for, and how to put both on your own custom domains.","href":"/pages/integrate/login-urls-and-domains"},{"title":"Welcome kit","href":"/pages/integrate/welcome-kit"},{"title":"Connect a Lovable storefront","description":"Wire a Lovable-generated storefront to the platform: which credential goes where, both ways into the flow, how to confirm a test order, and a reusable prompt.","href":"/pages/integrate/lovable-storefront"},{"title":"Your credentials","href":"/pages/integrate/your-credentials"},{"title":"Onboarding timeline","href":"/pages/integrate/onboarding-timeline"}]}]},{"tab":"API reference","pages":[{"title":"API reference","href":"/api-reference/brand-configuration/read-back-your-brands-platform-configuration"}]}]},"basePath":"","title":"Welcome kit - Purple Label MD","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":[],"chunks":[]}