---
title: "Preview publish plan version"
method: POST
path: "/plans/version/{plan_version_id}/publish-preview"
tags: ["plans"]
---

# Preview publish plan version

`POST /plans/version/{plan_version_id}/publish-preview`

## Request

- Base URL: `https://api.schematichq.com`
- URL: `https://api.schematichq.com/plans/version/{plan_version_id}/publish-preview`
- Auth: API key in header `X-Schematic-Api-Key`

## Path parameters

- `plan_version_id` string, required

## Request body

- PublishPlanVersionRequestBody
  - `activation_strategy` 'on_payment' | 'on_publish'
  - `address` CustomerBillingAddress
    - `city` string, required
    - `country` string, required
    - `line1` string, required
    - `line2` string, required
    - `postal_code` string, required
    - `state` string, required
  - `billing_cycle_anchor` string, date-time, nullable: The date the subscription's billing period renews on. Only honored on a first publish that starts a subscription.
  - `billing_start_date` string, date-time, nullable: The date the contract term starts. A past date backdates the subscription so the first invoice covers the term from this date to the renewal date. Requires billing_cycle_anchor. Only honored on a first publish that starts a subscription.
  - `collection_method` 'charge_automatically' | 'send_invoice'
  - `coupon_external_id` string, nullable: A Stripe coupon to apply. On a custom-plan republish it discounts the amendment invoice and is only used when that invoice is raised today; it must exist in Stripe. It is attached to the subscription, so a repeating or forever coupon also discounts the renewals that follow.
  - `custom_field_values` CheckoutFieldValue[], nullable
    - `id` string, required
    - `value` string, required
  - `customer_email` string, nullable
  - `days_until_due` integer, nullable: Payment terms in days. On a custom-plan republish they apply to the amendment invoice only, leave the subscription's renewal terms unchanged, and are only used when that invoice is raised today and sent rather than charged. Defaults to the subscription's terms.
  - `end_date` string, date-time, nullable: When a custom plan that doesn't renew ends: the company moves to the default plan then, and no renewal invoice is raised. Required when the version's renewal_policy is expire_to_default, and refused otherwise. Moved back to the last renewal on or before it, which must leave at least one whole billing period. Only honored on a first publish that starts a subscription.
  - `excluded_company_ids` string[], required
  - `migration_strategy` 'end_of_billing_period' | 'immediate' | 'leave' | 'scheduled', required
  - `phone` string, nullable
  - `prorate_first_period` boolean, nullable: When true, the partial period between the subscription starting and its renewal date is billed pro rata straight away. When false that period is free and no invoice is raised until the renewal date. Only applies alongside billing_cycle_anchor. Defaults to true.
  - `proration_behavior` 'always_invoice' | 'create_prorations' | 'none'
  - `require_no_migration` boolean, nullable: Refuse the publish if any company would be migrated onto the new version
  - `scheduled_at` string, date-time, nullable: When every company moves, for migration_strategy scheduled. Must be in the future; the migration runs within about a minute of this time. Not accepted with other strategies.
  - `send_invoice` boolean, nullable: Whether Stripe emails the invoice when it is finalized. Defaults to true.
  - `tax_id` TaxIDInput
    - `type` 'ae_trn' | 'au_abn' | 'au_arn' | 'br_cnpj' | 'br_cpf' | 'ca_bn' | 'ca_gst_hst' | 'ca_pst_bc' | 'ca_pst_mb' | 'ca_pst_sk' | 'ca_qst' | 'ch_uid' | 'ch_vat' | 'eu_vat' | 'gb_vat' | 'hk_br' | 'id_npwp' | 'il_vat' | 'in_gst' | 'jp_cn' | 'jp_rn' | 'jp_trn' | 'kr_brn' | 'mx_rfc' | 'my_frp' | 'my_itn' | 'my_sst' | 'no_vat' | 'nz_gst' | 'ph_tin' | 'sa_vat' | 'sg_gst' | 'sg_uen' | 'th_vat' | 'tr_tin' | 'tw_vat' | 'us_ein' | 'za_vat', required
    - `value` string, required

## Response `200`

OK

- object
  - `data` PublishPreviewResponseData, required
    - `billing_email` string, nullable
    - `currency` 'aed' | 'afn' | 'all' | 'amd' | 'ang' | 'aoa' | 'ars' | 'aud' | 'awg' | 'azn' | 'bam' | 'bbd' | 'bdt' | 'bif' | 'bmd' | 'bnd' | 'bob' | 'brl' | 'bsd' | 'bwp' | 'byn' | 'bzd' | 'cad' | 'cdf' | 'chf' | 'clp' | 'cny' | 'cop' | 'crc' | 'cve' | 'czk' | 'djf' | 'dkk' | 'dop' | 'dzd' | 'egp' | 'etb' | 'eur' | 'fjd' | 'fkp' | 'gbp' | 'gel' | 'gip' | 'gmd' | 'gnf' | 'gtq' | 'gyd' | 'hkd' | 'hnl' | 'htg' | 'huf' | 'idr' | 'ils' | 'inr' | 'isk' | 'jmd' | 'jpy' | 'kes' | 'kgs' | 'khr' | 'kmf' | 'krw' | 'kyd' | 'kzt' | 'lak' | 'lbp' | 'lkr' | 'lrd' | 'lsl' | 'mad' | 'mdl' | 'mga' | 'mkd' | 'mmk' | 'mnt' | 'mop' | 'mur' | 'mvr' | 'mwk' | 'mxn' | 'myr' | 'mzn' | 'nad' | 'ngn' | 'nio' | 'nok' | 'npr' | 'nzd' | 'pab' | 'pen' | 'pgk' | 'php' | 'pkr' | 'pln' | 'pyg' | 'qar' | 'ron' | 'rsd' | 'rub' | 'rwf' | 'sar' | 'sbd' | 'scr' | 'sek' | 'sgd' | 'shp' | 'sle' | 'sos' | 'srd' | 'std' | 'szl' | 'thb' | 'tjs' | 'top' | 'try' | 'ttd' | 'twd' | 'tzs' | 'uah' | 'ugx' | 'usd' | 'uyu' | 'uzs' | 'vnd' | 'vuv' | 'wst' | 'xaf' | 'xcd' | 'xcg' | 'xof' | 'xpf' | 'yer' | 'zar' | 'zmw'
    - `current_period_end` string, date-time, nullable
    - `current_period_start` string, date-time, nullable
    - `default_collection_method` 'charge_automatically' | 'send_invoice', required
    - `default_days_until_due` integer, required: Payment terms the amendment invoice gets when the publish request leaves days_until_due out.
    - `default_send_invoice` boolean, required: Whether the amendment invoice is emailed when the publish request leaves send_invoice out.
    - `effective_at` string, date-time, nullable: When the company moves to the new version. Null when no date can be named yet: the company's only subscription is in dunning or scheduled to cancel.
    - `ends_at` string, date-time, nullable: When the subscription ends instead of renewing once the amendment is finalized: the end date moved back to a renewal, or the end it already has. Null when it renews.
    - `has_billing_changes` boolean, required
    - `immediate_invoice_amount` integer, nullable: What the amendment's own invoice bills, in cents, when lands_on is immediate_invoice, after discounts and tax. Includes pending invoice items Stripe adds to the same invoice. Negative for a downgrade: Stripe raises a credit invoice with nothing due, and the credit goes to the customer's balance against later invoices.
    - `lands_on` 'immediate_invoice' | 'next_invoice' | 'none', required
    - `new_recurring_amount` integer, nullable: What the subscription's items bill per period once the new version is in place, in cents: unit price times quantity over its licensed recurring items, before discounts and tax, the way the subscription's total_price counts its items today. Null when the change is not priced, including a change with no billing impact.
    - `next_invoice_amount` integer, nullable: The next renewal invoice with the change applied, in cents, before any customer balance is applied. A downgrade invoiced now leaves a credit on that balance, so the amount due can be lower. Null when the change is not priced: it lands at the end of the period, or on a date without proration.
    - `next_invoice_at` string, date-time, nullable
    - `note` string, nullable
    - `pay_in_advance` PublishPreviewPayInAdvanceResponseData[], required
      - `committed_quantity` integer, required
      - `current_quantity` integer, nullable: Null when the subscription has no item for the feature.
      - `effective_quantity` integer, required: The quantity after finalizing. Finalizing raises an item to the committed quantity and never lowers it. Zero when the subscription will hold no item for the feature.
      - `feature_id` string, required
    - `payment_method` PublishPreviewPaymentMethodResponseData, required
      - `card_brand` string, nullable
      - `card_last4` string, nullable
      - `has_default` boolean, required
      - `payment_method_type` string, nullable
    - `proration_charge` integer, required: Sum of the positive proration lines, in cents.
    - `proration_credit` integer, required: Sum of the negative proration lines, in cents.
    - `proration_lines` PublishPreviewProrationLineResponseData[], required
      - `amount` integer, required
      - `description` string, required
      - `period_end` string, date-time, required
      - `period_start` string, date-time, required
      - `price_external_id` string, nullable
      - `quantity` integer, required
    - `proration_total` integer, required: proration_charge plus proration_credit, in cents, before tax.
    - `will_update_subscription` boolean, required
    - `would_fail` boolean, required
  - `params` object, required: Input parameters

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `500`: Server error

## Changes

> 230 revisions in range; 1 not diffed.

- **2026-10-20** `893a61af3688`: 1 info
  - added the optional property `data/ends_at` to the response with the `200` status
- **2026-10-20** `ce7c5cc627ad`: 1 info
  - added the new optional request property `end_date`
- **2026-10-12** `db1fe6b9cba3`: 1 info
  - added the optional property `data/new_recurring_amount` to the response with the `200` status
- **2026-10-12** `12535f6f8bb9`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/schematichq/apis/schematic-api/changes/plans/version/:plan_version_id/publish-preview/post.md)

---

[API](https://skmtc.dev/schematichq/apis/schematic-api.md) - [All operations](https://skmtc.dev/schematichq/apis/schematic-api/llms.txt) - [OpenAPI document](https://skmtc.dev/schematichq/apis/schematic-api/revisions/64cb7e17c236?raw)
