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

# Price a plan or quantity change

> Same body as `change-plan`, nothing charged · what to show before the customer confirms ("+1 seat: 5.00 today, then 30.00/month").




## OpenAPI

````yaml /v3-beta/api-reference/openapi.yaml post /v3/subscriptions/{id}/change-plan/preview
openapi: 3.1.0
info:
  title: Suby.fi Merchant API
  version: 3.0.0-beta
  description: >
    The **v3** public merchant API for Suby.fi. RESTful (plural,
    resource-oriented

    endpoints under the `/v3` prefix). Authenticate every request

    with your secret API key in the `X-Suby-Api-Key` header.


    - `sk_live_…` keys operate in **production** (real funds).

    - `sk_sandbox_…` keys operate in a fully simulated **sandbox** (test cards,
      Base Sepolia crypto, no real money). The environment is derived from the
      key prefix.
  contact:
    email: contact@suby.fi
    url: https://suby.fi
servers:
  - url: https://api.beta.suby.fi
    description: Production + sandbox (environment selected by API key prefix)
security:
  - ApiKeyAuth: []
tags:
  - name: Products
    description: Manage your product catalog (one-time and recurring).
  - name: Checkout
    description: >-
      Hosted checkout · signed session tokens (`cs_…`). Every card Suby holds
      was collected here, which is what keeps card data out of your systems.
  - name: Payments
    description: >-
      Read payments and receipts, refund them, and debit a stored instrument
      off-session (pay-as-you-go). Collecting a card happens on the hosted
      checkout, never here.
  - name: Subscriptions
    description: >-
      Drive a live subscription · read it, change its plan, end it.
      Subscriptions are opened by a checkout session, not by this API.
  - name: Discount Codes
    description: Promo codes, redeemed at checkout.
  - name: Crypto
    description: >-
      The headless rail · quote, charge, and settle on-chain from inside your
      own site. No card data is involved, so none of the constraints that keep
      card collection on a Suby page apply here.
  - name: Customers
    description: First-class customer records with billing address.
  - name: Payment Methods
    description: >-
      Read and detach the cards a customer has stored. They are created by a
      checkout session (`savePaymentMethod`, or `mode=setup`) · the only place a
      card is collected.
  - name: Licence Key
    description: >-
      The licence server · validate a key, take a seat, free one. Authenticated
      with your API key like everything else, and scoped to the licences you
      issued, so your backend relays the check rather than your customer's
      software calling it directly.
paths:
  /v3/subscriptions/{id}/change-plan/preview:
    post:
      tags:
        - Subscriptions
      summary: Price a plan or quantity change
      description: >
        Same body as `change-plan`, nothing charged · what to show before the
        customer confirms ("+1 seat: 5.00 today, then 30.00/month").
      operationId: previewSubscriptionChange
      parameters:
        - $ref: '#/components/parameters/SubscriptionId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlanChangeTarget'
      responses:
        '200':
          description: The change, priced
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessEnvelope'
                  - properties:
                      data:
                        type: object
                        properties:
                          direction:
                            type: string
                            enum:
                              - UPGRADE
                              - DOWNGRADE
                              - LATERAL
                          timing:
                            type: string
                            enum:
                              - immediate
                              - period_end
                            description: '`immediate` or at `effectiveAt`.'
                          effectiveAt:
                            type: string
                            format: date-time
                          productId:
                            type: string
                            description: The plan in force once the change applies.
                          quantity:
                            type: integer
                            description: The units held once the change applies.
                          amountDueNowCents:
                            type: string
                            description: Gross charged now, minor units.
                          amountDueNowVatCents:
                            type: string
                            nullable: true
                          recurringAmountCents:
                            type: string
                            description: Gross per cycle afterwards.
                          recurringVatCents:
                            type: string
                            nullable: true
                          currency:
                            type: string
                            enum:
                              - EUR
                              - USD
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: '`SUBSCRIPTION_NOT_FOUND`, `TARGET_PRODUCT_NOT_FOUND`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: '`SAME_PLAN`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Same as `change-plan`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  parameters:
    SubscriptionId:
      name: id
      in: path
      required: true
      schema:
        type: string
        example: sub_abc123
  schemas:
    PlanChangeTarget:
      type: object
      description: '`productId`, `quantity`, or both.'
      properties:
        productId:
          type: string
          description: Target plan. Omitted = current plan.
          example: pro_9m2k1x8s7d6f
        quantity:
          type: integer
          minimum: 1
          maximum: 999
          description: Units to hold afterwards (absolute, not a delta).
          example: 3
        effective:
          type: string
          enum:
            - auto
            - now
            - period_end
          default: auto
          description: '`auto`: increase now, decrease at period end.'
        proration:
          type: string
          enum:
            - delta
            - none
          default: delta
          description: '`delta` charges the prorated difference; `none` charges nothing.'
    SuccessEnvelope:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
        data:
          description: Endpoint-specific payload.
    Error:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Machine-readable error code.
          example: NOT_FOUND
        message:
          type: string
          example: Resource not found
        data:
          description: Optional error detail.
  responses:
    Unauthorized:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            error: UNAUTHORIZED
            message: Invalid or missing API key
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Suby-Api-Key
      description: Secret API key. `sk_live_…` (production) or `sk_sandbox_…` (sandbox).

````

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