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

# Verify a custom domain and advance provisioning

> Verifies the CNAME you added and advances the domain toward serving: a login domain proceeds through certificate issuance to active; a member-portal domain stops at the certificate-request state — the serving activation itself (certificate attach + host routing, cert_issued → active) is performed by the platform operator once your certificate is issued, never by this call. Call this once you have added the CNAME record from the register step. If verification or the certificate is not ready yet the row stays where it is and a retryable 409 is returned. Idempotent at (or past) the state this call drives to. The brand is the one your key owns (path brand_id must match your X-Brand-Id).



## OpenAPI

````yaml /openapi/public-openapi.json post /v1/account/brands/{brand_id}/domains/{kind}/verify
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/{kind}/verify:
    parameters:
      - $ref: '#/components/parameters/AccountBrandIdPath'
      - $ref: '#/components/parameters/DomainKindPath'
    post:
      tags:
        - Brand configuration
      summary: Verify a custom domain and advance provisioning
      description: >-
        Verifies the CNAME you added and advances the domain toward serving: a
        login domain proceeds through certificate issuance to active; a
        member-portal domain stops at the certificate-request state — the
        serving activation itself (certificate attach + host routing,
        cert_issued → active) is performed by the platform operator once your
        certificate is issued, never by this call. Call this once you have added
        the CNAME record from the register step. If verification or the
        certificate is not ready yet the row stays where it is and a retryable
        409 is returned. Idempotent at (or past) the state this call drives to.
        The brand is the one your key owns (path brand_id must match your
        X-Brand-Id).
      operationId: verifyAccountBrandDomain
      parameters:
        - $ref: '#/components/parameters/BrandIdHeader'
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/AccountDomainView'
                required:
                  - data
                type: object
          description: the advanced row (login → active; member → cert_requested)
        '401':
          $ref: '#/components/responses/EdgeUnauthorized'
        '404':
          $ref: '#/components/responses/EdgeNotFound'
        '409':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: verification or the certificate is not ready yet (retryable)
        '502':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: the domain provider did not complete the request
        '503':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: >-
            the durable domain registry is unavailable (nothing activated;
            retryable)
      security:
        - apiKey: []
components:
  parameters:
    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
    DomainKindPath:
      description: >-
        the custom-domain kind — login (the auth domain) or member (the
        member-portal domain).
      in: path
      name: kind
      required: true
      schema:
        enum:
          - login
          - member
        type: string
    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:
    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:
    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

````