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

# Create a subscription

> Creates the subscription and its first invoice, and sends the invoice to Xero, under the same rules as the New Subscription form. **`Idempotency-Key` is required**: a repeat of this request would otherwise be a second subscription and a second bill. A retry with the same key and body returns the first response. If Xero refuses the invoice the subscription still exists and the response is 201 with `invoice.xero.sync_status` of `failed`.

<Info>Requires the `subscriptions:write` scope. See [Authentication](/api-reference/authentication#scopes).</Info>


## OpenAPI

````yaml /api-reference/openapi.json post /v1/subscriptions
openapi: 3.1.0
info:
  title: Saasybill API
  version: 1.0.0
  description: >-
    Create and manage subscriptions in Saasybill from your own platform.


    **Authentication.** `Authorization: Bearer saasybill_live_…`. Create keys
    under Developer Settings.


    **Idempotency.** Send an `Idempotency-Key` on writes. It is required to
    create a subscription.


    **Webhooks.** Saasybill calls your URL when something changes. Events:
    `customer.created`, `customer.updated`, `customer.deleted`,
    `subscription.created`, `subscription.updated`, `subscription.ended`,
    `subscription.restored`, `subscription.deleted`, `invoice.created`,
    `invoice.updated`, `invoice.paid`, `invoice.voided`, `invoice.deleted`,
    `credit_note.created`, `credit_note.updated`, `credit_note.voided`,
    `credit_note.deleted`. Each request is signed: `Saasybill-Signature: t=<unix
    seconds>,v1=<hex>`, where `v1` is `HMAC-SHA256(secret, "<t>.<raw body>")`.
    Reject a `t` more than five minutes old. Deliveries are at-least-once,
    retried for about 20 hours, and unordered: de-duplicate on the event `id`.
    Changes are detected about once a minute, so an event can arrive up to a
    minute late, and changes inside one minute are combined.


    **Testing.** Create a sandbox under Developer Settings → Configuration,
    connect it to a Xero Demo Company, and use a test key (`saasybill_test_…`)
    created inside it. A test key works only in its sandbox, which sends no
    emails and is never billed. Your plans, customers and subscriptions can be
    copied into the sandbox when it is created or reset, and its test clock can
    be advanced to see renewals without waiting. `GET /v1/organisation` returns
    `livemode: false` for a sandbox.
servers:
  - url: https://api.saasybill.com
    description: Production
security: []
tags:
  - name: Organisation
    description: The organisation an API key belongs to.
  - name: Customers
    description: >-
      Customers are synced from Xero. Create one only where the organisation
      allows it.
  - name: Plans
    description: Read the pricing plans you can sell.
  - name: Charges
    description: Read the one-off fees that can be added to a new subscription.
  - name: Subscriptions
    description: Create subscriptions, change units, and end or restore them.
  - name: Invoices
    description: Read the invoices Saasybill raises in Xero.
  - name: Credit notes
    description: >-
      Read the credit notes Saasybill raises in Xero, and where their credit was
      applied.
  - name: Usage
    description: Report the usage that is billed in arrears against a subscription.
paths:
  /v1/subscriptions:
    post:
      tags:
        - Subscriptions
      summary: Create a subscription
      description: >-
        Creates the subscription and its first invoice, and sends the invoice to
        Xero, under the same rules as the New Subscription form.
        **`Idempotency-Key` is required**: a repeat of this request would
        otherwise be a second subscription and a second bill. A retry with the
        same key and body returns the first response. If Xero refuses the
        invoice the subscription still exists and the response is 201 with
        `invoice.xero.sync_status` of `failed`.
      operationId: post_v1_subscriptions
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          description: >-
            1 to 255 printable characters. A retry with the same key and body
            returns the first response.
          schema:
            type: string
            minLength: 1
            maxLength: 255
            example: signup_8f3a2c1d
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                customer:
                  description: The Saasybill customer id. Give this or `customer_code`.
                  type: string
                  minLength: 1
                  maxLength: 100
                customer_code:
                  type: string
                  description: >-
                    The organisation's own reference for the customer. Unique
                    per organisation.
                create_customer:
                  description: >-
                    Create the customer in Xero if no customer has
                    `customer_code`. Needs the organisation to have allowed it.
                  type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 255
                      description: The name the contact is created under in Xero.
                    first_name:
                      description: The contact person's first name, in Xero.
                      anyOf:
                        - type: string
                          maxLength: 255
                        - type: 'null'
                    last_name:
                      description: The contact person's last name, in Xero.
                      anyOf:
                        - type: string
                          maxLength: 255
                        - type: 'null'
                    email:
                      anyOf:
                        - type: string
                          maxLength: 255
                          format: email
                          pattern: >-
                            ^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
                        - type: 'null'
                  required:
                    - name
                  additionalProperties: false
                plan:
                  description: The plan id. Give this or `plan_code`.
                  type: string
                  minLength: 1
                  maxLength: 100
                plan_code:
                  type: string
                  minLength: 1
                  maxLength: 100
                units:
                  description: >-
                    Not for a plan with no units: a flat fee plan, or one with
                    no recurring fee.
                  type: integer
                  minimum: 0
                  maximum: 999999999
                flat_fee_price:
                  description: Only where the plan allows its price to be overridden.
                  anyOf:
                    - type: string
                      minLength: 1
                      maxLength: 20
                    - type: number
                start_date:
                  description: Defaults to today in the organisation's timezone.
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                end_after_cycles:
                  anyOf:
                    - type: integer
                      minimum: 1
                      maximum: 1000
                    - type: 'null'
                discount_percent:
                  description: 0 to 100. Defaults to 0.
                  anyOf:
                    - type: string
                      minLength: 1
                      maxLength: 20
                    - type: number
                label:
                  anyOf:
                    - type: string
                      maxLength: 255
                    - type: 'null'
                invoice_reference:
                  anyOf:
                    - type: string
                      maxLength: 255
                    - type: 'null'
                minimum_units:
                  anyOf:
                    - type: integer
                      minimum: 0
                      maximum: 999999999
                    - type: 'null'
                minimum_invoice_amount:
                  anyOf:
                    - anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 20
                        - type: number
                    - type: 'null'
                invoice_due_days:
                  anyOf:
                    - type: integer
                      minimum: 1
                      maximum: 365
                    - type: 'null'
                meter_minimums:
                  description: >-
                    Raise the minimum of meters the plan bills, for this
                    subscription only. A meter the plan does not bill is
                    refused, and a meter named twice.
                  maxItems: 50
                  type: array
                  items:
                    type: object
                    properties:
                      meter:
                        description: The Saasybill meter id. Give this or `meter_code`.
                        type: string
                        minLength: 1
                        maxLength: 100
                      meter_code:
                        type: string
                        description: >-
                          The meter's ID as shown in Saasybill, such as
                          `api_calls`.
                      minimum_units:
                        type: integer
                        minimum: 0
                        maximum: 999999999
                        description: >-
                          The least a period bills for this meter on this
                          subscription. Not below the plan's minimum for it.
                    required:
                      - minimum_units
                    additionalProperties: false
                cpi_enabled:
                  type: boolean
                  description: >-
                    Raise the plan price, and the rates of any meters the plan
                    bills, by the consumer price index at each renewal. Usage is
                    billed at the rates of the period it was used in. Annual
                    plans only, and only where the organisation's country has a
                    CPI figure or a manual rate. Defaults to false. Cannot be
                    changed through the API after creation.
                charges:
                  maxItems: 50
                  type: array
                  items:
                    type: object
                    properties:
                      charge:
                        type: string
                        minLength: 1
                        maxLength: 100
                      price:
                        description: >-
                          Only where the charge allows its price to be
                          overridden.
                        anyOf:
                          - type: string
                            minLength: 1
                            maxLength: 20
                          - type: number
                      apply_discount:
                        type: boolean
                    required:
                      - charge
                    additionalProperties: false
              additionalProperties: false
            examples:
              Per unit plan, by code:
                summary: Per unit plan, by code
                description: >-
                  The usual signup: find the customer and the plan by your own
                  codes.
                value:
                  customer_code: ACME-001
                  plan_code: TEAM-MONTHLY
                  units: 10
                  start_date: '2026-09-30'
                  discount_percent: '10'
                  label: Acme � Team plan
                  invoice_reference: PO-4471
              With a one-off charge:
                summary: With a one-off charge
                description: >-
                  Bill a charge once, on the first invoice. Charges are sent by
                  id. The second charge overrides its price.
                value:
                  customer_code: ACME-001
                  plan_code: TEAM-MONTHLY
                  units: 25
                  charges:
                    - charge: e2a7d5c8-91b3-4d16-a0f4-7c8b6e5d3a22
                      apply_discount: false
                    - charge: a8c4e1f7-3d92-4b05-8e6a-1c7f9d2b5e30
                      price: '300.00'
                      apply_discount: true
              Flat fee, fixed term:
                summary: Flat fee, fixed term
                description: >-
                  A flat fee plan takes no units. Set flat_fee_price only where
                  the plan allows its price to be overridden.
                value:
                  customer: 3b9f1c1e-6a52-4c0e-9d7e-1f6f2f0b7a11
                  plan: 2f6b9d3a-8c14-4e75-a0b2-6d1e7f3c9a48
                  flat_fee_price: '2400.00'
                  end_after_cycles: 12
                  invoice_due_days: 14
              Annual plan with CPI increases:
                summary: Annual plan with CPI increases
                description: >-
                  Sets cpi_enabled to raise the plan price by CPI at each
                  renewal. Annual plans only, and the organisation must have CPI
                  price adjustments switched on.
                value:
                  customer_code: ACME-001
                  plan_code: TEAM-ANNUAL
                  units: 10
                  cpi_enabled: true
              Create the customer if missing:
                summary: Create the customer if missing
                description: >-
                  Uses customer_code, and creates the customer in Xero if no
                  customer has that code. Needs the organisation to have allowed
                  it.
                value:
                  customer_code: NORTH-100
                  create_customer:
                    name: Northwind Traders
                    email: ap@northwind.example
                  plan_code: TEAM-MONTHLY
                  units: 5
              Usage plan with a raised meter minimum:
                summary: Usage plan with a raised meter minimum
                description: >-
                  For a plan that bills meters. Raises the minimum of one meter
                  for this subscription only, never below the plan’s own. A plan
                  with no recurring fee takes no units.
                value:
                  customer_code: ACME-001
                  plan_code: API-USAGE
                  meter_minimums:
                    - meter_code: api_calls
                      minimum_units: 10000
      responses:
        '201':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    const: subscription
                  customer:
                    type: string
                  customer_code:
                    type:
                      - string
                      - 'null'
                  plan:
                    type: string
                  status:
                    type: string
                    enum:
                      - pending
                      - active
                      - complete
                      - ended
                  currency:
                    type: string
                  interval:
                    type: object
                    properties:
                      unit:
                        type: string
                        enum:
                          - day
                          - week
                          - month
                          - year
                      count:
                        type: integer
                    required:
                      - unit
                      - count
                    additionalProperties: false
                  timezone:
                    type: string
                  start_date:
                    type: string
                    description: YYYY-MM-DD, in the subscription's own timezone.
                  renewal_date:
                    anyOf:
                      - type: string
                        description: YYYY-MM-DD, in the subscription's own timezone.
                      - type: 'null'
                  end_date:
                    anyOf:
                      - type: string
                        description: YYYY-MM-DD, in the subscription's own timezone.
                      - type: 'null'
                  units:
                    type: integer
                  minimum_units:
                    type: integer
                  discount_percent:
                    type: string
                    description: A decimal string, e.g. "19.9900".
                  cancel_at_period_end:
                    type: boolean
                  end_after_cycles:
                    anyOf:
                      - type: integer
                      - type: 'null'
                  label:
                    type:
                      - string
                      - 'null'
                  invoice_reference:
                    type:
                      - string
                      - 'null'
                  renewal_value:
                    type: string
                    description: >-
                      What the next period is certain to bill: the plan at its
                      current units, the add-ons, and the minimum units of each
                      meter the plan bills, net of the discount. Usage above the
                      meter minimums is not included; see `usage_value`.
                  usage_value:
                    type: string
                    description: >-
                      The average, over the last three closed usage periods, of
                      what each billed for usage above the meter minimums, net
                      of the discount. An estimate at the plan's current meter
                      prices, and never part of `renewal_value`. 0 until a usage
                      period has closed, and for a plan that bills no meter.
                  usage_value_annual:
                    type: string
                    description: '`usage_value` times the periods in a year.'
                  minimum_usage_value:
                    type: string
                    description: >-
                      The part of `renewal_value` that is the meter minimums,
                      net of the discount. 0 for a plan that bills no meter.
                  meters:
                    type: array
                    items:
                      type: object
                      properties:
                        meter:
                          type: string
                          description: The Saasybill meter id.
                        meter_code:
                          type: string
                        name:
                          type: string
                        minimum_units:
                          type: integer
                          description: >-
                            The minimum in force: this subscription's own where
                            it set one, never below the plan's.
                        plan_minimum_units:
                          type: integer
                          description: The plan's minimum for the meter.
                      required:
                        - meter
                        - meter_code
                        - name
                        - minimum_units
                        - plan_minimum_units
                      additionalProperties: false
                    description: >-
                      The meters the subscription's plan bills for, with the
                      minimum each is billed at.
                  cpi_enabled:
                    type: boolean
                    description: Whether the price rises with CPI at each renewal.
                  created:
                    type: string
                    format: date-time
                    description: ISO 8601, UTC.
                  invoice:
                    anyOf:
                      - type: object
                        properties:
                          id:
                            type: string
                          object:
                            type: string
                            const: invoice
                          customer:
                            type: string
                          subscription:
                            type:
                              - string
                              - 'null'
                          number:
                            description: Xero's invoice number, once it is in Xero.
                            type:
                              - string
                              - 'null'
                          reference:
                            type:
                              - string
                              - 'null'
                          status:
                            type: string
                            enum:
                              - draft
                              - awaiting_approval
                              - approved
                              - paid
                              - voided
                              - deleted
                              - not_in_external
                          currency:
                            type: string
                          invoice_date:
                            type: string
                            format: date-time
                            description: ISO 8601, UTC.
                          due_date:
                            anyOf:
                              - type: string
                                format: date-time
                                description: ISO 8601, UTC.
                              - type: 'null'
                          subtotal:
                            type: string
                            description: Excluding tax.
                          total:
                            type: string
                            description: Including tax, as Xero returns it.
                          credit_note_amount:
                            type: string
                            description: A decimal string, e.g. "19.9900".
                          amount_paid:
                            anyOf:
                              - type: string
                                description: A decimal string, e.g. "19.9900".
                              - type: 'null'
                          sent:
                            type: boolean
                          xero:
                            type: object
                            properties:
                              sync_status:
                                type: string
                                enum:
                                  - synced
                                  - failed
                                  - pending
                                description: >-
                                  `failed` means the invoice exists here and
                                  Xero refused it; the subscription that raised
                                  it was still created.
                              invoice_id:
                                type:
                                  - string
                                  - 'null'
                              sync_error:
                                type:
                                  - string
                                  - 'null'
                            required:
                              - sync_status
                              - invoice_id
                              - sync_error
                            additionalProperties: false
                          lines:
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  type: string
                                type:
                                  anyOf:
                                    - type: string
                                      enum:
                                        - subscription
                                        - addon
                                        - charge
                                        - usage
                                    - type: 'null'
                                  description: >-
                                    What the line bills for. `usage` is metered
                                    usage, one line per meter per billing
                                    period.
                                revenue_type:
                                  anyOf:
                                    - type: string
                                      enum:
                                        - new_subscription
                                        - expansion
                                        - renewal
                                        - usage
                                    - type: 'null'
                                  description: >-
                                    The revenue bucket the line falls in.
                                    Metered usage is `usage`, never `renewal`.
                                    Null where it was not recorded.
                                meter:
                                  description: >-
                                    The Saasybill meter id a `usage` line bills.
                                    Null on every other line.
                                  type:
                                    - string
                                    - 'null'
                                usage_quantity:
                                  description: >-
                                    The quantity a `usage` line was priced for,
                                    as a decimal string, after the meter's
                                    minimum. `units` is this rounded up. Null on
                                    every other line.
                                  type:
                                    - string
                                    - 'null'
                                name:
                                  type:
                                    - string
                                    - 'null'
                                description:
                                  type:
                                    - string
                                    - 'null'
                                units:
                                  anyOf:
                                    - type: integer
                                    - type: 'null'
                                amount:
                                  type: string
                                  description: A decimal string, e.g. "19.9900".
                                discount_amount:
                                  type: string
                                  description: A decimal string, e.g. "19.9900".
                                charge_amount:
                                  type: string
                                  description: >-
                                    What is billed: `amount` less
                                    `discount_amount`.
                                effective_date:
                                  anyOf:
                                    - type: string
                                      format: date-time
                                      description: ISO 8601, UTC.
                                    - type: 'null'
                              required:
                                - id
                                - type
                                - revenue_type
                                - meter
                                - usage_quantity
                                - name
                                - description
                                - units
                                - amount
                                - discount_amount
                                - charge_amount
                                - effective_date
                              additionalProperties: false
                          created:
                            type: string
                            format: date-time
                            description: ISO 8601, UTC.
                        required:
                          - id
                          - object
                          - customer
                          - subscription
                          - number
                          - reference
                          - status
                          - currency
                          - invoice_date
                          - due_date
                          - subtotal
                          - total
                          - credit_note_amount
                          - amount_paid
                          - sent
                          - xero
                          - created
                        additionalProperties: false
                      - type: 'null'
                    description: >-
                      The first invoice. Null in setup mode, where none is
                      raised, and for a plan with no recurring fee sold with no
                      add-ons or charges, which has nothing to bill for its
                      first period. Check `xero.sync_status`.
                required:
                  - id
                  - object
                  - customer
                  - customer_code
                  - plan
                  - status
                  - currency
                  - interval
                  - timezone
                  - start_date
                  - renewal_date
                  - end_date
                  - units
                  - minimum_units
                  - discount_percent
                  - cancel_at_period_end
                  - end_after_cycles
                  - label
                  - invoice_reference
                  - renewal_value
                  - usage_value
                  - usage_value_annual
                  - minimum_usage_value
                  - meters
                  - cpi_enabled
                  - created
                  - invoice
                additionalProperties: false
              example:
                id: 9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33
                object: subscription
                customer: 3b9f1c1e-6a52-4c0e-9d7e-1f6f2f0b7a11
                customer_code: ACME-001
                plan: b6c1e0a4-2f7d-4a61-8f0c-5d3e9a7b2c44
                status: active
                currency: AUD
                interval:
                  unit: month
                  count: 1
                timezone: Australia/Sydney
                start_date: '2026-09-30'
                renewal_date: '2026-10-30'
                end_date: null
                units: 10
                minimum_units: 5
                discount_percent: '10.00'
                cancel_at_period_end: false
                end_after_cycles: null
                label: Acme � Team plan
                invoice_reference: PO-4471
                renewal_value: '108.0000'
                usage_value: '0.0000'
                usage_value_annual: '0.0000'
                minimum_usage_value: '0.0000'
                meters: []
                cpi_enabled: false
                created: '2026-09-30T04:12:00.000Z'
                invoice:
                  id: 5f8a3c9d-7e21-4b04-9c6d-0a2b4e8f1d55
                  object: invoice
                  customer: 3b9f1c1e-6a52-4c0e-9d7e-1f6f2f0b7a11
                  subscription: 9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33
                  number: INV-0042
                  reference: PO-4471
                  status: awaiting_approval
                  currency: AUD
                  invoice_date: '2026-09-29T14:00:00.000Z'
                  due_date: '2026-10-29T13:00:00.000Z'
                  subtotal: '558.0000'
                  total: '613.8000'
                  credit_note_amount: '0.0000'
                  amount_paid: null
                  sent: false
                  xero:
                    sync_status: synced
                    invoice_id: f0e9d8c7-b6a5-4f43-9210-fedcba987654
                    sync_error: null
                  lines:
                    - id: 0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c77
                      type: subscription
                      revenue_type: new_subscription
                      meter: null
                      usage_quantity: null
                      name: Team
                      description: Team � 10 seats
                      units: 10
                      amount: '120.0000'
                      discount_amount: '12.0000'
                      charge_amount: '108.0000'
                      effective_date: '2026-09-29T14:00:00.000Z'
                    - id: 1b2c3d4e-5f6a-4b7c-9d8e-0f1a2b3c4d88
                      type: charge
                      revenue_type: new_subscription
                      meter: null
                      usage_quantity: null
                      name: Onboarding
                      description: One-off setup and training
                      units: null
                      amount: '450.0000'
                      discount_amount: '0.0000'
                      charge_amount: '450.0000'
                      effective_date: '2026-09-29T14:00:00.000Z'
                  created: '2026-09-30T04:12:01.000Z'
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimit-Reset'
        '401':
          description: The key is missing, malformed, revoked or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: authentication_error
                  code: invalid_api_key
                  message: 'Provide a valid API key as `Authorization: Bearer <key>`.'
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
        '403':
          description: >-
            The key lacks the scope, is a test key, or the organisation has not
            allowed this.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: permission_error
                  code: insufficient_scope
                  message: This API key does not have the `subscriptions:write` scope.
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
        '404':
          description: No such object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: not_found
                  code: subscription_not_found
                  message: There is no subscription with that id.
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
        '409':
          description: >-
            The request conflicts with the current state, or with an earlier
            request using the same `Idempotency-Key`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: conflict
                  code: idempotency_conflict
                  message: >-
                    This `Idempotency-Key` was used with a different request.
                    Use a new key for a different request.
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
        '422':
          description: A field is missing or invalid. `error.param` names it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: invalid_request_error
                  code: invalid_parameter
                  message: '`units`: Invalid input: expected number, received string'
                  param: units
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
        '429':
          description: 'Rate limited: 120 requests a minute per key. See `Retry-After`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: rate_limit_error
                  code: rate_limited
                  message: Too many requests. Try again in 12 seconds.
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
        '500':
          description: >-
            Something went wrong on our side. Retry; quote `error.request_id` if
            it persists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: api_error
                  code: internal_error
                  message: >-
                    Something went wrong on our side. Retry the request; if it
                    keeps failing, quote the request id.
                  request_id: req_4f1a9c2e7b8d3a605e1c9f02
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
      security:
        - bearerAuth:
            - subscriptions:write
components:
  headers:
    Request-Id:
      description: A unique id for the request. Quote it when you contact support.
      schema:
        type: string
        example: req_4f1a9c2e7b8d3a605e1c9f02
    RateLimit-Limit:
      description: Requests allowed per minute for this key.
      schema:
        type: integer
        example: 120
    RateLimit-Remaining:
      description: Requests left in the current window.
      schema:
        type: integer
        example: 117
    RateLimit-Reset:
      description: Seconds until the oldest counted request stops counting.
      schema:
        type: integer
        example: 41
  schemas:
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              enum:
                - authentication_error
                - permission_error
                - invalid_request_error
                - not_found
                - conflict
                - rate_limit_error
                - api_error
            code:
              type: string
              description: Stable. Branch on this, never on `message`.
            message:
              type: string
            param:
              type: string
            request_id:
              type: string
          required:
            - type
            - code
            - message
            - request_id
          additionalProperties: false
      required:
        - error
      additionalProperties: false
      description: >-
        Every failed request answers with this shape. Branch on `error.code`,
        never on `error.message`.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        An API key. Its scopes decide what it may call: `customers:read` (List
        and look up customers.) `customers:write` (Create customers, and Xero
        contacts where the organisation allows it.) `catalogue:read` (List plans
        and charges.) `subscriptions:read` (List and look up subscriptions.)
        `subscriptions:write` (Create subscriptions, change units, end and
        restore them.) `invoices:read` (List and look up invoices.)
        `credit_notes:read` (List and look up credit notes, and where their
        credit was applied.)

````

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