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

# Update a draft invoice

> Updates a draft. Send only the fields to change; `items`, when sent, replaces every line (line ids change). Once finalized an invoice is frozen and this returns `409`. Emits `invoice.updated`.

**Scope:** `invoices:write` + `business:read` + `clients:read`



## OpenAPI

````yaml /openapi.json patch /invoices/{id}
openapi: 3.1.0
info:
  title: Invoice-AI API
  version: 1.0.0
  description: >-
    Stripe-shaped invoicing over HTTP: customers, products, prices, invoices and
    invoice items, with `cus_…`, `prod_…`, `price_…`, `in_…` and `ii_…` ids.


    - **Auth:** `Authorization: Bearer inv_live_…`, with per-key scopes.

    - **Envelope:** JSON bodies; responses wrap the resource in `{ "data": … }`;
    lists add `next_cursor`.

    - **Money:** integer minor units of the currency everywhere (`250000` is
    $2,500.00; ¥5,000 is `5000`).

    - **Errors:** RFC 9457 `application/problem+json` — branch on `code`.

    - **Idempotency:** operations that spend an invoice number, email or record
    payment require an `Idempotency-Key`.

    - **Rate limits:** 120 requests/minute per key. Sending email: 10/hour per
    key and 50/hour per account. See the `RateLimit-*` headers.
  contact:
    name: Invoice-AI support
    url: https://invoice.horizonpay.co
servers:
  - url: https://invoice.horizonpay.co/api/v1
    description: Production
security:
  - apiKey: []
tags:
  - name: Business
    x-displayName: Business
    description: >-
      Your business profile — the issuer printed on every invoice. Read-only
      over the API; edit it in Settings.
  - name: Customers
    x-displayName: Customers
    description: >-
      The people and companies you bill. Every invoice references a customer by
      `cus_…` id. Customers are archived rather than deleted, so issued invoices
      keep naming who they were billed to.
  - name: Products
    x-displayName: Products
    description: >-
      The things you sell. A product carries a name and description; amounts
      live on its prices. Archiving sets `active: false` and keeps history
      intact.
  - name: Prices
    x-displayName: Prices
    description: >-
      Ways to charge for a product: an amount in integer minor units and a
      currency, one-time or recurring. Bill a price on an invoice line with
      `price: "price_…"`.
  - name: Invoices
    x-displayName: Invoices
    description: >-
      Invoices move `draft` → `open` (finalize assigns a permanent, consecutive
      number) → `paid`, or `open` → `void`. Drafts are freely editable and
      deletable; finalized invoices are frozen. `overdue` is an open invoice
      past its due date, derived at read time. Operations that spend a number,
      send email or record payment require an `Idempotency-Key`.
  - name: Invoice items
    x-displayName: Invoice items
    description: >-
      Individual lines of an invoice. Add or remove lines on a draft one at a
      time; totals are recomputed server-side and the whole invoice is returned.
  - name: Webhook endpoints
    x-displayName: Webhook endpoints
    description: >-
      Register https endpoints to receive invoice events (`invoice.created`,
      `invoice.finalized`, `invoice.paid`, …). Deliveries are signed per
      [Standard Webhooks](https://www.standardwebhooks.com/) with `webhook-id`,
      `webhook-timestamp` and `webhook-signature` headers (HMAC-SHA256 over
      `{id}.{timestamp}.{body}`); failed deliveries are retried with backoff.
paths:
  /invoices/{id}:
    patch:
      tags:
        - Invoices
      summary: Update a draft invoice
      description: >-
        Updates a draft. Send only the fields to change; `items`, when sent,
        replaces every line (line ids change). Once finalized an invoice is
        frozen and this returns `409`. Emits `invoice.updated`.


        **Scope:** `invoices:write` + `business:read` + `clients:read`
      operationId: updateInvoice
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: The draft, `in_…` or UUID.
            examples:
              - in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8
          required: true
          description: The draft, `in_…` or UUID.
      requestBody:
        required: true
        content:
          application/json:
            example:
              due_date: '2026-10-22'
              description: Consulting retainer — net 30.
              footer: Thank you for your business.
            schema:
              $ref: '#/components/schemas/InvoiceUpdate'
      responses:
        '200':
          description: The updated draft, with lines.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              example:
                data:
                  id: in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8
                  object: invoice
                  number: null
                  status: draft
                  customer: cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6
                  currency: USD
                  collection_method: send_invoice
                  issue_date: '2026-09-22'
                  due_date: '2026-10-22'
                  description: Consulting retainer — net 30.
                  footer: Thank you for your business.
                  subtotal: 2550000
                  discount: 0
                  taxable: 2550000
                  tax: 0
                  total: 2550000
                  amount_due: 0
                  amount_in_words: Twenty Five Thousand Five Hundred USD Only
                  public_url_token: 2b7e4c1a-9f3d-4e68-8a5b-0d1c7f3e9a46
                  finalized_at: null
                  paid_at: null
                  voided_at: null
                  void_reason: null
                  created: '2026-09-22T09:30:00.000Z'
                  updated: '2026-09-22T09:45:00.000Z'
                  lines:
                    data:
                      - id: ii_Da4Vq9Ns2Kx7Bm3Yt8Rc1Lp6
                        object: invoiceitem
                        price: price_Jc5Tn8Wq1Ze6Ra3Ym9Ub2Gs7
                        product: prod_Hy7Rq2Lm9Xc4Vb8Nt3Kd6Pw1
                        description: Consulting retainer
                        quantity: 1
                        unit: NOS
                        unit_amount: 2500000
                        amount: 2500000
                        discount_percent: 0
                        tax_rate: 0
                        tax_amount: 0
                      - id: ii_Ew8Hz3Jc6Tq1Ms5Nv9Kb2Xr4
                        object: invoiceitem
                        price: null
                        product: null
                        description: Onboarding workshop
                        quantity: 1
                        unit: NOS
                        unit_amount: 50000
                        amount: 50000
                        discount_percent: 0
                        tax_rate: 0
                        tax_amount: 0
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Invoice'
                    description: The updated draft.
                required:
                  - data
                additionalProperties: false
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: >-
            No such invoice or customer. Another account's resource is also a
            `404`, so ids cannot be probed. Codes: `not_found`.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                not_found:
                  summary: Invoice not found.
                  value:
                    type: https://invoice.horizonpay.co/problems/not-found
                    title: Not found
                    status: 404
                    detail: Invoice not found.
                    instance: req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
                    code: not_found
        '409':
          description: 'The invoice is no longer a draft. Codes: `invalid_state`.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                invalid_state:
                  summary: This invoice has been finalized and can no longer be edited.
                  value:
                    type: https://invoice.horizonpay.co/problems/invalid-state
                    title: Invalid state for this operation
                    status: 409
                    detail: >-
                      This invoice has been finalized and can no longer be
                      edited.
                    instance: req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
                    code: invalid_state
        '422':
          description: 'The body failed validation. Codes: `validation`.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                validation:
                  summary: Some fields need attention.
                  value:
                    type: https://invoice.horizonpay.co/problems/validation
                    title: Validation failed
                    status: 422
                    detail: Some fields need attention.
                    instance: req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
                    code: validation
                    errors:
                      - path: due_date
                        message: Invalid ISO date
        '429':
          $ref: '#/components/responses/RateLimited'
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            curl -X PATCH
            https://invoice.horizonpay.co/api/v1/invoices/in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8
            \
              -H "Authorization: Bearer $INVOICE_AI_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "due_date": "2026-10-22",
                "description": "Consulting retainer — net 30.",
                "footer": "Thank you for your business."
              }'
        - lang: node
          label: Node.js
          source: >-
            import InvoiceAI from '@horizonpay/invoice-ai'


            const invoiceai = new InvoiceAI() // reads INVOICE_AI_API_KEY


            const invoice = await
            invoiceai.invoices.update('in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8', {
              due_date: '2026-10-22',
              description: 'Consulting retainer — net 30.',
              footer: 'Thank you for your business.',
            })

            console.log(invoice.due_date, invoice.total)
        - lang: python
          label: Python
          source: |-
            from invoice_ai import InvoiceAI

            client = InvoiceAI()  # reads INVOICE_AI_API_KEY

            invoice = client.invoices.update(
                "in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8",
                due_date="2026-10-22",
                description="Consulting retainer — net 30.",
                footer="Thank you for your business.",
            )
            print(invoice.due_date, invoice.total)
components:
  schemas:
    InvoiceUpdate:
      type: object
      properties:
        customer:
          description: >-
            Bill a different customer, `cus_…` or UUID. Omit to keep the current
            one.
          examples:
            - cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6
          type: string
          minLength: 1
        currency:
          description: ISO 4217 code. Defaults to your business currency.
          examples:
            - USD
          type: string
          minLength: 3
          maxLength: 3
          pattern: ^[A-Z]{3}$
        collection_method:
          description: Defaults to `send_invoice`. Informational today.
          examples:
            - send_invoice
          type: string
          enum:
            - charge_automatically
            - send_invoice
        due_date:
          description: Due date, `YYYY-MM-DD`. `""` clears it.
          examples:
            - '2026-10-22'
          anyOf:
            - type: string
              format: date
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$
            - type: string
              const: ''
        days_until_due:
          description: >-
            Alternative to `due_date` on create only: issue date + N days
            (0–365). Ignored on update.
          examples:
            - 30
          type: integer
          minimum: 0
          maximum: 365
        description:
          description: Notes printed on the invoice.
          type: string
        footer:
          description: Terms printed at the foot of the invoice.
          type: string
        items:
          description: >-
            The lines, at least one. On update, replaces every existing line;
            omit to keep them.
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineInput'
      description: >-
        Any subset of fields. Omitted fields keep their stored value; omit
        `items` to keep the lines.
    Invoice:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier, `in_…`.
          examples:
            - in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8
        object:
          type: string
          const: invoice
          description: Always `invoice`.
        number:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The invoice number, e.g. `INV-0042` (your prefix + a zero-padded
            counter). `null` until finalized — a draft has no number because
            none was spent on it.
          examples:
            - INV-0042
        status:
          type: string
          enum:
            - draft
            - open
            - paid
            - overdue
            - void
          description: >-
            `draft` → `open` (finalize) → `paid` (pay) or `void`. `overdue` is
            an open invoice past `due_date`; it is derived at read time and
            never stored.
          examples:
            - open
        customer:
          anyOf:
            - type: string
            - type: 'null'
          description: The billed customer, `cus_…`.
          examples:
            - cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6
        currency:
          type: string
          description: ISO 4217 currency code. Defaults to your business currency.
          examples:
            - USD
        collection_method:
          type: string
          enum:
            - charge_automatically
            - send_invoice
          description: >-
            How you intend to collect. Informational today; defaults to
            `send_invoice`.
        issue_date:
          type: string
          description: Issue date (ISO 8601 date). Set to the creation date.
          format: date
          examples:
            - '2026-09-22'
        due_date:
          anyOf:
            - type: string
            - type: 'null'
          description: Due date (ISO 8601 date), or `null`.
          format: date
          examples:
            - '2026-10-22'
        description:
          anyOf:
            - type: string
            - type: 'null'
          description: Notes printed on the invoice.
          examples:
            - Consulting retainer.
        footer:
          anyOf:
            - type: string
            - type: 'null'
          description: Terms printed at the foot of the invoice.
          examples:
            - Thank you for your business.
        subtotal:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Sum of quantity × unit_amount over all lines, before discount and
            tax. Integer minor units of the currency (`250000` is $2,500.00;
            ¥5,000 is `5000`).
          examples:
            - 2550000
        discount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Total discount across lines. Integer minor units of the currency
            (`250000` is $2,500.00; ¥5,000 is `5000`).
          examples:
            - 0
        taxable:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            `subtotal` − `discount`. Integer minor units of the currency
            (`250000` is $2,500.00; ¥5,000 is `5000`).
          examples:
            - 2550000
        tax:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Total tax across lines. Integer minor units of the currency
            (`250000` is $2,500.00; ¥5,000 is `5000`).
          examples:
            - 0
        total:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            `taxable` + `tax`. Integer minor units of the currency (`250000` is
            $2,500.00; ¥5,000 is `5000`).
          examples:
            - 2550000
        amount_due:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            What is still owed: `total` while `open` or `overdue`, otherwise 0.
            Integer minor units of the currency (`250000` is $2,500.00; ¥5,000
            is `5000`).
          examples:
            - 2550000
        amount_in_words:
          anyOf:
            - type: string
            - type: 'null'
          description: The total spelled out, as printed on the PDF.
          examples:
            - Twenty Five Thousand Five Hundred USD Only
        public_url_token:
          type: string
          description: >-
            Token of the public share link (`/i/{token}`). Anyone with it can
            view the invoice.
          examples:
            - 2b7e4c1a-9f3d-4e68-8a5b-0d1c7f3e9a46
        finalized_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          description: When the invoice was finalized, or `null`.
        paid_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          description: When the invoice was marked paid, or `null`.
        voided_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          description: When the invoice was voided, or `null`.
        void_reason:
          anyOf:
            - type: string
            - type: 'null'
          description: The reason given to `POST /invoices/{id}/void`.
        created:
          type: string
          description: When the invoice was created (ISO 8601).
          format: date-time
        updated:
          type: string
          description: When the invoice was last changed (ISO 8601).
          format: date-time
        lines:
          description: >-
            The invoice lines. Included when reading or writing a single
            invoice; omitted from list results and from the pay and void
            responses.
          type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/InvoiceItem'
              description: The lines, in order.
          required:
            - data
          additionalProperties: false
      required:
        - id
        - object
        - number
        - status
        - customer
        - currency
        - collection_method
        - issue_date
        - due_date
        - description
        - footer
        - subtotal
        - discount
        - taxable
        - tax
        - total
        - amount_due
        - amount_in_words
        - public_url_token
        - finalized_at
        - paid_at
        - voided_at
        - void_reason
        - created
        - updated
      additionalProperties: false
      description: 'An invoice: a draft, or a numbered document once finalized.'
    Problem:
      type: object
      properties:
        type:
          type: string
          description: >-
            A URI identifying the problem type:
            `https://invoice.horizonpay.co/problems/<code>` with underscores as
            hyphens.
          examples:
            - https://invoice.horizonpay.co/problems/invalid-state
        title:
          type: string
          description: Short, human-readable summary of the problem type.
          examples:
            - Invalid state for this operation
        status:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: The HTTP status code, repeated for convenience.
          examples:
            - 409
        detail:
          type: string
          description: >-
            Human-readable explanation of this occurrence. Wording may change —
            do not parse it.
          examples:
            - This invoice has been finalized and can no longer be edited.
        instance:
          type: string
          description: >-
            The request id (also sent as `X-Request-Id`), for correlating with
            our logs.
          examples:
            - req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
        code:
          type: string
          description: >-
            Stable machine-readable code. Branch on this, never on `detail`. One
            of: `validation`, `idempotency_mismatch`, `unauthorized`,
            `forbidden`, `not_found`, `invalid_state`, `conflict`,
            `idempotency_key_required`, `rate_limited`, `upstream_failed`,
            `internal_error`.
          examples:
            - invalid_state
        errors:
          description: Field-level problems. Present on `validation` errors only.
          type: array
          items:
            type: object
            properties:
              path:
                type: string
                description: Dot-path of the offending field, e.g. `items.0.unit_amount`.
                examples:
                  - email
              message:
                type: string
                description: What is wrong with it.
                examples:
                  - Enter a valid email
            required:
              - path
              - message
            additionalProperties: false
      required:
        - type
        - title
        - status
        - detail
        - instance
        - code
      additionalProperties: false
      description: >-
        An RFC 9457 problem details object, served as
        `application/problem+json`. Every non-2xx response uses this shape.
    InvoiceLineInput:
      type: object
      properties:
        price:
          description: >-
            A catalog price, `price_…` or UUID. Its product name, unit amount
            and tax rate fill any of `description`, `unit_amount`, `tax_rate`
            you omit. Its currency must match the invoice.
          examples:
            - price_Jc5Tn8Wq1Ze6Ra3Ym9Ub2Gs7
          type: string
        description:
          default: ''
          description: What you are billing for. Required unless `price` is given.
          examples:
            - Onboarding workshop
          type: string
        quantity:
          default: 1
          description: Quantity, greater than zero. Defaults to 1.
          examples:
            - 1
          type: number
          exclusiveMinimum: 0
        unit:
          default: NOS
          description: Unit of measure. Defaults to `NOS` (numbers).
          examples:
            - NOS
          type: string
          enum:
            - NOS
            - PCS
            - KGS
            - GMS
            - LTR
            - MTR
            - SQF
            - SQM
            - HRS
            - DAY
            - MON
            - BOX
            - SET
            - OTH
        unit_amount:
          description: >-
            Price per unit in integer minor units of the invoice currency.
            Required unless `price` is given.
          examples:
            - 50000
          type: integer
          minimum: 0
          maximum: 9007199254740991
        discount_percent:
          default: 0
          description: Discount percentage, 0–100, applied before tax. Defaults to 0.
          examples:
            - 0
          type: number
          minimum: 0
          maximum: 100
        tax_rate:
          description: >-
            Tax percentage, 0–100, added on top. Defaults to the price’s rate,
            or 0 on ad-hoc lines.
          examples:
            - 0
          type: number
          minimum: 0
          maximum: 100
      description: Either `price`, or `description` + `unit_amount`.
    InvoiceItem:
      type: object
      properties:
        id:
          type: string
          description: >-
            Unique identifier, `ii_…`. Lines get new ids whenever the draft is
            re-saved.
          examples:
            - ii_Da4Vq9Ns2Kx7Bm3Yt8Rc1Lp6
        object:
          type: string
          const: invoiceitem
          description: Always `invoiceitem`.
        price:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The `price_…` this line was billed from, or `null` for an ad-hoc
            line.
          examples:
            - price_Jc5Tn8Wq1Ze6Ra3Ym9Ub2Gs7
        product:
          anyOf:
            - type: string
            - type: 'null'
          description: The price's product, `prod_…`, or `null`.
          examples:
            - prod_Hy7Rq2Lm9Xc4Vb8Nt3Kd6Pw1
        description:
          type: string
          description: What is being billed. Defaults to the product name on priced lines.
          examples:
            - Consulting retainer
        quantity:
          type: number
          description: Quantity, greater than zero. May be fractional.
          examples:
            - 1
        unit:
          type: string
          description: >-
            Unit of measure: `NOS`, `PCS`, `KGS`, `GMS`, `LTR`, `MTR`, `SQF`,
            `SQM`, `HRS`, `DAY`, `MON`, `BOX`, `SET`, `OTH`.
          examples:
            - NOS
        unit_amount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Price per unit. Integer minor units of the currency (`250000` is
            $2,500.00; ¥5,000 is `5000`).
          examples:
            - 2500000
        amount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Line total after discount, including tax. Integer minor units of the
            currency (`250000` is $2,500.00; ¥5,000 is `5000`).
          examples:
            - 2500000
        discount_percent:
          type: number
          description: Discount percentage (0–100) applied before tax.
          examples:
            - 0
        tax_rate:
          type: number
          description: >-
            Tax percentage (0–100), exclusive — added on top of the discounted
            amount.
          examples:
            - 0
        tax_amount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Tax on this line. Integer minor units of the currency (`250000` is
            $2,500.00; ¥5,000 is `5000`).
          examples:
            - 0
      required:
        - id
        - object
        - price
        - product
        - description
        - quantity
        - unit
        - unit_amount
        - amount
        - discount_percent
        - tax_rate
        - tax_amount
      additionalProperties: false
      description: >-
        One line of an invoice. Totals are always recomputed server-side from
        the lines.
  headers:
    RequestId:
      required: true
      description: >-
        The request id: yours, if you sent `X-Request-Id` (up to 200
        characters), otherwise one we generated. Quote it to support.
      schema:
        type: string
        description: >-
          The request id: yours, if you sent `X-Request-Id` (up to 200
          characters), otherwise one we generated. Quote it to support.
        examples:
          - req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
    RateLimitLimit:
      required: true
      description: Requests allowed in the current window for this key and bucket.
      schema:
        type: integer
        minimum: -9007199254740991
        maximum: 9007199254740991
        description: Requests allowed in the current window for this key and bucket.
        examples:
          - 120
    RateLimitRemaining:
      required: true
      description: Requests left in the current window.
      schema:
        type: integer
        minimum: -9007199254740991
        maximum: 9007199254740991
        description: Requests left in the current window.
        examples:
          - 119
    RateLimitReset:
      required: true
      description: Unix time (seconds) at which the window resets.
      schema:
        type: integer
        minimum: -9007199254740991
        maximum: 9007199254740991
        description: Unix time (seconds) at which the window resets.
        examples:
          - 1789371294
    RetryAfter:
      required: true
      description: Seconds to wait before retrying.
      schema:
        type: integer
        minimum: -9007199254740991
        maximum: 9007199254740991
        description: Seconds to wait before retrying.
        examples:
          - 42
  responses:
    Unauthorized:
      description: >-
        The API key is missing, malformed, unknown, revoked or expired. The
        response carries `WWW-Authenticate: Bearer`. Codes: `unauthorized`.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            unauthorized:
              summary: 'Send your API key as `Authorization: Bearer inv_live_…`.'
              value:
                type: https://invoice.horizonpay.co/problems/unauthorized
                title: Unauthorized
                status: 401
                detail: 'Send your API key as `Authorization: Bearer inv_live_…`.'
                instance: req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
                code: unauthorized
    Forbidden:
      description: >-
        The key is valid but lacks a scope this operation needs (see
        `x-required-scope`). Codes: `forbidden`.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            forbidden:
              summary: This credential is missing the invoices:write scope.
              value:
                type: https://invoice.horizonpay.co/problems/forbidden
                title: Insufficient scope
                status: 403
                detail: This credential is missing the invoices:write scope.
                instance: req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
                code: forbidden
    RateLimited:
      description: >-
        Rate limit exceeded for this API key. Wait the number of seconds in
        `Retry-After` before retrying. Codes: `rate_limited`.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            rate_limited:
              summary: Rate limit of 120 per 60s exceeded.
              value:
                type: https://invoice.horizonpay.co/problems/rate-limited
                title: Too many requests
                status: 429
                detail: Rate limit of 120 per 60s exceeded.
                instance: req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71
                code: rate_limited
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: inv_live_<id>_<secret>
      description: >-
        An Invoice-AI API key sent as `Authorization: Bearer inv_live_…`.


        Create keys in **Settings → API keys**; the secret is shown once. Each
        key carries scopes, and every operation lists the scope it needs
        (`x-required-scope`):


        - `business:read` — Read your business profile, tax ID and bank details

        - `clients:read` — List and read your clients

        - `clients:write` — Create, update and archive clients

        - `products:read` — List and read products and prices

        - `products:write` — Create, update and archive products and prices

        - `invoices:read` — List and read invoices, including PDFs

        - `invoices:write` — Create, edit and delete drafts

        - `invoices:finalize` — Finalize invoices and void them

        - `invoices:send` — Email invoices to your clients

        - `payments:write` — Mark invoices as paid

        - `webhooks:manage` — Manage webhook endpoints


        Keys cannot be created or revoked through the API, so a leaked key
        cannot mint more keys.

````

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