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

# Migrate To A Plan Version

> Moves the subscription to a named version of its plan. The move takes effect at the end of the current billing period: the current period bills as before, and each period that starts at or after that boundary bills from the target version. The target can be an older or a newer published version. A migration always sets versionPolicy to pinned, so a later change of the plan's default version does not move the subscription. To follow the plan default again, call PATCH /v0/subscriptions/{id} with versionPolicy: 'floating'. A second migration before the boundary replaces the first. Migrating to the version the subscription is already on changes nothing except that it pins a floating subscription, so it is safe to repeat. A version number that does not exist on the plan and an archived version both return 404. The request is refused with 409 and a code when: the subscription is not live; the subscription ends at or before the boundary; a kept override has a rate that would mean something else on the new price; a feature's reset period, metric or pricing unit changes; or the new version sells a price that a continuing interval already covers.



## OpenAPI

````yaml /openapi.json post /v0/subscriptions/{id}/versionMigration
openapi: 3.1.0
info:
  title: Paygentic API
  version: 0.1.0
  description: >
    The Paygentic API provides a comprehensive platform for building and scaling
    monetization infrastructure.


    ## Authentication

    All API requests require authentication using an API key passed in the
    `Authorization` header:

    ```

    Authorization: Bearer YOUR_API_KEY

    ```


    ## Base URL

    All API requests should be made to:

    ```

    https://api.paygentic.io/v0

    ```
  contact:
    name: Paygentic Support
    email: support@paygentic.io
  license:
    name: Proprietary
servers:
  - url: https://api.paygentic.io
    description: Production API
  - url: https://api.sandbox.paygentic.io
    description: Sandbox API
security:
  - BearerAuth: []
tags:
  - name: Customers
    description: >-
      A `Customer` is an entity connected to a `Merchant` via a `Subscription`.
      This represents the merchant-facing perspective of `Consumers` who
      purchase their `Products`.
  - name: Billable Metrics
    description: >-
      A `Billable Metric` defines a measurable quantity tied to a `Product`'s
      consumption. Each metric stores details including its label, an
      explanatory description, and measurement units.
  - name: Grants
    description: >-
      Grants credit a customer's metered entitlement balance. Merchants can
      create grants directly or void existing ones.


      Use `GET /v1/entitlements?customerId={id}` or `GET
      /v1/entitlements?subscriptionId={id}` to find the metered entitlement `id`
      needed for these endpoints.
  - name: Features
    description: >-
      A `Feature` represents a specific capability or functionality provided by
      a `Product`. Features can be metered (usage-based), static (fixed
      allocation), or boolean (enabled/disabled).
  - name: Fees
    description: >-
      A `Fee` defines a recurring or one-time charge tied to a `Product`. Fees
      are linked to prices, and cadence is defined on the Price.
  - name: Plans
    description: >-
      A `Plan` links a collection of `Prices` to a `Product`. It functions as a
      pricing structure document for a particular feature set or service
      offering.
  - name: Prices
    description: >-
      A `Price` determines the monetary value for a single unit of a `Billable
      Metric`. Prices are exclusively grouped within a `Plan`.
  - name: Products
    description: >-
      A `Product` is an offering sold by a `Merchant`. It includes product
      metadata like title, summary, and pricing details. `Plans`, `Prices`, and
      `Subscriptions` are all associated with products.
  - name: Sources
    description: >-
      A `Source` is an external data provider capable of automatically creating
      usage events. Configuration occurs at the plan level, enabling data
      retrieval from third-party platforms such as Stripe to produce billable
      events.
  - name: Subscriptions
    description: >-
      A `Subscription` is a customer's commitment to purchase a `Product`
      following the terms of a `Plan` and its linked `Prices`.
  - name: Users
    description: >-
      A `User` is an entity granted access to an Organization's resources. All
      operations are performed by users.
  - name: Invoices V2
    description: >-
      Invoice V2 operations supporting billing cycles organized by time periods.
      Warning: v0 invoice endpoints are no longer supported.
  - name: Revenue
    description: Revenue data from invoices and payments
  - name: Profitability
    description: Per-customer profitability summaries
  - name: Test Clocks
    description: >-
      Test clocks provide programmable time control to simulate subscription and
      billing scenarios during testing.
  - name: Events
    description: Ingest raw metering events that are processed by the meters service.
  - name: Payments
    description: >-
      Create and manage one-off payments. A payment represents a single charge
      that a merchant wants to collect from a customer.
  - name: Payment Sessions
    description: >-
      Handle payment session lifecycle and processing across various entity
      types including invoices and subscriptions
  - name: Costs
    description: >-
      A Cost represents the operational or infrastructure expense of serving
      customers for a given product. Costs are metered (driven by event-based
      usage) and are tracked in parallel with billable metrics to give merchants
      visibility into both revenue and cost per customer.
  - name: ExternalReferences
    description: >-
      An `ExternalReference` links a Paygentic entity (e.g. an `Item`) to a
      record in an external system such as Salesforce or NetSuite. Multiple
      external records may map to the same Paygentic entity, but each external
      id is the *primary* reference of at most one entity per merchant.
  - name: Items
    description: >-
      An `Item` is the canonical "thing you sell" that external-system mappings
      point at. It is fully decoupled from the billing `Product` and holds no
      pricing/plan/metering, and it is CRM/ERP agnostic — which providers map to
      it lives entirely in its `ExternalReference` rows.
  - name: MerchantIntegrations
    description: >-
      A `MerchantIntegration` records a merchant's connection to an external
      provider. One connection per `(merchant, provider)` — re-connecting
      upserts in place.
  - name: Approvals
    description: Submit, decide, cancel, and read maker-checker approvals.
  - name: Orders
    description: Manage Orders, their line items, and billing schedules.
  - name: Billing Schedules
    description: >-
      Owner-polymorphic billing schedules with intervals and staged invoice
      projections. A BillingSchedule belongs to exactly one Order or one
      Subscription (XOR). Cadence lives on ScheduleIntervals
      (cadence-on-the-line).
paths:
  /v0/subscriptions/{id}/versionMigration:
    post:
      tags:
        - Subscriptions
      summary: Migrate To A Plan Version
      description: >-
        Moves the subscription to a named version of its plan. The move takes
        effect at the end of the current billing period: the current period
        bills as before, and each period that starts at or after that boundary
        bills from the target version. The target can be an older or a newer
        published version. A migration always sets versionPolicy to pinned, so a
        later change of the plan's default version does not move the
        subscription. To follow the plan default again, call PATCH
        /v0/subscriptions/{id} with versionPolicy: 'floating'. A second
        migration before the boundary replaces the first. Migrating to the
        version the subscription is already on changes nothing except that it
        pins a floating subscription, so it is safe to repeat. A version number
        that does not exist on the plan and an archived version both return 404.
        The request is refused with 409 and a code when: the subscription is not
        live; the subscription ends at or before the boundary; a kept override
        has a rate that would mean something else on the new price; a feature's
        reset period, metric or pricing unit changes; or the new version sells a
        price that a continuing interval already covers.
      operationId: migrateSubscriptionVersion
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
          description: The subscription ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MigrateSubscriptionVersionRequest'
            example:
              targetVersionNumber: 2
      responses:
        '200':
          description: >-
            The subscription after the migration, and what the migration did. If
            changed is false, nothing moved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MigrateSubscriptionVersionResponse'
              example:
                subscription:
                  id: sub_j1k2l3m4n5o6p7q8
                  object: subscription
                  versionPolicy: pinned
                  autoCharge: true
                  taxExempt: true
                  createdAt: '2024-02-01T14:45:30Z'
                  customerId: cus_r9s0t1u2v3w4x5y6
                  endingAt: '2024-12-31T23:59:59Z'
                  estimatedTaxRate: 0
                  name: Analytics Co - Data Platform Enterprise
                  payment: null
                  planId: plan_z7a8b9c0d1e2f3g4
                  startedAt: '2024-02-01T14:45:30Z'
                  status: active
                  terminatedAt: null
                  terminatedBy: null
                  terminationReason: null
                  updatedAt: '2024-02-15T09:20:00Z'
                  planVersionId: pver_u2v3w4x5y6z7a8b9
                  versionNumber: 2
                migration:
                  fromVersionNumber: 1
                  toVersionNumber: 2
                  effectiveAt: '2024-03-01T00:00:00Z'
                  changed: true
                lineItems:
                  syncFailed: false
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          description: >-
            Another change is in progress on this subscription or its plan.
            Retry after the time in the Retry-After header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    MigrateSubscriptionVersionRequest:
      type: object
      additionalProperties: false
      required:
        - targetVersionNumber
      description: The plan version to move the subscription to.
      properties:
        targetVersionNumber:
          type: integer
          minimum: 1
          maximum: 2147483647
          description: The number of a published version of the subscription's plan.
    MigrateSubscriptionVersionResponse:
      type: object
      required:
        - subscription
        - migration
        - lineItems
      properties:
        subscription:
          $ref: '#/components/schemas/Subscription'
        migration:
          type: object
          required:
            - fromVersionNumber
            - toVersionNumber
            - effectiveAt
            - changed
          properties:
            fromVersionNumber:
              type:
                - integer
                - 'null'
              description: >-
                The version the subscription was on. Null for a legacy
                subscription with no version pin.
            toVersionNumber:
              type: integer
              description: The version the subscription is now pinned to.
            effectiveAt:
              type:
                - string
                - 'null'
              format: date-time
              description: When the target version starts to bill. Null when nothing moved.
            changed:
              type: boolean
              description: >-
                False when the subscription was already on the target and
                already pinned.
        lineItems:
          type: object
          required:
            - syncFailed
          properties:
            syncFailed:
              type: boolean
              description: >-
                True when the migration was saved but the line-item re-derive
                failed. The migration is not rolled back, and the re-derive is
                retried automatically.
    Error:
      type: object
      required:
        - message
      properties:
        error:
          type: string
          description: >-
            Coarse HTTP error category (e.g. 'bad_request', 'forbidden'). Maps
            to the HTTP status code.
        message:
          type: string
          description: >-
            Human-readable error message. Clients must not parse this field
            programmatically.
        code:
          type: string
          examples:
            - TAX_NOT_ENABLED
            - PAYMENT_SESSION_EXPIRED
          description: >-
            Optional semantic business error code for machine-readable
            discrimination (e.g. 'TAX_NOT_ENABLED'). UPPER_SNAKE_CASE. Clients
            should check this field, not message.
        details:
          type: object
          description: Additional error details
          additionalProperties: true
      example:
        message: The requested resource was not found
        error: not_found
    Subscription:
      type: object
      required:
        - id
        - object
        - merchantId
        - name
        - customerId
        - planId
        - status
        - startedAt
        - createdAt
        - updatedAt
        - paymentTermDays
        - versionPolicy
      properties:
        id:
          type: string
        object:
          type: string
          enum:
            - subscription
        merchantId:
          $ref: '#/components/schemas/OrganizationId'
          description: >-
            The merchant organization that owns this subscription, equal to the
            customer's merchant.
        autoCharge:
          type: boolean
          description: >-
            Whether automatic charging is enabled for this subscription. When
            true, invoices will be automatically paid using stored payment
            methods.
          default: false
        createdAt:
          type: string
          format: date-time
        customerId:
          type: string
        endingAt:
          type: string
          format: date-time
        estimatedTaxRate:
          type: number
          description: >-
            Projected tax percentage rate. Sample values: 8.875 indicates 8.875%
            tax rate, 10.0 indicates 10% tax rate, 0 indicates no tax applied
        taxExempt:
          type: boolean
          description: When true, tax rate is forced to 0%.
          default: false
        name:
          type: string
        payment:
          description: >-
            Payment session details when upfront payment is required, or
            confirmation of a zero-amount paid invoice
          oneOf:
            - type: object
              properties:
                amount:
                  type: string
                  description: >-
                    Total payment amount in decimal dollar format. Sample
                    values: '250.00' equals $250.00, '99.99' equals $99.99
                breakdown:
                  type: object
                  description: Breakdown of payment amount
                  properties:
                    upfrontCharges:
                      type: string
                      description: >-
                        One-time flat fee charges in decimal dollar format.
                        Sample values: '50.00' equals $50.00 setup fee, '100.00'
                        equals $100.00 activation fee
                    walletCharge:
                      type: string
                      description: Wallet charge amount in decimal dollar format.
                  required:
                    - upfrontCharges
                    - walletCharge
                checkoutUrl:
                  type: string
                  description: Checkout page URL for customer payment completion.
                invoiceId:
                  type: string
                  description: ID of the invoice linked to this payment.
                paymentSessionId:
                  type: string
                  description: Payment session identifier for upfront payment processing.
                status:
                  type: string
                  description: Payment status
                  enum:
                    - pending
              required:
                - paymentSessionId
                - checkoutUrl
                - amount
                - status
                - breakdown
            - type: object
              description: Zero-amount Invoice 0 that completed synchronously to PAID
              properties:
                invoiceId:
                  type: string
                  description: The Invoice 0 id
                amount:
                  type: string
                  description: Payment amount ('0' for zero-amount subscriptions)
                status:
                  type: string
                  description: Payment status
                  enum:
                    - paid
              required:
                - invoiceId
                - amount
                - status
            - type: object
              description: >-
                Invoice 0 awaiting merchant approval before payment can proceed.
                The invoice is in DRAFT status with totals calculated. Approval
                is a platform-managed action and will be available via a public
                endpoint in a future release.
              properties:
                invoiceId:
                  type: string
                  description: The Invoice 0 id awaiting approval
                amount:
                  type: string
                  description: Total payment amount in decimal dollar format
                status:
                  type: string
                  description: Payment status
                  enum:
                    - awaiting_approval
              required:
                - invoiceId
                - amount
                - status
        planId:
          type: string
        planVersionId:
          type: string
          description: The plan version pinned to this subscription at creation.
        versionNumber:
          type: integer
          minimum: 1
          description: >-
            The version number of the plan version referenced by planVersionId,
            as of subscription creation.
        versionPolicy:
          $ref: '#/components/schemas/SubscriptionVersionPolicy'
        prefundAmount:
          type: string
          deprecated: true
          description: Deprecated. Legacy-only, not populated for new subscriptions.
        minimumAccountBalance:
          type: string
          deprecated: true
          description: Deprecated. Legacy-only, not populated for new subscriptions.
        startedAt:
          type: string
          format: date-time
        status:
          type: string
          enum:
            - pending_payment
            - active
            - terminated
        terminatedAt:
          type: string
          format: date-time
        terminatedBy:
          type: string
          description: ID of who terminated the subscription (customer ID or merchant ID)
        terminationReason:
          type: string
          description: Reason for termination
        terminationChangeReason:
          type: string
          nullable: true
          enum:
            - commercial
            - correction
            - migration
            - unspecified
            - null
          x-speakeasy-unknown-values: allow
          description: >-
            Why the subscription was terminated. Null while it is not
            terminated.
        testClockId:
          type: string
          description: >-
            Test clock ID if this subscription is attached to a test clock. Only
            present in non-production environments.
        updatedAt:
          type: string
          format: date-time
        walletId:
          type: string
          deprecated: true
          description: Deprecated. Legacy-only, not populated for new subscriptions.
        renewalReminderEnabled:
          type: boolean
          nullable: true
          description: >-
            Whether renewal reminder emails are enabled for this subscription.
            Null means use plan default.
        renewalReminderDays:
          type: integer
          nullable: true
          description: >-
            Number of days before renewal to send the reminder. Null means use
            plan default.
        paymentTermDays:
          type: integer
          description: >-
            Payment term in days ("Net X") snapshotted onto every invoice the
            subscription generates (invoice dueAt = invoice issue date +
            paymentTermDays). Defaults to 0 ("due on issue"); a non-zero value
            is only set on bankTransferOnly subscriptions.
          minimum: 0
          maximum: 365
        autoApprove:
          type: boolean
          nullable: true
          description: >-
            Subscription-level auto-approval override. Null means plan default
            is used.
        metadata:
          $ref: '#/components/schemas/SubscriptionMetadata'
        customer:
          type: object
          description: >-
            Customer details with merchant and consumer information. Only
            included when include=customer is specified in the list query.
          properties:
            id:
              type: string
              description: Customer ID
            merchantId:
              type: string
              description: Merchant organization ID
            merchant:
              type: object
              properties:
                id:
                  type: string
                name:
                  type: string
                email:
                  type: string
              required:
                - id
                - name
                - email
            consumer:
              type: object
              properties:
                id:
                  type: string
                name:
                  type: string
                email:
                  type: string
              required:
                - id
                - name
                - email
    ValidationError:
      type: object
      required:
        - message
        - errors
      properties:
        error:
          type: string
          enum:
            - validation_error
          default: validation_error
          description: Error type indicating validation failure
        message:
          type: string
          description: Human-readable error message
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                description: The field that failed validation
              message:
                type: string
                description: Validation error message for this field
              code:
                type: string
                description: Validation error code
            required:
              - field
              - message
          description: Array of field-specific validation errors
      example:
        message: Validation failed
        error: validation_error
        errors:
          - field: email
            message: Invalid email format
            code: invalid_format
    OrganizationId:
      type: string
      pattern: ^org_[a-zA-Z0-9]+$
      description: Unique identifier for an organization
    SubscriptionVersionPolicy:
      type: string
      enum:
        - floating
        - pinned
      description: >-
        How the subscription follows new versions of its plan. `floating`
        follows the plan's default version: when the default changes, the
        subscription bills from the new default from its next billing period.
        `pinned` keeps the plan version that the subscription holds. A
        subscription created without a value is `floating`. A change to this
        value does not change a billing period that has already started.
    SubscriptionMetadata:
      type: object
      description: >-
        Free-form merchant metadata to attach to the subscription. Values must
        be strings, numbers, or booleans.
      additionalProperties:
        type:
          - string
          - number
          - boolean
  responses:
    BadRequest:
      description: >-
        Bad Request - The request could not be understood or was missing
        required parameters
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/Error'
              - $ref: '#/components/schemas/ValidationError'
    Unauthorized:
      description: Unauthorized - Authentication failed or user does not have permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Forbidden - Request is understood but refused
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not Found - The requested resource could not be found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Conflict:
      description: Conflict - The request conflicts with the current state of the resource
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalServerError:
      description: Internal Server Error - Something went wrong on the server side
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: API key authentication

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.