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

# Update plan draft

> Change a draft's prices per interval, trials, the interval shown first, countries with their currency and prices, and credit or balance rules, or undo single changes. Each block sent replaces that block; blocks left out stay as they are. Buyers and subscribers see nothing until the draft is published.

Change a draft's prices per interval, trials, the interval shown first, countries with their currency and prices, and credit or balance rules, or undo single changes. Each block sent replaces that block; blocks left out stay as they are. Buyers and subscribers see nothing until the draft is published.


## OpenAPI

````yaml /openapi/en/rest/2026-08-27.json patch /plans/{id}/drafts/{draftId}
openapi: 3.1.0
info:
  title: Commet API
  version: '2026-08-27'
  description: Billing and payments API for SaaS and AI products.
servers:
  - url: https://commet.co/api/v1
security:
  - ApiKeyAuth: []
tags:
  - name: Test Clock
    description: >-
      Simulate the passage of time in sandbox to test billing flows. Mirrors
      Stripe test clocks: forward-only and sandbox-only.
  - name: Customers
  - name: Subscriptions
  - name: Plans
  - name: Markets
    description: >-
      Reusable country groups for market-specific prices and selectable price
      variants.
  - name: Offers
  - name: Promo Codes
  - name: Features
  - name: Usage
  - name: Seats
  - name: Quota
  - name: Add-ons
  - name: Portal
  - name: Credit Packs
  - name: Plan Groups
  - name: Invoices
  - name: Payments
    description: >-
      One-time payments with no subscription or plan. Charge a customer's saved
      payment method off-session, or create a payment link the customer opens to
      pay. Tax, invoice, and receipt are handled automatically.
  - name: Transactions
  - name: Webhooks
  - name: API Keys
  - name: Payouts
    description: >-
      Withdraw available balance to your bank and manage the payout account
      (verification + destination bank accounts).
  - name: Provisioning
    description: >-
      Take ownership of an organization an agent provisioned headlessly. The
      agent holds the API keys from the start; a human claims the account
      through a claim link.
paths:
  /plans/{id}/drafts/{draftId}:
    patch:
      tags:
        - Plans
      summary: Update plan draft
      description: >-
        Change a draft's prices per interval, trials, the interval shown first,
        countries with their currency and prices, and credit or balance rules,
        or undo single changes. Each block sent replaces that block; blocks left
        out stay as they are. Buyers and subscribers see nothing until the draft
        is published.
      operationId: update-plan-draft
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            Unique key used to safely retry this write for 24 hours without
            applying it twice.
          schema:
            type: string
            minLength: 1
            maxLength: 200
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: draftId
          in: path
          required: true
          schema:
            type: string
        - name: Commet-Version
          in: header
          required: false
          description: >-
            API version used by this reference. Send this header to select this
            contract explicitly.
          schema:
            type: string
            default: '2026-08-27'
          example: '2026-08-27'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                prices:
                  description: >-
                    Every interval the draft sells. An interval the draft sold
                    and this list leaves out is removed from the draft.
                  type: array
                  items:
                    type: object
                    properties:
                      billingInterval:
                        type: string
                        enum:
                          - weekly
                          - monthly
                          - quarterly
                          - semiannual
                          - yearly
                          - one_time
                      price:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                        description: USD price in cents.
                      includedCredits:
                        anyOf:
                          - type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          - type: 'null'
                      includedBalance:
                        anyOf:
                          - type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          - type: 'null'
                      trialDays:
                        description: Days of trial on this price. Null removes the trial.
                        anyOf:
                          - type: integer
                            minimum: 1
                            maximum: 730
                          - type: 'null'
                      trialRequiresPaymentMethod:
                        type: boolean
                      isDefault:
                        description: >-
                          Show this interval first at checkout and in pricing
                          tables.
                        type: boolean
                    required:
                      - billingInterval
                      - price
                countries:
                  description: >-
                    Every country with its own currency or prices. A country the
                    draft sold and this list leaves out is removed. A country
                    missing a price blocks publishing.
                  type: array
                  items:
                    type: object
                    properties:
                      country:
                        type: string
                        minLength: 2
                        maxLength: 2
                        description: ISO country code.
                      currency:
                        type: string
                        description: The currency the country pays in, USD included.
                      exchangeRate:
                        description: >-
                          Local units per USD for prices that follow the USD
                          base. USD defaults to 1.
                        anyOf:
                          - type: number
                            exclusiveMinimum: 0
                          - type: 'null'
                      prices:
                        type: array
                        items:
                          anyOf:
                            - type: object
                              properties:
                                billingInterval:
                                  type: string
                                  enum:
                                    - weekly
                                    - monthly
                                    - quarterly
                                    - semiannual
                                    - yearly
                                    - one_time
                                price:
                                  type: integer
                                  minimum: 0
                                  maximum: 9007199254740991
                                  description: >-
                                    The price set by hand, in the currency's
                                    minor unit.
                                includedBalance:
                                  description: >-
                                    The balance included each period in this
                                    country, in the currency's minor unit.
                                    Required when the plan's price includes a
                                    balance.
                                  type: integer
                                  minimum: 0
                                  maximum: 9007199254740991
                              required:
                                - billingInterval
                                - price
                            - type: object
                              properties:
                                billingInterval:
                                  type: string
                                  enum:
                                    - weekly
                                    - monthly
                                    - quarterly
                                    - semiannual
                                    - yearly
                                    - one_time
                                followBase:
                                  type: boolean
                                  const: true
                                  description: Follow the USD base at the exchange rate.
                              required:
                                - billingInterval
                                - followBase
                      topUpMinimum:
                        description: >-
                          Smallest balance top-up in this country, in the
                          currency's minor unit. Null follows the USD minimum at
                          the exchange rate; left out keeps it.
                        anyOf:
                          - type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          - type: 'null'
                      maxPlanBalance:
                        description: >-
                          Most unused plan balance that rolls over in this
                          country. Null follows the USD cap at the exchange
                          rate; left out keeps it.
                        anyOf:
                          - type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          - type: 'null'
                      planBalanceLimit:
                        description: >-
                          Most plan balance spent per limit interval in this
                          country. Null follows the USD limit at the exchange
                          rate; left out keeps it.
                        anyOf:
                          - type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          - type: 'null'
                      addonPrices:
                        description: >-
                          What the country pays for each add-on the draft sells.
                          Left out keeps the country's add-on prices; sent, it
                          replaces them, and add-ons not listed follow the USD
                          price.
                        type: array
                        items:
                          anyOf:
                            - type: object
                              properties:
                                addonId:
                                  type: string
                                price:
                                  type: integer
                                  minimum: 0
                                  maximum: 9007199254740991
                                  description: >-
                                    The add-on's price set by hand, in the
                                    currency's minor unit.
                              required:
                                - addonId
                                - price
                            - type: object
                              properties:
                                addonId:
                                  type: string
                                followBase:
                                  type: boolean
                                  const: true
                                  description: >-
                                    Follow the add-on's USD price at the
                                    exchange rate.
                              required:
                                - addonId
                                - followBase
                      creditPackPrices:
                        description: >-
                          What the country pays for each credit pack the draft
                          sells. Left out keeps the country's pack prices; sent,
                          it replaces them, and packs not listed follow the USD
                          price.
                        type: array
                        items:
                          anyOf:
                            - type: object
                              properties:
                                creditPackId:
                                  type: string
                                price:
                                  type: integer
                                  minimum: 0
                                  maximum: 9007199254740991
                                  description: >-
                                    The pack's price set by hand, in the
                                    currency's minor unit.
                              required:
                                - creditPackId
                                - price
                            - type: object
                              properties:
                                creditPackId:
                                  type: string
                                followBase:
                                  type: boolean
                                  const: true
                                  description: >-
                                    Follow the pack's USD price at the exchange
                                    rate.
                              required:
                                - creditPackId
                                - followBase
                    required:
                      - country
                      - currency
                      - prices
                rules:
                  description: Credit or balance rules; fields left out stay as they are.
                  type: object
                  properties:
                    freeIncludedCredits:
                      description: Credits a free plan includes each month.
                      anyOf:
                        - type: integer
                          minimum: 0
                          maximum: 2147483647
                        - type: 'null'
                    freeIncludedBalance:
                      description: Balance a free plan includes each month, in cents.
                      anyOf:
                        - type: integer
                          minimum: 0
                          maximum: 2147483647
                        - type: 'null'
                    unusedPlanCredits:
                      type: string
                      enum:
                        - expire
                        - roll_over
                    maxPlanCredits:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 2147483647
                        - type: 'null'
                    planCreditLimit:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 9007199254740991
                        - type: 'null'
                    planCreditLimitInterval:
                      anyOf:
                        - type: string
                          enum:
                            - day
                            - week
                        - type: 'null'
                    unusedPlanBalance:
                      type: string
                      enum:
                        - expire
                        - roll_over
                    maxPlanBalance:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 2147483647
                        - type: 'null'
                    planBalanceLimit:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 9007199254740991
                        - type: 'null'
                    planBalanceLimitInterval:
                      anyOf:
                        - type: string
                          enum:
                            - day
                            - week
                        - type: 'null'
                    blockOnExhaustion:
                      type: boolean
                    purchasesEnabled:
                      type: boolean
                    creditPurchaseUnitPrice:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 9007199254740991
                        - type: 'null'
                    creditPurchaseMinimum:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 9007199254740991
                        - type: 'null'
                    topUpMinimum:
                      anyOf:
                        - type: integer
                          minimum: 1
                          maximum: 9007199254740991
                        - type: 'null'
                undo:
                  description: >-
                    Change keys to put back as the version the draft started
                    from had them.
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: Success
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
            RateLimit-Limit:
              description: Maximum number of requests allowed in the current window.
              schema:
                type: string
            RateLimit-Remaining:
              description: Requests remaining in the current window.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlanDraft'
              example:
                id: plr_d1r2a3f4
                fromVersionId: plr_9i0j1k2l
                changes:
                  - key: price:pp_1a2b3c4d
                    section: Price
                    country: null
                    label: Monthly price
                    before: $49.00
                    after: $59.00
                  - key: country:UY
                    section: Uruguay
                    country: UY
                    label: Currency
                    before: null
                    after: USD at 1 per USD
                createdAt: '2026-11-04T12:00:00.000Z'
                updatedAt: '2026-11-04T12:05:00.000Z'
                object: plan_draft
        '400':
          description: Bad request
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: validation_error
                  code: validation_error
                  message: The request contains an invalid parameter.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/validation_error.md
        '401':
          description: Unauthorized
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: authentication_error
                  code: unauthorized
                  message: A valid API key is required.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/unauthorized.md
        '403':
          description: Forbidden
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: authentication_error
                  code: forbidden
                  message: You do not have permission to perform this operation.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/forbidden.md
        '404':
          description: Not found
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: not_found_error
                  code: not_found
                  message: The requested resource was not found.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/not_found.md
        '409':
          description: Conflict
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: conflict_error
                  code: idempotency_in_progress
                  message: >-
                    A request with this idempotency key is still being
                    processed.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/idempotency_in_progress.md
        '429':
          description: Too many requests
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
            RateLimit-Limit:
              description: Maximum number of requests allowed in the current window.
              schema:
                type: string
            RateLimit-Remaining:
              description: Requests remaining in the current window.
              schema:
                type: string
            RateLimit-Reset:
              description: Seconds until the rate limit window resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: rate_limit_error
                  code: rate_limited
                  message: >-
                    Too many requests. Retry after the interval specified in the
                    Retry-After header.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/rate_limited.md
        '500':
          description: Internal server error
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: internal_error
                  code: internal_error
                  message: An unexpected error occurred while processing the request.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/internal_error.md
        '503':
          description: Service unavailable
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: internal_error
                  code: idempotency_unavailable
                  message: >-
                    Idempotency storage is temporarily unavailable. Retry with
                    the same idempotency key.
                  doc_url: >-
                    https://commet.co/docs/api-reference/2026-08-27/errors/idempotency_unavailable.md
components:
  headers:
    RequestId:
      description: >-
        Server-generated identifier that correlates this response with Platform
        logs.
      schema:
        type: string
        format: uuid
  schemas:
    PlanDraft:
      type: object
      properties:
        id:
          type: string
          description: Public plan draft ID.
        fromVersionId:
          type: string
          description: The version the draft started from.
        changes:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
                description: Identifies the change; send it to undo just this change.
              section:
                type: string
                description: >-
                  Where the change is: Price, Trial, a rules section, Add-ons,
                  or a country.
              country:
                description: ISO country code when the change belongs to one country.
                type:
                  - string
                  - 'null'
              label:
                type: string
                description: What changed, such as Monthly price.
              before:
                description: The value before, formatted.
                type:
                  - string
                  - 'null'
              after:
                description: The value now, formatted.
                type:
                  - string
                  - 'null'
            required:
              - key
              - section
              - country
              - label
              - before
              - after
            additionalProperties: false
          description: What the draft changes against the version it started from.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        object:
          type: string
          const: plan_draft
        livemode:
          type: boolean
      required:
        - id
        - fromVersionId
        - changes
        - createdAt
        - updatedAt
        - object
        - livemode
      additionalProperties: false
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
            code:
              type: string
            message:
              type: string
            param:
              type: string
            details: {}
            doc_url:
              type: string
          required:
            - type
            - code
            - message
            - doc_url
          additionalProperties: false
      required:
        - error
      additionalProperties: false
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````

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