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

# Move a subscription to another plan



## OpenAPI

````yaml /api-reference/commerce-v1.openapi.json post /v1/commerce/subscriptions/{id}/plan
openapi: 3.0.3
info:
  description: >-
    Public REST API for COPE vendor integrations. Authenticate with a COPE API
    key or Clerk bearer token and call the endpoints described below.
  title: COPE Public API
  version: v1
servers:
  - description: Production
    url: https://api.cope.com
security:
  - cope_sk: []
paths:
  /v1/commerce/subscriptions/{id}/plan:
    post:
      tags:
        - Subscriptions
      summary: Move a subscription to another plan
      operationId: commerce.subscriptions.plan_changes.create
      parameters:
        - description: id public identifier.
          example: sub_A1b2C3d4E5f6G7h8
          in: path
          name: id
          required: true
          schema:
            example: sub_A1b2C3d4E5f6G7h8
            pattern: ^sub_[A-Za-z0-9]{8,32}$
            type: string
        - description: >-
            Required. At most 255 characters of valid UTF-8 with no NUL byte.
            The change attempt is recorded against this key for this
            subscription: a retry that carries the same key and the same body
            returns the original response instead of changing the subscription
            twice, and the same key with a different body is refused with 409
            idempotency_conflict.
          in: header
          name: Idempotency-Key
          required: true
          schema:
            maxLength: 255
            type: string
      requestBody:
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                plan_id:
                  example: plan_A1b2C3d4
                  pattern: ^plan_[A-Za-z0-9]{8,32}$
                  type: string
              required:
                - plan_id
              type: object
      responses:
        '200':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  data:
                    additionalProperties: false
                    properties:
                      effective_at:
                        type: string
                      effective_confirmed_at:
                        nullable: true
                        type: string
                      failure:
                        additionalProperties: false
                        nullable: true
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                        required:
                          - code
                          - message
                        type: object
                      from:
                        additionalProperties: false
                        properties:
                          amount_cents:
                            type: integer
                          currency:
                            type: string
                          plan_id:
                            nullable: true
                            type: string
                        required:
                          - plan_id
                          - amount_cents
                          - currency
                        type: object
                      reason:
                        nullable: true
                        type: string
                      requested_by:
                        additionalProperties: false
                        properties:
                          actor_id:
                            type: string
                          actor_type:
                            type: string
                          business_id:
                            type: string
                          initiated_by:
                            type: string
                        required:
                          - initiated_by
                          - actor_type
                          - actor_id
                          - business_id
                        type: object
                      status:
                        type: string
                      subscription_id:
                        type: string
                      to:
                        additionalProperties: false
                        properties:
                          amount_cents:
                            type: integer
                          currency:
                            type: string
                          plan_id:
                            type: string
                        required:
                          - plan_id
                          - amount_cents
                          - currency
                        type: object
                      type:
                        type: string
                    required:
                      - subscription_id
                      - type
                      - status
                      - effective_at
                      - effective_confirmed_at
                      - reason
                      - from
                      - to
                      - requested_by
                      - failure
                    type: object
                required:
                  - data
                type: object
          description: Successful response
        '400':
          content:
            application/problem+json:
              examples:
                subscription_idempotency_key_required:
                  summary: Missing Idempotency-Key header
                  value:
                    code: idempotency_key_required
                    detail: >-
                      an Idempotency-Key header is required for a subscription
                      change
                    errors:
                      - code: idempotency_key_required
                        detail: >-
                          an Idempotency-Key header is required for a
                          subscription change
                        param: idempotency_key
                    request_id: req_123
                    status: 400
                    title: Idempotency Key Required
                    type: https://docs.cope.com/errors/idempotency_key_required
                subscription_invalid_idempotency_key:
                  summary: Malformed Idempotency-Key header
                  value:
                    code: invalid_idempotency_key
                    detail: >-
                      Idempotency-Key header must be at most 255 characters of
                      valid UTF-8 without a NUL byte
                    errors:
                      - code: invalid_idempotency_key
                        detail: >-
                          Idempotency-Key header must be at most 255 characters
                          of valid UTF-8 without a NUL byte
                        param: idempotency_key
                    request_id: req_123
                    status: 400
                    title: Invalid Idempotency Key
                    type: https://docs.cope.com/errors/invalid_idempotency_key
                unparsable_request:
                  summary: Unparsable request
                  value:
                    code: invalid_request
                    detail: >-
                      The request could not be parsed. Check the query string
                      and the request body.
                    request_id: req_123
                    status: 400
                    title: Invalid Request
                    type: https://docs.cope.com/errors/invalid_request
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Invalid request
        '401':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Missing or invalid bearer token
        '403':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Bearer token is not authorized for this route
        '404':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Resource not found
        '409':
          content:
            application/problem+json:
              examples:
                subscription_idempotency_conflict:
                  summary: Idempotency key reused with a different body
                  value:
                    code: idempotency_conflict
                    detail: >-
                      request body does not match the original request for this
                      idempotency key
                    errors:
                      - code: idempotency_body_mismatch
                        detail: >-
                          request body does not match the original request for
                          this idempotency key
                        param: idempotency_key
                    request_id: req_123
                    status: 409
                    title: Idempotency Conflict
                    type: https://docs.cope.com/errors/idempotency_conflict
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: >-
            The idempotency key was already used for this subscription with a
            different body.
        '422':
          content:
            application/problem+json:
              examples:
                subscription_validation_failed:
                  summary: The body carries an invalid or unsupported member
                  value:
                    code: validation_failed
                    detail: null
                    errors:
                      - code: unsupported
                        detail: amount_cent is not supported by this public endpoint
                        param: amount_cent
                    request_id: req_123
                    status: 422
                    title: Validation Failed
                    type: https://docs.cope.com/errors/validation_failed
                plan_not_available:
                  summary: The target plan cannot be moved to
                  value:
                    code: plan_not_available
                    detail: target plan is not on this product for this business
                    errors:
                      - code: plan_not_available
                        detail: target plan is not on this product for this business
                        param: plan_id
                    request_id: req_123
                    status: 422
                    title: Plan Not Available
                    type: https://docs.cope.com/errors/plan_not_available
                too_close_to_renewal:
                  summary: The next renewal is inside the change cutoff
                  value:
                    code: too_close_to_renewal
                    detail: too close to renewal
                    errors:
                      - code: too_close_to_renewal
                        detail: too close to renewal
                        param: subscription_id
                    request_id: req_123
                    status: 422
                    title: Too Close To Renewal
                    type: https://docs.cope.com/errors/too_close_to_renewal
                subscription_not_eligible:
                  summary: The subscription cannot be changed
                  value:
                    code: subscription_not_eligible
                    detail: installment plan
                    errors:
                      - code: installment_plan
                        detail: installment plan
                        param: subscription_id
                    request_id: req_123
                    status: 422
                    title: Subscription Not Eligible
                    type: https://docs.cope.com/errors/subscription_not_eligible
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: The body is invalid, or the subscription cannot be changed now
      security:
        - cope_sk: []
components:
  schemas:
    PublicProblemDetail:
      additionalProperties: false
      properties:
        code:
          type: string
        detail:
          nullable: true
          type: string
        errors:
          items:
            additionalProperties: false
            properties:
              code:
                type: string
              detail:
                type: string
              param:
                type: string
            required:
              - code
              - detail
            type: object
          type: array
        request_id:
          type: string
        status:
          type: integer
        title:
          type: string
        type:
          type: string
      required:
        - type
        - title
        - status
        - code
        - request_id
      type: object
  securitySchemes:
    cope_sk:
      description: >-
        Bearer credential for the public API. Vendor integrations should send a
        live COPE API key (`ck_live_*`; keys issued earlier as `cope_sk_live_*`
        keep working). Clerk bearer tokens are also accepted when paired with
        `X-Cope-Business-Id`.
      scheme: bearer
      type: http

````