> For the complete documentation index, see [llms.txt](https://docs.peakcommerce.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.peakcommerce.com/developers/api-groups/preview.md).

# Preview

The **Preview API** runs the same business-rule and pricing-engine logic as the corresponding mutating endpoints, but returns the *planned* outcome without committing it. It exists so that customer-facing UIs (and CSR / partner consoles) can show the effective date, proration, retention requirements, and which rule will apply *before* the customer clicks **Confirm**.

There is one preview endpoint per high-impact subscription transition:

* `POST /preview/plan-change` — what would happen if we moved this subscription to that product?
* `POST /preview/cancellation` — when would the cancel take effect, what refund / credit follows, and is a retention step required first?
* `POST /preview/add-on` — when would the add-on start, will it co-term, and what is the prorated first charge?

Each response includes `effectiveDate`, the resolved `businessRule` (its id, name, and key parameters), the resolved `pricing` block (delegated to [`/pricing/resolve`](/developers/api-groups/pricing.md)), and any `requirements` the UI must satisfy before calling the matching mutator (e.g. capture a retention reason).

Previews are read-only and write nothing to the audit log. They require the `read` scope.

## Endpoints

### `POST /api/v1/preview/add-on`

{% openapi src="<https://api.peakcommerce.com/api/v1/openapi.json>" path="/preview/add-on" method="post" %}
<https://api.peakcommerce.com/api/v1/openapi.json>
{% endopenapi %}

Computes the result of attaching `addOnProductId` to `subscriptionId` without applying it. The response carries the `effectiveDate` (which can be "immediate", the next bill cycle, or aligned to the parent subscription's term depending on the matching business rule), whether the add-on will be **co-termed** to the base subscription, the prorated first charge, and the `businessRule` that drove these decisions.

Pair with `POST /subscriptions/{id}/change-plan` (or the dedicated add-on mutator if your integration uses one) to commit. Returns `404` when either id is not found in the tenant's catalog or subscription set.

### `POST /api/v1/preview/cancellation`

{% openapi src="<https://api.peakcommerce.com/api/v1/openapi.json>" path="/preview/cancellation" method="post" %}
<https://api.peakcommerce.com/api/v1/openapi.json>
{% endopenapi %}

Computes the result of cancelling `subscriptionId` without applying it. The response includes the `effectiveDate` and a human-readable `effectiveDateLabel` derived from the matching cancellation rule's `changeTiming` — `immediate`, `end_of_term`, `custom_delay`, or `grace_period` are all honored end-to-end, so admin edits to a cancellation rule's timing flow straight through this preview without any code change. Cancellation rule selection follows the shared product → category → tenant-global → platform-default precedence, so multi-rule tenants always get the most specific cancellation rule for the subscription's product. The response also surfaces the refund or credit the customer would receive, any `retentionRequirements` the UI must satisfy first (e.g. capture a reason, present a save offer), and the matching `businessRule` for transparency.

Use the result to render the cancellation confirmation modal; commit by calling [`POST /subscriptions/{id}/cancel`](/developers/api-groups/subscriptions.md#post-apiv1subscriptionsidcancel).

Plan-change and add-on previews resolve their effective-date timing through the same shared business-rule resolver and pass product/category hints (target product + current product for plan-change; the add-on product itself for add-on) so product- and category-scoped tenant rules win over tenant-global and platform-default rows. Admin edits to a tenant's product-scoped rule take effect on the very next preview without code changes.

### `POST /api/v1/preview/order-total`

{% openapi src="<https://api.peakcommerce.com/api/v1/openapi.json>" path="/preview/order-total" method="post" %}
<https://api.peakcommerce.com/api/v1/openapi.json>
{% endopenapi %}

*Notes, examples, or caveats for `POST /preview/order-total` go here.*

### `POST /api/v1/preview/plan-change`

{% openapi src="<https://api.peakcommerce.com/api/v1/openapi.json>" path="/preview/plan-change" method="post" %}
<https://api.peakcommerce.com/api/v1/openapi.json>
{% endopenapi %}

Computes the result of moving `subscriptionId` to `targetProductId` without applying it. The response includes `effectiveDate` (immediate vs end-of-term), the prorated charge or credit, the matching `businessRule`, and the resolved unit price for the target plan (via the [Pricing API](/developers/api-groups/pricing.md)).

Use the response to populate the plan-change confirmation dialog; commit by calling [`POST /subscriptions/{id}/change-plan`](/developers/api-groups/subscriptions.md#post-apiv1subscriptionsidchange-plan) with the same `targetProductId`. Returns `404` when either the subscription or the target product is not in the tenant's catalog.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.peakcommerce.com/developers/api-groups/preview.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
