---
title: "Preview plan change"
method: POST
path: "/api/billing/preview-upgrade/{price_id}"
---

# Preview plan change

`POST /api/billing/preview-upgrade/{price_id}`

## Request

- Base URL: `https://app.base44.com`
- URL: `https://app.base44.com/api/billing/preview-upgrade/{price_id}`
- Auth: HTTP bearer

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Shows what upgrading your workspace to another plan costs, without changing or charging anything. Pass the price ID of the plan you're considering, from `price_ids` in [List plans](/api-reference/list-plans). Only the workspace owner can preview.

The preview mirrors [Change plan](/api-reference/change-plan): `prorated_amount_due` is what that call charges now, and `recurring_amount` is what the new plan costs at each renewal. It previews upgrades only. A downgrade returns 400, because a downgrade charges nothing now and takes effect at the end of the billing period.

This previews plans billed through Stripe. For a workspace billed through Wix, use [Preview Wix plan change](/api-reference/preview-wix-plan-change). A Wix-billed workspace can still get a result here, but it doesn't apply to its plan.

The base rate limit is 20 requests per minute per user. See [Rate limits](/developers/references/apps-api/get-started/rate-limits) for the multiplier your plan gets.

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time.</Warning>

## Path parameters

- `price_id` string, required: Price ID of the plan to preview, from `price_ids` in [List plans](/api-reference/list-plans).

## Response `200`

What the upgrade costs now and at renewal.

- PlanChangePreview: What an upgrade costs now and at renewal.
  - `prorated_amount_due` number, required: Amount [Change plan](/api-reference/change-plan) charges now for this upgrade, in major units of `currency` (dollars, not cents). When `full_diff` is `true`, this is the full price difference rather than a prorated amount.
  - `currency` string, required: Lowercase three-letter currency code of both amounts.
  - `next_billing_date` integer, required: When the new plan next renews, as a Unix timestamp in seconds.
  - `recurring_amount` number, required: What the new plan costs at each renewal, in major units of `currency`.
  - `billing_interval` string, required: How often the new plan renews: `month` or `year`.
  - `full_diff` boolean, required: `true` when `prorated_amount_due` is the full price difference between the plans, not a prorated share of it.

## Other responses

- `400`: `price_id` isn't a plan, the workspace has no active subscription, the target is a downgrade, or the move isn't allowed: a different currency, yearly to monthly billing, or a lower plan while switching to yearly billing.
- `401`: Missing or invalid credentials. A read-only token gets this response too.
- `402`: The workspace has an overdue invoice. Pay it before upgrading.
- `403`: You aren't the workspace owner.
- `409`: The subscription has ended, or the workspace is still on a free migration trial.
- `429`: Rate limit exceeded. The base rate limit is 20 requests per minute per user. See [Rate limits](/developers/references/apps-api/get-started/rate-limits) for the multiplier your plan gets.

## Changes

> 66 revisions in range; 1 not diffed.

- **2026-10-26** `395a6758864a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/adexad/apis/base44-app-management-api/changes/api/billing/preview-upgrade/:price_id/post.md)

---

[API](https://skmtc.dev/adexad/apis/base44-app-management-api.md) - [All operations](https://skmtc.dev/adexad/apis/base44-app-management-api/llms.txt) - [OpenAPI document](https://skmtc.dev/adexad/apis/base44-app-management-api/revisions/d877a932dc19?raw)
