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

# Subscription Offers

> Fetch the effective subscription offer for a product or variant to power frequency selectors, savings displays, and checkout validation on your storefront.

Before a customer can subscribe, your product detail page needs to know which subscription frequencies are available, what discounts apply, and whether subscriptions are offered at all for that product or variant. The subscription offer endpoint gives you all of this in a single read, resolved against the plans and offers you have configured in Admin.

## Fetching a subscription offer

Call `GET /store/products/:id/subscription-offer` to retrieve the effective offer for a product. Pass an optional `variant_id` query parameter to resolve the offer for a specific variant instead.

```bash theme={null}
GET /store/products/:id/subscription-offer
GET /store/products/:id/subscription-offer?variant_id=variant_123
```

When `variant_id` is provided and that variant has its own offer configured, the variant-level offer takes precedence over the product-level offer. If no offer is found at either level, or if the offer is disabled, the response returns `is_subscription_available: false`.

## Response shape

```json theme={null}
{
  "subscription_offer": {
    "is_subscription_available": true,
    "product_id": "prod_123",
    "variant_id": "variant_456",
    "source_offer_id": "offer_789",
    "source_scope": "variant",
    "allowed_frequencies": [
      {
        "frequency_interval": "month",
        "frequency_value": 1,
        "label": "Monthly",
        "discount": {
          "type": "percentage",
          "value": 10
        }
      },
      {
        "frequency_interval": "month",
        "frequency_value": 3,
        "label": "Every 3 months",
        "discount": {
          "type": "percentage",
          "value": 15
        }
      }
    ],
    "discount_semantics": "per_order",
    "minimum_cycles": 2,
    "trial": null
  }
}
```

## Response fields

| Field                       | Description                                                                    |
| --------------------------- | ------------------------------------------------------------------------------ |
| `is_subscription_available` | `true` if subscriptions are available for this product or variant              |
| `product_id`                | The product the offer applies to                                               |
| `variant_id`                | The resolved variant, if `variant_id` was passed                               |
| `source_offer_id`           | The internal ID of the offer that was resolved                                 |
| `source_scope`              | Whether the offer came from `"variant"` or `"product"` level                   |
| `allowed_frequencies`       | Array of available subscription cadences (see below)                           |
| `discount_semantics`        | How the discount is applied — for example `"per_order"`                        |
| `minimum_cycles`            | The minimum number of billing cycles before cancellation is allowed, or `null` |
| `trial`                     | Trial configuration object, or `null` if no trial is configured                |

## Frequency items

Each object in `allowed_frequencies` describes one selectable cadence:

| Field                | Description                                              |
| -------------------- | -------------------------------------------------------- |
| `frequency_interval` | Time unit: `"week"`, `"month"`, or `"year"`              |
| `frequency_value`    | Number of intervals between billings                     |
| `label`              | Human-readable label you can display directly in your UI |
| `discount.type`      | Discount type — for example `"percentage"` or `"fixed"`  |
| `discount.value`     | The discount amount in the given type's unit             |

## Powering a PDP subscription selector

Use this endpoint to drive the subscription UI on your product detail page. A typical implementation fetches the offer on page load and uses the response to:

1. **Show or hide the subscription option** — render the subscription selector only when `is_subscription_available` is `true`.
2. **Populate the frequency selector** — render one option per item in `allowed_frequencies`, using `label` as the display text.
3. **Display the discount** — show the savings for each frequency using `discount.type` and `discount.value`.
4. **Set checkout metadata** — when the customer confirms a frequency, use the selected `frequency_interval` and `frequency_value` to set the line item metadata before calling the subscribe endpoint.

```typescript theme={null}
const { subscription_offer } = await medusa.client.fetch(
  `/store/products/${productId}/subscription-offer?variant_id=${variantId}`
);

if (!subscription_offer.is_subscription_available) {
  // Hide subscription option
  return;
}

// Render a frequency option for each allowed cadence
const options = subscription_offer.allowed_frequencies.map((freq) => ({
  label: freq.label,
  interval: freq.frequency_interval,
  value: freq.frequency_value,
  discount: freq.discount,
}));
```

<Note>
  The `allowed_frequencies` array only contains cadences that are active in your Plans & Offers configuration. Use this list to validate which cadences a customer can select — do not allow customers to submit cadences that are not present in the response.
</Note>
