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

# Enable an offering for your brand

> Enables an offering for YOUR brand using your own API key — records the intent "enable offering Y for my brand" and answers with the enablement and its computed activation report. The brand is the one your key owns (resolved from X-Brand-Id); the brand_id in the path must match it (any mismatch, foreign, or unknown brand answers 404, never 403 — no cross-tenant existence leak). The offering_ref must already exist in the canonical catalog: an unknown offering is 404, never auto-created (nothing invented, nothing derived from the SKU code). Idempotency-Key is carried through — replay of the same request returns the original result. This is enablement configuration, NOT a price path (no money moves; pricing self-serve is a separate surface).



## OpenAPI

````yaml /openapi/public-openapi.json post /v1/account/brands/{brand_id}/offerings
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}/offerings:
    post:
      tags:
        - Offering configuration
      summary: Enable an offering for your brand
      description: >-
        Enables an offering for YOUR brand using your own API key — records the
        intent "enable offering Y for my brand" and answers with the enablement
        and its computed activation report. The brand is the one your key owns
        (resolved from X-Brand-Id); the brand_id in the path must match it (any
        mismatch, foreign, or unknown brand answers 404, never 403 — no
        cross-tenant existence leak). The offering_ref must already exist in the
        canonical catalog: an unknown offering is 404, never auto-created
        (nothing invented, nothing derived from the SKU code). Idempotency-Key
        is carried through — replay of the same request returns the original
        result. This is enablement configuration, NOT a price path (no money
        moves; pricing self-serve is a separate surface).
      operationId: enableAccountOffering
      parameters:
        - $ref: '#/components/parameters/BrandIdHeader'
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
        - description: the brand to enable the offering for (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
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountOfferingEnableRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/AccountOfferingEnablementView'
                required:
                  - data
                type: object
          description: the offering was already enabled — an idempotent re-enable or replay
        '201':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/AccountOfferingEnablementView'
                required:
                  - data
                type: object
          description: >-
            enablement intent recorded; the body carries the computed activation
            report
        '400':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: >-
            a malformed body (missing/empty offering_ref) or a missing
            Idempotency-Key
        '401':
          $ref: '#/components/responses/EdgeUnauthorized'
        '404':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: >-
            unknown or foreign brand (identical for both — 404, never 403; no
            cross-tenant existence leak), or the offering_ref is absent from the
            canonical catalog (never auto-created)
        '409':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: >-
            Idempotency-Key reused with a materially different request (code
            IDEMPOTENCY_CONFLICT)
        '502':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/EdgeProblem'
          description: >-
            the catalog service is temporarily unavailable (nothing enabled;
            retryable)
      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
    IdempotencyKeyHeader:
      description: >-
        Accepted on mutations; carried in trusted context, enforced in a later
        WI.
      in: header
      name: Idempotency-Key
      required: false
      schema:
        type: string
  schemas:
    AccountOfferingEnableRequest:
      description: >-
        The enable request body — the offering to enable for your brand. The
        brand is resolved from your key (the path brand_id must match
        X-Brand-Id) and is never carried here.
      properties:
        offering_ref:
          description: >-
            the offering code to enable (offering_ref = the catalog offering/SKU
            code); must exist in the canonical catalog.
          minLength: 1
          type: string
      required:
        - offering_ref
      type: object
    AccountOfferingEnablementView:
      description: >-
        An enablement record with its computed activation status. The status is
        derived from the activation checks on every response — never stored and
        never writable; "active" cannot appear while any performed check fails,
        a check is unverifiable, or a check was not performed.
      properties:
        brand_id:
          type: string
        checks:
          items:
            $ref: '#/components/schemas/OfferingActivationCheckRow'
          type: array
        client_id:
          description: the brand's parent client/tenant.
          type: string
        enabled_at:
          format: date-time
          type: string
        id:
          description: opaque prefixed id (enb_…)
          type: string
        offering_ref:
          type: string
        sku_id:
          type: string
        status:
          enum:
            - enabled_pending_activation
            - active
          type: string
      required:
        - id
        - brand_id
        - client_id
        - sku_id
        - offering_ref
        - enabled_at
        - status
        - checks
      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
    OfferingActivationCheckRow:
      description: >-
        One row of the activation report. kind=performed carries a definitive
        result; kind=unverifiable means the check's source was unconfigured or
        unreachable, so activation is withheld rather than assumed;
        kind=named_pending names a check that is not yet ruled on (never
        fabricated, and never silently blocking).
      properties:
        blocking:
          description: present exactly when kind=named_pending
          type: boolean
        check:
          type: string
        detail:
          type: string
        kind:
          enum:
            - performed
            - unverifiable
            - named_pending
          type: string
        result:
          description: present exactly when kind=performed
          enum:
            - pass
            - fail
          type: string
      required:
        - check
        - kind
        - detail
      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)
  securitySchemes:
    apiKey:
      description: 'Per-client API key (M2M). Presented as `Authorization: Bearer <key>`.'
      scheme: bearer
      type: http

````