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

# Create an invoice

> Creates a draft invoice for a customer and drains that customer's pending
items in the given currency onto it. With no pending items the result is
an empty draft. The invoice and the item assignments commit atomically.




## OpenAPI

````yaml /openapi/invoices.yaml post /invoices
openapi: 3.0.3
info:
  title: Ionic Invoices API
  version: '2026-05-30'
  description: |
    Invoices and invoice items.

    An invoice item is a pending charge recorded against a customer. When an
    invoice is created for that customer, every pending item in the invoice
    currency is drained onto the new draft as a line. A draft can be edited
    freely; finalizing it assigns a gapless, per-merchant/mode sequential number
    (for example `INV-000001`), applies tax, freezes the lines, and opens the
    invoice. Drafts carry no number, so an abandoned draft never consumes one
    and the finalized sequence is always contiguous.

    All monetary amounts are integers in the currency's minor unit (for example
    cents for USD). Timestamps are Unix epoch seconds. Identifiers are opaque,
    prefixed strings: invoices are `inv_…`, invoice items `ii_…`, and invoice
    lines `il_…`.

    Authentication uses a merchant secret key as a bearer token. Read endpoints
    require the `invoices:read` permission; write endpoints require
    `invoices:write`. The mode of the key (test or live) scopes which invoices
    and invoice items it can see, mutate, and drain. Live invoice numbers use
    `INV-000001` style labels; test invoice numbers use `TEST-INV-000001`.
    Mutating endpoints accept an optional `Idempotency-Key` header.

    Errors are returned as `{ "error": { "code": "...", "message": "..." } }`.
    A malformed path identifier returns 400. Concurrent updates are retried
    automatically; if they still conflict, the API returns 409 and the request
    can be retried.
servers:
  - url: '{baseUrl}/v1'
    variables:
      baseUrl:
        default: https://api.ionicfi.com
        description: API base URL for your environment.
security:
  - secretKey: []
tags:
  - name: Invoices
    description: Create, finalize, and manage invoices.
  - name: Invoice Items
    description: Pending charges that drain onto a customer's next invoice.
paths:
  /invoices:
    post:
      tags:
        - Invoices
      summary: Create an invoice
      description: >
        Creates a draft invoice for a customer and drains that customer's
        pending

        items in the given currency onto it. With no pending items the result is

        an empty draft. The invoice and the item assignments commit atomically.
      operationId: invoices_create
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInvoiceRequest'
      responses:
        '201':
          description: The created draft invoice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/CustomerNotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/CustomerDeleted'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - secretKey:
            - invoices:write
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        A unique key that makes retries safe: the same key with the same request
        body returns the original response instead of repeating the operation.
      schema:
        type: string
        maxLength: 255
  schemas:
    CreateInvoiceRequest:
      type: object
      required:
        - customer
        - currency
        - collection_method
      properties:
        customer:
          type: string
        currency:
          type: string
        collection_method:
          type: string
          enum:
            - charge_automatically
            - send_invoice
        due_date:
          type: integer
          nullable: true
          description: Unix epoch seconds; used with send_invoice.
        metadata:
          type: object
          additionalProperties:
            type: string
    Invoice:
      type: object
      required:
        - allow_save_card
        - amount_paid
        - amount_remaining
        - attempt_count
        - collection_method
        - created_at
        - currency
        - customer
        - id
        - lines
        - metadata
        - number
        - object
        - status
        - subtotal
        - tax
        - total
        - updated_at
      properties:
        id:
          type: string
          description: The invoice id (`inv_…`).
        object:
          type: string
          enum:
            - invoice
          description: Always `invoice`.
        number:
          type: string
          nullable: true
          description: >-
            The gapless per-merchant number, assigned at finalize. Null while
            draft.
        customer:
          type: string
          description: The billed customer (`cus_…`), set at creation and immutable.
        subscription:
          type: string
          nullable: true
          description: >-
            The subscription that generated this invoice (`sub_…`). Absent for
            one-off invoices created directly against a customer.
        status:
          type: string
          enum:
            - draft
            - open
            - paid
            - void
            - uncollectible
          description: >-
            One of `draft` (being built, lines mutable, never customer-visible),
            `open` (finalized, lines frozen, awaiting payment), `paid`
            (terminal; reachable from `open`, from `uncollectible` via a late
            payment, or directly at finalize when the total is zero), `void`
            (terminal; requires `amount_paid` of zero), or `uncollectible`
            (written off; not terminal, since a late payment can still move it
            to `paid`).
        collection_method:
          type: string
          enum:
            - charge_automatically
            - send_invoice
          description: >-
            One of `charge_automatically` (charged automatically against the
            pinned payment method) or `send_invoice` (the buyer pays the hosted
            page by `due_date`).
        collection_payment_method_id:
          type: string
          nullable: true
          description: >-
            The payment method (`pm_…`) pinned for automatic collection. Null
            when no method is pinned.
        allow_save_card:
          type: boolean
          description: >-
            Whether the hosted invoice page offers the buyer the option to save
            their card for future use.
        currency:
          type: string
          description: >-
            Three-letter ISO currency code. USD, EUR, and GBP are supported; all
            use 2-decimal minor units.
        lines:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLine'
          description: The invoice's line items. Frozen once the invoice leaves `draft`.
        subtotal:
          type: integer
          description: The sum of the line amounts, in minor units.
        tax:
          type: integer
          description: >-
            The tax amount, in minor units. Zero until finalize supplies a tax
            amount.
        total:
          type: integer
          description: >-
            `subtotal` plus `tax` minus discounts, in minor units. Discounts can
            reduce this to zero but never below it.
        amount_paid:
          type: integer
          description: The cumulative amount paid so far, in minor units.
        amount_remaining:
          type: integer
          description: '`total` minus `amount_paid`, in minor units.'
        due_date:
          type: integer
          nullable: true
          description: >-
            Unix epoch seconds by which the buyer must pay. Used with
            `send_invoice`; null otherwise.
        finalized_at:
          type: integer
          nullable: true
          description: >-
            Unix epoch seconds when the invoice was finalized. Null while the
            invoice is a draft.
        paid_at:
          type: integer
          nullable: true
          description: >-
            Unix epoch seconds when the invoice became fully paid. Null until
            then.
        voided_at:
          type: integer
          nullable: true
          description: >-
            Unix epoch seconds when the invoice was voided. Null unless the
            invoice is void.
        next_payment_attempt_at:
          type: integer
          nullable: true
          description: >-
            Unix time of the next scheduled automatic collection retry. Present
            only while a dunning retry is pending.
        payment_intent:
          type: string
          nullable: true
          description: >-
            The payment intent created to collect this invoice (`pi_…`). Present
            once a collection attempt has created one; links the invoice to its
            transaction.
        attempt_count:
          type: integer
          description: >-
            The number of collection attempts recorded against this invoice so
            far.
        max_attempts:
          type: integer
          nullable: true
          description: >-
            The dunning policy's total attempt allowance, for rendering progress
            like "attempt N of max_attempts". Present only on subscription
            `charge_automatically` invoices when the dunning schedule is enabled
            for the deployment; null otherwise.
        hosted_invoice_url:
          type: string
          nullable: true
          description: >-
            The buyer-facing hosted invoice page URL. Present once the invoice
            has been finalized and hosted invoicing is enabled for the
            deployment; null on drafts or when hosted invoicing is not
            configured.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            A string key-value map for storing your own structured data. Up to
            50 keys; each key at most 40 characters and each value at most 500
            characters.
        created_at:
          type: integer
          description: Unix epoch seconds when the invoice was created.
        updated_at:
          type: integer
          description: Unix epoch seconds when the invoice was last updated.
    InvoiceLine:
      type: object
      required:
        - amount
        - currency
        - description
        - id
        - quantity
        - unit_amount
      properties:
        id:
          type: string
          description: The invoice line id (`il_…`).
        description:
          type: string
          description: The line's label, shown on the invoice.
        quantity:
          type: integer
          description: The quantity of the line item. At least 1.
        unit_amount:
          type: integer
          description: The per-unit price, in minor units.
        amount:
          type: integer
          description: >-
            The line's total amount, in minor units. Equal to `unit_amount`
            times `quantity` unless the line is a proration or has an explicit
            override.
        currency:
          type: string
          description: >-
            The line's currency. Always matches the invoice's currency; a
            mismatch is rejected at construction.
        invoice_item:
          type: string
          nullable: true
          description: Source invoice item, when the line came from a drain.
        price:
          type: string
          nullable: true
          description: >-
            The catalog price (`price_…`) this line was derived from, when
            applicable. Null when the line was added directly.
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: A stable, machine-readable error code.
            message:
              type: string
  responses:
    BadRequest:
      description: The request was malformed or failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_DATA
              message: invalid currency
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: The key lacks the required permission, or the merchant is not active.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    CustomerNotFound:
      description: No such customer for this merchant.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: CUSTOMER_NOT_FOUND
              message: customer not found
    Conflict:
      description: The resource was modified concurrently; retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: CONFLICT
              message: invoice was modified concurrently, please retry
    CustomerDeleted:
      description: The customer has been deleted.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: CUSTOMER_ALREADY_DELETED
              message: customer is deleted
    RateLimited:
      description: Too many requests. Honour the `Retry-After` header before retrying.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: |
        The API could not return a successful response. For a mutating request,
        retrieve the resource before retrying because the operation may have
        completed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: 'A merchant secret key (`sk_…`) sent as `Authorization: Bearer <key>`.'

````