> ## Documentation Index
> Fetch the complete documentation index at: https://docs.purplelabelmd.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Read back your brand's platform configuration

> Returns a copy of the brand configuration as the platform holds it — your theme, your offerings, and your redirect allowlist — for the brand you pass. This is the client-facing readback promised in the welcome kit. Key-scoped and tenant-isolated: you may read only a brand your API key owns; the brand_id in the path must match the X-Brand-Id you present (any mismatch, foreign, or unknown brand answers 404, never 403 — no cross-tenant existence leak). A brand with no configuration set yet answers 404.



## OpenAPI

````yaml /openapi/public-openapi.json get /v1/account/brands/{brand_id}/config
openapi: 3.1.0
info:
  title: Purple API
  version: 0.0.0
servers:
  - url: https://api.dev.purplelabelmd.com
security: []
tags:
  - description: Sign a patient in and out and manage the browser session.
    name: Sessions & authentication
  - description: Run the server-driven intake questionnaire question by question.
    name: Intake
  - description: Address autocomplete for the intake flow.
    name: Addresses
  - description: Read the public status of a patient's enrollment.
    name: Enrollment
  - description: Track a client's onboarding progress.
    name: Onboarding
  - description: Read back the platform configuration stored for your brand.
    name: Brand configuration
  - description: Enable offerings for your brand and set their display copy.
    name: Offering configuration
  - description: Start and track payments for an order.
    name: Payments
  - description: Subscribe to platform events and manage delivery endpoints.
    name: Webhooks
paths:
  /v1/account/brands/{brand_id}/config:
    get:
      tags:
        - Brand configuration
      summary: Read back your brand's platform configuration
      description: >-
        Returns a copy of the brand configuration as the platform holds it —
        your theme, your offerings, and your redirect allowlist — for the brand
        you pass. This is the client-facing readback promised in the welcome
        kit. Key-scoped and tenant-isolated: you may read only a brand your API
        key owns; the brand_id in the path must match the X-Brand-Id you present
        (any mismatch, foreign, or unknown brand answers 404, never 403 — no
        cross-tenant existence leak). A brand with no configuration set yet
        answers 404.
      operationId: getAccountBrandConfig
      parameters:
        - $ref: '#/components/parameters/BrandIdHeader'
        - description: the brand whose configuration to read (must match X-Brand-Id).
          in: path
          name: brand_id
          required: true
          schema:
            pattern: ^brd_[A-Za-z0-9][A-Za-z0-9_-]*$
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/BrandConfigView'
                required:
                  - data
                type: object
          description: the brand's configuration (clinically inert by construction)
        '400':
          $ref: '#/components/responses/EdgeBadRequest'
        '401':
          $ref: '#/components/responses/EdgeUnauthorized'
        '404':
          $ref: '#/components/responses/EdgeNotFound'
      security:
        - apiKey: []
components:
  parameters:
    BrandIdHeader:
      description: >-
        Opaque brand id (brd_...). Validated to belong to the resolved client
        (§2).
      in: header
      name: X-Brand-Id
      required: true
      schema:
        pattern: ^brd_[A-Za-z0-9][A-Za-z0-9_-]*$
        type: string
  schemas:
    BrandConfigView:
      additionalProperties: false
      description: >-
        A brand's platform configuration as the platform holds it — clinically
        inert BY CONSTRUCTION (the validator enforces a top-level allowlist + a
        recursive clinical-shaped-key denylist). The client readback and the
        operator view return this EXACT shape (one projection, no drift).
        Presentation and commercial reach only; never a clinical field.
        additionalProperties:false mirrors the validator's top-level allowlist.
      properties:
        brand_id:
          pattern: ^brd_[A-Za-z0-9][A-Za-z0-9_-]*$
          type: string
        commercial:
          additionalProperties:
            type: string
          description: commercial references (storefront/pricing ids) — references only.
          type: object
        copy:
          additionalProperties:
            type: string
          description: brand-overridable copy slots (slot id → display string).
          type: object
        display:
          allOf:
            - $ref: '#/components/schemas/BrandDisplay'
          description: >-
            The per-brand display-identity block (name, logo, token-set), if
            set. Identity only; never a clinical copy channel. When absent, this
            brand has no display identity and the brand-display serve returns
            the explicit purple fallback.
        enabled_therapies:
          description: >-
            therapy references this brand offers (references, never
            definitions). This is also the field the intake surface reads to
            decide which questionnaire a patient is served at a journeyless
            first touch: one enabled therapy serves that therapy's questionnaire
            always; more than one requires the entry link to name an `offering`;
            none serves the platform's shared questionnaire. Values must be
            therapy keys the clinical service currently serves; the vocabulary
            is not enumerated here — it is clinical's committed roster (`GET
            /v1/instrument-bundles/roster`), which grows as new shared intakes
            ship.
          items:
            type: string
          type: array
        redirect_allowlist:
          description: >-
            absolute-https return-URL prefixes permitted as post-completion
            redirect targets.
          items:
            format: uri
            type: string
          type: array
        theme:
          additionalProperties:
            oneOf:
              - type: string
              - type: number
          description: presentation theme tokens — scalar leaves only (string or number).
          type: object
        updated_at:
          description: when this configuration was last written.
          format: date-time
          type: string
        version:
          description: server-minted monotone version (e.g. v3); the caller never sets it.
          type: string
      required:
        - brand_id
        - version
      type: object
    BrandDisplay:
      additionalProperties: false
      description: >-
        The per-brand display-identity block: the brand's display name, logo
        references, and token-set that the platform-controlled surfaces (portal,
        checkout door, identity) resolve per request. Identity only — never a
        clinical copy channel: a `copy` key here is refused, and the
        brand-config clinical-shaped-key denylist scans it like everything else.
        It is a sibling of `theme`, not a replacement: `theme` is the
        render-time instrument overlay, while these tokens are the brand-chrome
        identity the platform surfaces render — disjoint consumers, no
        precedence.
      properties:
        display_name:
          description: >-
            the brand's display name shown to patients (document titles, login
            shell).
          minLength: 1
          type: string
        logo:
          additionalProperties: false
          description: >-
            logo references per mode — each an absolute https URL or a
            root-relative path ('/…').
          properties:
            dark:
              description: >-
                dark-mode logo reference (absolute https URL or root-relative
                path).
              type: string
            light:
              description: >-
                light-mode logo reference (absolute https URL or root-relative
                path).
              type: string
          type: object
        support_email:
          description: optional brand support email.
          format: email
          type: string
        tokens:
          allOf:
            - $ref: '#/components/schemas/BrandDisplayTokens'
      required:
        - display_name
      type: object
    EdgeProblem:
      description: RFC 7807 problem+json error body.
      properties:
        detail:
          type: string
        status:
          type: integer
        title:
          type: string
        type:
          format: uri-reference
          type: string
      required:
        - type
        - title
        - status
      type: object
    BrandDisplayTokens:
      additionalProperties: false
      description: >-
        The brand token-set family (colors per mode, base radius, and type
        families), mirroring the design-system brand-token shape minus name and
        logo (which are hoisted to display_name and logo). A partial override
        set: a brand supplies any subset of the known slots; completeness for
        stylesheet generation is achieved downstream by merging onto the default
        brand fallback. String leaves only; unknown token slots are refused.
      properties:
        colors:
          additionalProperties: false
          description: >-
            semantic color slots per mode — BrandColorSet keys → CSS color
            strings.
          properties:
            dark:
              additionalProperties:
                type: string
              description: dark-mode color slots (BrandColorSet keys → CSS color strings).
              type: object
            light:
              additionalProperties:
                type: string
              description: light-mode color slots (BrandColorSet keys → CSS color strings).
              type: object
          type: object
        radius:
          description: base corner radius, e.g. '0.625rem'.
          type: string
        typography:
          additionalProperties: false
          properties:
            fontMono:
              type: string
            fontSans:
              type: string
          type: object
      type: object
  responses:
    EdgeBadRequest:
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/EdgeProblem'
      description: malformed or absent X-Brand-Id
    EdgeUnauthorized:
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/EdgeProblem'
      description: >-
        missing, unknown, or revoked API key - one opaque body (no
        enumeration/timing oracle, §1)
    EdgeNotFound:
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/EdgeProblem'
      description: >-
        brand not found for this tenant - identical for unknown and foreign
        brands (404, never 403; no cross-tenant existence leak, §2)
  securitySchemes:
    apiKey:
      description: 'Per-client API key (M2M). Presented as `Authorization: Bearer <key>`.'
      scheme: bearer
      type: http

````