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

> Read every offering enabled for your brand, with its name, therapy, entry mode, checkout link, price and readiness, in one call from your server.

`GET /v1/account/brands/{brand_id}/offerings` lists every offering enabled for your brand. It
returns what a storefront needs to show and link each one: its name, its `sku_id`, its therapy,
its entry mode, its checkout link, the price shown for it, and whether it can be sold yet. Build
your catalog from this list. Your welcome pack may still print the same facts, but this read is
where they live, and it stays current as offerings are added.

## Call it from your server

This read takes your **secret API key**, so call it from your server, never from browser code.
The publishable brand key is refused here: this read is not one of the operations that key may
call (see [your credentials](https://docs.purplelabelmd.com/pages/integrate/your-credentials.md)).

```bash theme={null}
curl "$PURPLE_API_BASE/v1/account/brands/brd_acme/offerings" \
  --header "Authorization: Bearer $PURPLE_API_KEY" \
  --header "X-Brand-Id: brd_acme"
```

The brand is the one your key owns, and you present it in `X-Brand-Id`. The `brand_id` in the path
must match it. A mismatched, unknown or foreign brand answers `404`, never `403`, so the answer
never says whether another client's brand exists. Enabling an offering with
`POST /v1/account/brands/{brand_id}/offerings` follows the same rule.

The read changes nothing and moves no money.

## What comes back

A `200` carries a `data` list, one entry per enabled offering, in the catalog's order. A brand with
no enabled offerings answers `200` with an empty list (`{"data": []}`), never an error.

```json theme={null}
{
  "data": [
    {
      "offering_ref": "SEMA-1M",
      "sku_id": "sku_b7945bba07e4",
      "display_name": "Semaglutide, monthly",
      "display_name_source": "brand",
      "therapy": "Weight loss",
      "therapy_key": "weight_loss",
      "entry_mode": "checkout-first",
      "entry_link": "https://members.example.com/checkout?offering_ref=SEMA-1M&sku_id=sku_b7945bba07e4&therapy=weight_loss",
      "price": {
        "status": "available",
        "amount_minor": 29900,
        "currency": "USD",
        "billing_frequency": "monthly",
        "shipping_frequency": "monthly"
      },
      "readiness": { "status": "active", "lifecycle": { "status": "live" }, "checks": [] },
      "not_measured": []
    }
  ]
}
```

Each entry carries:

| Field | What it is |
| - | - |
| `offering_ref` | The offering's code, such as `SEMA-1M`. The checkout link and every offering call carry it. |
| `sku_id` | The offering id, shaped `sku_...`. |
| `display_name` | The name to show: the name your brand published for the offering, else the platform's name for the product. It is present for an offering whose price is not set yet, too. |
| `display_name_source` | Whose name `display_name` is: `brand` or `platform`. Omitted when `display_name` is `null`. |
| `therapy` | The offering's therapy as the catalog names it. Use it to group offerings and place them in your site's navigation. |
| `therapy_key` | The therapy key a checkout-first link carries, such as `weight_loss`. `null` when the catalog maps no key for the therapy, and a checkout-first link is then not available. |
| `entry_mode` | How a patient starts this offering: `questions-first` (the health questions come before payment) or `checkout-first` (payment first, the questions after). See [which way in](https://docs.purplelabelmd.com/pages/integrate/lovable-storefront.md#which-way-in-your-entry-mode). |
| `entry_link` | The checkout link for this offering on your member portal address. A questions-first link carries `{journey_id}` where the patient's journey id goes. Your storefront does not open a questions-first link itself: it hands the patient to the checkout door, and the door sends the patient there (see [handing the patient to checkout](https://docs.purplelabelmd.com/pages/integrate/lovable-storefront.md#handing-the-patient-to-checkout)). `null` when no link is available, and `entry_link_unavailable` says why. |
| `entry_link_unavailable` | Present exactly when `entry_link` is `null`. See [when there is no checkout link](#when-there-is-no-checkout-link). |
| `price` | The price shown for the offering. See [price, or no price yet](#price-or-no-price-yet). |
| `readiness` | Whether the offering can be sold yet. See [readiness](#readiness). |
| `not_measured` | The names of the fields that could not be read right now. Empty when every read answered. |

## Price, or no price yet

`price` is the same price the checkout charges, read from the same source. It is never computed
for this list. Its `status` is one of three values:

* **`available`**: the price is set. The entry carries `amount_minor` (a whole number in the
  smallest unit of the currency, so `29900` is \$299.00), `currency` (`USD`), and
  `billing_frequency` (`one_time`, `monthly`, `quarterly`, `semiannual` or `annual`). It may also
  carry `shipping_frequency` (`none`, `weekly`, `biweekly`, `monthly` or `quarterly`), or
  `shipping_interval_days` and `renewal_interval_days` when the schedule follows the medication's
  supply.
* **`no_price_yet`**: the price or its billing terms are not set up yet. No amount is given, rather
  than a guessed one, and a checkout for the offering is refused. Show the offering without a price
  and without a buy control.
* **`not_measured`**: the price could not be read right now. This is not the same as "no price
  yet": the price may well be set. Try the read again before you tell a patient anything about the
  price.

## Null means one of two things

A field that is `null` means one of two different things, and `not_measured` tells them apart:

* **`null`, and the field is named in `not_measured`**: the part of the platform that holds the
  value could not be read right now. The offering is still listed. Read again later.
* **`null`, and the field is not named in `not_measured`**: the platform holds no value for it. For
  example, `therapy_key` is `null` when the catalog maps no key for the offering's therapy.

`not_measured` can name `display_name`, `therapy`, `therapy_key`, `entry_mode`, `entry_link` and
`price`.

## When there is no checkout link

When `entry_link` is `null`, `entry_link_unavailable` carries one of four reasons:

| Reason | What it means |
| - | - |
| `no_member_address` | Your brand has no active member portal address yet. Every checkout link is built on that address, so there is no link until it exists. Your onboarding contact sets it up (see [Login URLs and domains](https://docs.purplelabelmd.com/pages/integrate/login-urls-and-domains.md)). |
| `no_therapy_key` | A checkout-first link needs a therapy key, and the catalog maps none for this offering's therapy. |
| `offering_id_not_accepted` | The offering's `sku_id` is not one the checkout accepts. |
| `not_measured` | A part the link depends on could not be read right now. |

Show such an offering without a buy control, and ask your onboarding contact to resolve any reason
other than `not_measured`.

## Readiness

`readiness` says whether the offering can be sold yet, exactly as the catalog reports it:

* `status`: `enabled_pending_activation` (enabled for your brand, not yet ready to sell) or
  `active`.
* `lifecycle`, when the catalog has one: its `status` is `live`, `setting_up` or `paused`, with
  `live_since`, `paused_at` and `pause_reasons` where they apply.
* `checks`: the activation checks behind the status.

An offering that is enabled but still pending is listed with its name, so your storefront can show
it as coming soon.

## Errors

| Status | When |
| - | - |
| `401` | The API key is missing or not recognized. |
| `404` | The brand in the path is unknown, foreign, or does not match `X-Brand-Id`. |
| `502`, `503` | The platform could not read the catalog right now. Nothing is listed. Retry. |

## Your brand configuration does not list offerings

The brand configuration readback,
[`GET /v1/account/brands/{brand_id}/config`](https://docs.purplelabelmd.com/pages/integrate/brand-configuration#read-it-back),
returns your theme, your enabled therapies and your redirect allowlist. It does not carry your
offerings. List them with this read.

## The endpoint

* [List your brand's enabled offerings](https://docs.purplelabelmd.com/api-reference/offering-configuration/list-your-brands-enabled-offerings.md) — `GET /v1/account/brands/{brand_id}/offerings`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.