> ## 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.

# List your brand's custom domains

> Returns your brand's custom-domain rows — the custom login domain and/or member-portal domain you have registered — each with its current provisioning state and the CNAME record to add to your DNS. A brand with no custom domains (the shared-domain default) returns an empty list, and a kind you have not registered is simply absent — a shared-domain brand's flow is never gated by any of this. Key-scoped and tenant-isolated: the brand is the one your API key owns and the brand_id in the path must match your X-Brand-Id (any mismatch, foreign, or unknown brand answers 404, never 403 — no cross-tenant existence leak).



## OpenAPI

````yaml /openapi/public-openapi.json get /v1/account/brands/{brand_id}/domains
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}/domains:
    get:
      tags:
        - Brand configuration
      summary: List your brand's custom domains
      description: >-
        Returns your brand's custom-domain rows — the custom login domain and/or
        member-portal domain you have registered — each with its current
        provisioning state and the CNAME record to add to your DNS. A brand with
        no custom domains (the shared-domain default) returns an empty list, and
        a kind you have not registered is simply absent — a shared-domain
        brand's flow is never gated by any of this. Key-scoped and
        tenant-isolated: the brand is the one your API key owns and the brand_id
        in the path must match your X-Brand-Id (any mismatch, foreign, or
        unknown brand answers 404, never 403 — no cross-tenant existence leak).
      operationId: listAccountBrandDomains
      parameters:
        - $ref: '#/components/parameters/BrandIdHeader'
        - $ref: '#/components/parameters/AccountBrandIdPath'
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/AccountDomainList'
                required:
                  - data
                type: object
          description: your brand's custom-domain rows (0, 1, or 2)
        '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
    AccountBrandIdPath:
      description: >-
        the brand whose custom domains to view or manage (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
  schemas:
    AccountDomainList:
      additionalProperties: false
      description: >-
        your brand's custom-domain rows (0, 1, or 2 — one per kind you have
        registered).
      properties:
        domains:
          items:
            $ref: '#/components/schemas/AccountDomainView'
          type: array
      required:
        - domains
      type: object
    AccountDomainView:
      additionalProperties: false
      description: >-
        One custom-domain row as the registry holds it: the brand, the kind
        (login | member), the hostname, its provisioning state, who owns and who
        bound the host, timestamps, and the CNAME paste-row to add to your DNS.
        The row never carries a secret nor the provider's internal domain id. An
        absent row (a kind you have not registered) is the shared-domain
        default.
      properties:
        bound_by:
          description: >-
            which actor bound this host, and on which plane —
            `operator:<subject>` or `client:<client id>`. Derived from the
            authenticated caller at the moment of the binding; it can never be
            supplied in a request body. Absent on a row bound before this field
            was recorded (the binder of those rows is genuinely unknown, and is
            not guessed). The time of the binding is the row's created_at, since
            a live binding is never re-owned in place.
          type: string
        brand_id:
          pattern: ^brd_[A-Za-z0-9][A-Za-z0-9_-]*$
          type: string
        cname:
          allOf:
            - $ref: '#/components/schemas/DomainCnameRecord'
          description: >-
            the CNAME record to add to your DNS (present from cname_rendered
            onward).
        created_at:
          format: date-time
          type: string
        hostname:
          description: your custom hostname (e.g. login.example.com).
          type: string
        kind:
          enum:
            - login
            - member
          type: string
        owner:
          description: >-
            who owns this host binding. `customer` is a domain you brought and
            verified; `platform-brand` is the platform-owned member host every
            brand receives by default; `platform-walk` is a standing platform
            program host. Set on the operator plane only — a brand cannot assign
            its own ownership — and always present on a row.
          enum:
            - platform-walk
            - platform-brand
            - customer
          type: string
        state:
          description: >-
            the provisioning state. login: requested → cname_rendered →
            verifying → verified → cert_issued → active. member: requested →
            cname_rendered → verifying → verified → cert_requested → cert_issued
            → active (the serving tail: verify stops at cert_requested;
            cert_issued and active are operator-advanced — active means the
            hostname serves this brand at the edge).
          enum:
            - requested
            - cname_rendered
            - verifying
            - verified
            - cert_issued
            - active
            - cert_requested
          type: string
        updated_at:
          format: date-time
          type: string
      required:
        - brand_id
        - kind
        - hostname
        - state
        - owner
        - created_at
        - updated_at
      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
    DomainCnameRecord:
      additionalProperties: false
      description: >-
        The CNAME record you add to your DNS to point your custom hostname at
        the platform's edge. A business hostname pair — never a secret. Present
        once the domain has been registered with the provider (state
        cname_rendered onward).
      properties:
        name:
          description: the record NAME to set (your custom hostname).
          type: string
        type:
          const: CNAME
          type: string
        value:
          description: the record VALUE — the edge target the CNAME must point at.
          type: string
      required:
        - type
        - name
        - value
      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

````