---
title: "Replace a plan"
method: PUT
path: "/api/v1/plans/{plan_id}"
tags: ["Plans"]
---

# Replace a plan

`PUT /api/v1/plans/{plan_id}`

Full replacement of a plan's version. On a draft plan, updates in-place.
On a published plan, creates a new version. Set `status` to `DRAFT` to
stage as a new draft without publishing.

## Path parameters

- `plan_id` string, MeteroidId, required

## Request body

- ReplacePlanRequest
  - `add_ons` PlanAddOnInput[]
    - `add_on_id` string, MeteroidId, required
    - `max_instances` integer, nullable
    - `price_id` string, MeteroidId
    - `self_serviceable` boolean, nullable
  - `billing` BillingConfig
    - `billing_cycles` integer, nullable
    - `net_terms` integer
    - `period_start_day` integer, nullable
  - `components` PriceComponentInput[], required
    - `fee` union, required
      - RatePlanFee — Recurring rate fee (e.g., monthly subscription)
        - `rates` TermRate[], required
          - `price` string, decimal, required
          - `term` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
      - SlotPlanFee — Slot-based fee (e.g., per-seat pricing)
        - `minimum_count` integer, nullable
        - `quota` integer, nullable
        - `rates` TermRate[], required
          - `price` string, decimal, required
          - `term` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `slot_unit_name` string, required
      - CapacityPlanFee — Capacity-based fee with included committed usage and overage
        - `cadence` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `metric_id` string, MeteroidId, required
        - `thresholds` CapacityThreshold[], required
          - `included_amount` integer, required
          - `per_unit_overage` string, decimal, required
          - `price` string, decimal, required
      - UsagePlanFee — Usage-based fee
        - `cadence` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `metric_id` string, MeteroidId, required
        - `pricing` union, required
          - PerUnitPlanPricing
            - `rate` string, decimal, required
          - TieredPlanPricing
            - `block_size` integer, nullable
            - `tiers` TierRow[], required
              - …
          - VolumePlanPricing
            - `block_size` integer, nullable
            - `tiers` TierRow[], required
              - …
          - PackagePlanPricing
            - `block_size` integer, required
            - `rate` string, decimal, required
          - MatrixPlanPricing
            - `rates` MatrixRow[], required
              - …
      - ExtraRecurringPlanFee — Extra recurring fee
        - `billing_type` 'ADVANCE' | 'ARREARS', required
        - `cadence` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `quantity` integer, required
        - `unit_price` string, decimal, required
      - OneTimePlanFee — One-time fee
        - `quantity` integer, required
        - `unit_price` string, decimal, required
    - `name` string, required
    - `product_id` string, MeteroidId
  - `currency` string, required
  - `description` string, nullable
  - `name` string, required
  - `status` 'DRAFT' | 'ACTIVE' | 'INACTIVE' | 'ARCHIVED'
  - `trial` TrialConfig
    - `duration_days` integer, required
    - `is_free` boolean, required
    - `trialing_plan_id` string, MeteroidId

## Response `200`

Plan updated

- Plan
  - `available_parameters` AvailableParameters, required
    - `billing_periods` object — Map of component_id -> available billing periods (e.g., "MONTHLY", "ANNUAL")
    - `capacity_thresholds` object — Map of component_id -> available capacity values
    - `slot_components` string[] — List of component_ids that support slot parametrization (initial slot count)
  - `billing_cycles` integer, nullable
  - `created_at` string, date-time, required
  - `currency` string, required
  - `description` string, nullable
  - `entitlements` Entitlement[]
    - `created_at` string, date-time, required
    - `feature_id` string, MeteroidId, required
    - `id` string, MeteroidId, required
    - `updated_at` string, date-time, required
    - `value` union, required
      - BooleanEntitlementValue
        - `enabled` boolean, required
      - MeteredEntitlementValue
        - `enabled` boolean — Per-entitlement kill switch. `false` means disabled.
        - `limit` string, decimal, nullable — Cap on usage. Null means unlimited.
        - `reset_period` union
          - BillingCycleResetPeriod — Resets each time your subscription renews — anchored to your billing cycle.
          - CalendarResetPeriod — Resets on calendar boundaries (e.g. the 1st of every month) — not tied to subscription start date.
            - `interval` integer, required
            - `unit` 'HOUR' | 'DAY' | 'WEEK' | 'MONTH' | 'YEAR', required
          - FixedWindowResetPeriod — Resets at regular intervals — anchored to your subscription's exact activation time.
            - `interval` integer, required
            - `unit` 'HOUR' | 'DAY' | 'WEEK' | 'MONTH' | 'YEAR', required
          - SlidingWindowResetPeriod — Always ends at now — e.g. 30 days means the last 30 days, old usage drops off automatically.
            - `interval` integer, required
            - `unit` 'HOUR' | 'DAY' | 'WEEK' | 'MONTH' | 'YEAR', required
          - NeverResetPeriod — Never resets — counts all usage since the subscription was activated.
  - `id` string, MeteroidId, required
  - `name` string, required
  - `net_terms` integer, required
  - `period_start_day` integer, nullable
  - `plan_type` 'STANDARD' | 'FREE' | 'CUSTOM', required
  - `price_components` PriceComponent[], required
    - `fee` union
      - RatePlanFee — Recurring rate fee (e.g., monthly subscription)
        - `rates` TermRate[], required
          - `price` string, decimal, required
          - `term` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
      - SlotPlanFee — Slot-based fee (e.g., per-seat pricing)
        - `minimum_count` integer, nullable
        - `quota` integer, nullable
        - `rates` TermRate[], required
          - `price` string, decimal, required
          - `term` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `slot_unit_name` string, required
      - CapacityPlanFee — Capacity-based fee with included committed usage and overage
        - `cadence` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `metric_id` string, MeteroidId, required
        - `thresholds` CapacityThreshold[], required
          - `included_amount` integer, required
          - `per_unit_overage` string, decimal, required
          - `price` string, decimal, required
      - UsagePlanFee — Usage-based fee
        - `cadence` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `metric_id` string, MeteroidId, required
        - `pricing` union, required
          - PerUnitPlanPricing
            - `rate` string, decimal, required
          - TieredPlanPricing
            - `block_size` integer, nullable
            - `tiers` TierRow[], required
              - …
          - VolumePlanPricing
            - `block_size` integer, nullable
            - `tiers` TierRow[], required
              - …
          - PackagePlanPricing
            - `block_size` integer, required
            - `rate` string, decimal, required
          - MatrixPlanPricing
            - `rates` MatrixRow[], required
              - …
      - ExtraRecurringPlanFee — Extra recurring fee
        - `billing_type` 'ADVANCE' | 'ARREARS', required
        - `cadence` 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'ANNUAL', required
        - `quantity` integer, required
        - `unit_price` string, decimal, required
      - OneTimePlanFee — One-time fee
        - `quantity` integer, required
        - `unit_price` string, decimal, required
    - `id` string, MeteroidId, required
    - `name` string, required
    - `product_id` string, MeteroidId
  - `product_family` ProductFamily, required
    - `id` string, MeteroidId, required
    - `name` string, required
  - `self_service_rank` integer, nullable
  - `status` 'DRAFT' | 'ACTIVE' | 'INACTIVE' | 'ARCHIVED', required
  - `trial` TrialConfig
    - `duration_days` integer, required
    - `is_free` boolean, required
    - `trialing_plan_id` string, MeteroidId
  - `version` integer, required
  - `version_id` string, MeteroidId, required

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `404` — Plan not found
- `429` — Too many requests

## Changes

- **2026-08-12** (v1) `4e013b4e4a8f` — 16 breaking, 8 info
  - the `components/items/fee/oneOf[#/components/schemas/CapacityPlanFee]/thresholds/items/per_unit_overage` request property type/format changed from `string`/`` to `string`/`decimal`
  - the `components/items/fee/oneOf[#/components/schemas/CapacityPlanFee]/thresholds/items/price` request property type/format changed from `string`/`` to `string`/`decimal`
  - the `components/items/fee/oneOf[#/components/schemas/ExtraRecurringPlanFee]/unit_price` request property type/format changed from `string`/`` to `string`/`decimal`
  - the `components/items/fee/oneOf[#/components/schemas/OneTimePlanFee]/unit_price` request property type/format changed from `string`/`` to `string`/`decimal`
  - …20 more
- **2026-06-01** (v1) `07a61fe347a5` — 1 breaking, 1 warning
  - removed the required property `entitlements/items/value/oneOf[#/components/schemas/MeteredEntitlementValue]/overage_behavior` from the response with the `200` status
  - removed the optional property `entitlements/items/value/oneOf[#/components/schemas/MeteredEntitlementValue]/warning_threshold_pct` from the response with the `200` status
- …earlier changes not shown

[Full history](https://skmtc.dev/meteroid-oss/apis/meteroid/changes/api/v1/plans/:plan_id/put.md)

---

[API](https://skmtc.dev/meteroid-oss/apis/meteroid.md) · [All operations](https://skmtc.dev/meteroid-oss/apis/meteroid/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/meteroid-oss/meteroid/revisions/03f9d8ae5c5e/schema)
