How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.
Your integration holds up to four values. Two of them are secrets that the platform shows you
exactly once — this page explains why, and what to do about it.
Value
Looks like
Secret?
Shown
API key
pk_...
Yes
Once, at issue
Brand ID
brd_...
No
Always visible
Webhook signing secret
psig_...
Yes
Once, at registration
Publishable brand key
pub_test_... / pub_live_...
No — browser-safe by design
Once, at issue
pk_ is the secret one. Some payment tools use a pk_ prefix for their browser-safe key. This
platform does not, and issues no sk_ key at all: here pk_ marks the server-side API key, and the
browser-safe credential is the publishable brand key below. A pk_ value in browser code, a public
repository, or a prompt pasted into a code-generation tool is a disclosed secret — rotate it.
Your API key is created by our onboarding team when your account is set up — there is no
self-serve key generation. You receive the key value exactly once, at the moment it is
issued. Store it in your secret manager immediately.The platform does not keep your key. What we store is a one-way fingerprint — enough to
recognize the key when your requests present it, never enough to reconstruct it. That means:
Nobody can read your key back. Not through the API, not from a dashboard, and not by
asking us — the value no longer exists on our side.
A breach of our storage does not leak a usable key. The fingerprint cannot be turned back
into the credential.
A lost key is replaced, not recovered. See rotation below.
Your brand ID (brd_...) travels with the key on every request as the X-Brand-Id header. It
is an identifier, not a secret — it appears in your dashboard views and can always be read back.
If a key is lost, or you suspect it has been exposed, ask your onboarding contact to rotate it.
Rotation issues a new key — shown once, like the first — and revokes every previous key in
the same act. There is no overlap window by default: plan the swap so your servers pick up the
new value promptly. Requests presenting a revoked key receive the same 401 as an unknown key.
Revocation is fast, not instant — budget 30 seconds. The platform caches credential
resolutions for up to 30 seconds, and that window is the upper bound on how long a revoked or
rotated key can still be accepted. A key you have just replaced may keep answering until the window
closes.This matters most in the case you are most likely to be in when you read it: if a key has leaked,
rotating it starts the clock rather than stopping it. Treat the old value as live for 30 seconds
after you rotate, and if the exposure is serious do not rely on rotation alone to end it.
Rotate immediately if a key ever lands anywhere it should not: a repository, a log file, a chat
message, browser code, or a crash report.
The publishable key is the one credential meant to live in a public page bundle. It is issued per
brand — not per client — and it reaches exactly two read-only operations: your brand’s
storefront price read and its readiness read. Every other operation, and every write, is refused.It is shown once at issue, like the API key, and replacing it is the same act: a new key is minted
for the brand and every previous key for that brand is revoked. As with the API key, that takes
effect within one 30-second cache window rather than instantly — a replaced publishable key can
still be accepted until the window closes. It is not a secret, so a leaked
value is not an incident — but it is still brand-scoped capability, so replace it if it ends up
somewhere you did not intend.A publishable key only works from an origin registered on your brand’s browser-origin allowlist.
Authentication covers both halves.
When a webhook endpoint is registered — either during onboarding or by your own call to
POST /v1/webhooks/registrations — the platform generates a signing secret (psig_...) and
returns it once, in the creation response. Every delivery to your endpoint carries a
signature computed with it, so your receiver can verify that events really come from the
platform.The same show-once rule applies: registration reads (GET /v1/webhooks/registrations) confirm a
secret exists but never return its value. To replace a signing secret, delete the registration
and create a new one — you get a fresh secret in that creation response, and signatures made
with the old one stop being produced.
Keep both secrets server-side only: environment variables or a secret manager, never
browser code, mobile apps, or public repositories.
Scope access narrowly — the API key authenticates your whole client account.
Log request outcomes, not credentials. If your framework logs headers, redact
Authorization.
Use your test-scoped credentials everywhere except your production deployment.
{"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/your-credentials","slug":"/pages/integrate/your-credentials","pageMetadata":{"title":"Your credentials","description":"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.","api_refs":["POST /v1/webhooks/registrations","GET /v1/webhooks/registrations"],"href":"/pages/integrate/your-credentials"},"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: \"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.\"\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`,p:`p`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Heading,Table,Warning}=_components;if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Your integration holds up to four values. Two of them are secrets that the platform shows you\nexactly once — this page explains why, and what to do about it.`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Value`}),_jsx(_components.th,{children:`Looks like`}),_jsx(_components.th,{children:`Secret?`}),_jsx(_components.th,{children:`Shown`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`API key`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`pk_...`})}),_jsx(_components.td,{children:_jsx(_components.strong,{children:`Yes`})}),_jsx(_components.td,{children:`Once, at issue`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Brand ID`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`brd_...`})}),_jsx(_components.td,{children:`No`}),_jsx(_components.td,{children:`Always visible`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Webhook signing secret`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`psig_...`})}),_jsx(_components.td,{children:_jsx(_components.strong,{children:`Yes`})}),_jsx(_components.td,{children:`Once, at registration`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Publishable brand key`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`pub_test_...`}),` / `,_jsx(_components.code,{children:`pub_live_...`})]}),_jsx(_components.td,{children:`No — browser-safe by design`}),_jsx(_components.td,{children:`Once, at issue`})]})]})]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`pk_`}),` is the secret one.`]}),` Some payment tools use a `,_jsx(_components.code,{children:`pk_`}),` prefix for their browser-safe key. This\nplatform does not, and issues no `,_jsx(_components.code,{children:`sk_`}),` key at all: here `,_jsx(_components.code,{children:`pk_`}),` marks the server-side API key, and the\nbrowser-safe credential is the publishable brand key below. A `,_jsx(_components.code,{children:`pk_`}),` value in browser code, a public\nrepository, or a prompt pasted into a code-generation tool is a disclosed secret — rotate it.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`how-your-api-key-is-issued`,children:`How your API key is issued`}),`\n`,_jsxs(_components.p,{children:[`Your API key is created by our onboarding team when your account is set up — there is no\nself-serve key generation. You receive the key value `,_jsx(_components.strong,{children:`exactly once`}),`, at the moment it is\nissued. Store it in your secret manager immediately.`]}),`\n`,_jsx(_components.p,{children:`The platform does not keep your key. What we store is a one-way fingerprint — enough to\nrecognize the key when your requests present it, never enough to reconstruct it. That means:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Nobody can read your key back.`}),` Not through the API, not from a dashboard, and not by\nasking us — the value no longer exists on our side.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A breach of our storage does not leak a usable key.`}),` The fingerprint cannot be turned back\ninto the credential.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A lost key is replaced, not recovered.`}),` See rotation below.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Your brand ID (`,_jsx(_components.code,{children:`brd_...`}),`) travels with the key on every request as the `,_jsx(_components.code,{children:`X-Brand-Id`}),` header. It\nis an identifier, not a secret — it appears in your dashboard views and can always be read back.`]}),`\n`,_jsx(Heading,{level:`2`,id:`rotation-the-only-recovery`,children:`Rotation: the only recovery`}),`\n`,_jsxs(_components.p,{children:[`If a key is lost, or you suspect it has been exposed, ask your onboarding contact to rotate it.\nRotation issues a `,_jsx(_components.strong,{children:`new`}),` key — shown once, like the first — and `,_jsx(_components.strong,{children:`revokes every previous key in\nthe same act`}),`. There is no overlap window by default: plan the swap so your servers pick up the\nnew value promptly. Requests presenting a revoked key receive the same `,_jsx(_components.code,{children:`401`}),` as an unknown key.`]}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Revocation is fast, not instant — budget 30 seconds.`}),` The platform caches credential\nresolutions for up to `,_jsx(_components.strong,{children:`30 seconds`}),`, and that window is the upper bound on how long a revoked or\nrotated key can still be accepted. A key you have just replaced may keep answering until the window\ncloses.`]}),_jsx(_components.p,{children:`This matters most in the case you are most likely to be in when you read it: if a key has leaked,\nrotating it starts the clock rather than stopping it. Treat the old value as live for 30 seconds\nafter you rotate, and if the exposure is serious do not rely on rotation alone to end it.`})]}),`\n`,_jsx(_components.p,{children:`Rotate immediately if a key ever lands anywhere it should not: a repository, a log file, a chat\nmessage, browser code, or a crash report.`}),`\n`,_jsx(Heading,{level:`2`,id:`your-publishable-brand-key`,children:`Your publishable brand key`}),`\n`,_jsxs(_components.p,{children:[`The publishable key is the one credential meant to live in a public page bundle. It is issued per\n`,_jsx(_components.strong,{children:`brand`}),` — not per client — and it reaches exactly two read-only operations: your brand’s\nstorefront price read and its readiness read. Every other operation, and every write, is refused.`]}),`\n`,_jsxs(_components.p,{children:[`It is shown once at issue, like the API key, and replacing it is the same act: a new key is minted\nfor the brand and every previous key for that brand is revoked. As with the API key, that takes\neffect `,_jsx(_components.strong,{children:`within one 30-second cache window`}),` rather than instantly — a replaced publishable key can\nstill be accepted until the window closes. It is not a secret, so a leaked\nvalue is not an incident — but it is still brand-scoped capability, so replace it if it ends up\nsomewhere you did not intend.`]}),`\n`,_jsxs(_components.p,{children:[`A publishable key only works from an origin registered on your brand’s browser-origin allowlist.\n`,_jsx(_components.a,{href:`/pages/authentication`,children:`Authentication`}),` covers both halves.`]}),`\n`,_jsx(Heading,{level:`2`,id:`your-webhook-signing-secret`,children:`Your webhook signing secret`}),`\n`,_jsxs(_components.p,{children:[`When a webhook endpoint is registered — either during onboarding or by your own call to\n`,_jsx(_components.code,{children:`POST /v1/webhooks/registrations`}),` — the platform generates a signing secret (`,_jsx(_components.code,{children:`psig_...`}),`) and\nreturns it `,_jsx(_components.strong,{children:`once, in the creation response`}),`. Every delivery to your endpoint carries a\nsignature computed with it, so your receiver can verify that events really come from the\nplatform.`]}),`\n`,_jsxs(_components.p,{children:[`The same show-once rule applies: registration reads (`,_jsx(_components.code,{children:`GET /v1/webhooks/registrations`}),`) confirm a\nsecret exists but never return its value. To replace a signing secret, delete the registration\nand create a new one — you get a fresh secret in that creation response, and signatures made\nwith the old one stop being produced.`]}),`\n`,_jsx(Heading,{level:`2`,id:`handling-rules`,children:`Handling rules`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Keep both secrets `,_jsx(_components.strong,{children:`server-side only`}),`: environment variables or a secret manager, never\nbrowser code, mobile apps, or public repositories.`]}),`\n`,_jsx(_components.li,{children:`Scope access narrowly — the API key authenticates your whole client account.`}),`\n`,_jsxs(_components.li,{children:[`Log request outcomes, not credentials. If your framework logs headers, redact\n`,_jsx(_components.code,{children:`Authorization`}),`.`]}),`\n`,_jsx(_components.li,{children:`Use your test-scoped credentials everywhere except your production deployment.`}),`\n`]})]})}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":"Your credentials","description":"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.","api_refs":["POST /v1/webhooks/registrations","GET /v1/webhooks/registrations"],"href":"/pages/integrate/your-credentials"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"How your API key is issued","slug":"how-your-api-key-is-issued","depth":2,"children":[]},{"title":"Rotation: the only recovery","slug":"rotation-the-only-recovery","depth":2,"children":[]},{"title":"Your publishable brand key","slug":"your-publishable-brand-key","depth":2,"children":[]},{"title":"Your webhook signing secret","slug":"your-webhook-signing-secret","depth":2,"children":[]},{"title":"Handling rules","slug":"handling-rules","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/purplelabelmd/3b4d4a495cd0c48d/brand.js"],"subdomain":"purplelabelmd","siteName":"Purple Label MD","title":"Your credentials - Purple Label MD","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-12T02:36:05.968Z","originalFileLocation":"pages/integrate/your-credentials.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=\"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.\">\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=\"Your credentials - Purple Label MD\">\u003cmeta data-mint-head property=\"og:description\" content=\"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.\">\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/your-credentials\">\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=Your+credentials\u0026amp;description=How+your+API+key+and+webhook+signing+secret+are+issued%2C+why+each+is+shown+only+once%2C+and+how+rotation+works.\u0026amp;theme=1cfc55286f6f85a93657a32a\u0026amp;signature=f4496912cbbc0d2964106121dc1fccb0fab2a2920c8220bb74474d652208f0f7\">\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=\"Your credentials - Purple Label MD\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://purplelabelmd.mintlify.site/_mintlify/api/og/v2?division=Integrate\u0026amp;title=Your+credentials\u0026amp;description=How+your+API+key+and+webhook+signing+secret+are+issued%2C+why+each+is+shown+only+once%2C+and+how+rotation+works.\u0026amp;theme=1cfc55286f6f85a93657a32a\u0026amp;signature=f4496912cbbc0d2964106121dc1fccb0fab2a2920c8220bb74474d652208f0f7\">\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/your-credentials\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/pages/integrate/your-credentials.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/your-credentials#webpage\",\"url\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials\",\"name\":\"Your credentials\",\"description\":\"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.\",\"dateModified\":\"2026-11-12T02:36:05.968Z\",\"isPartOf\":{\"@id\":\"https://docs.purplelabelmd.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Integrate\",\"item\":\"https://docs.purplelabelmd.com/pages/integrate/how-it-works\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Your credentials\",\"item\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials#article\",\"headline\":\"Your credentials\",\"name\":\"Your credentials\",\"description\":\"How your API key and webhook signing secret are issued, why each is shown only once, and how rotation works.\",\"url\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials\",\"mainEntityOfPage\":{\"@id\":\"https://docs.purplelabelmd.com/pages/integrate/your-credentials#webpage\"},\"dateModified\":\"2026-11-12T02:36:05.968Z\",\"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/your-credentials.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","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","description":"The steps from provisioning to live, and how to find out what's waiting on you.","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":"Your credentials - Purple Label MD","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":[],"chunks":[]}