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

# Attach Quote Invoice Plan

> **Quote door.** A quote owns its invoices. This attaches a plan you wrote
to the quote, replacing any plan on it, and binding the quote uses it. The
settings stay as they are.

The body is a `PolicyInvoiceTransactionPlan`: the policy's existing
invoices to void, each with the `headJournalId` you read, and the invoices
to create. A new business or renewal quote has no existing invoices. Before
the plan is saved it gets the checks a bind runs on a quote's plan:
billing continuity on an endorsement, cancellation or reinstatement; each
create's payee; each void's watermark and whether the invoice can still be
voided; invoice continuity; and that the kept and created invoices add up
to the quote's `fullTermBillingInfo`, line item by line item. The plan is
checked again when the quote is bound, against the invoices then current.

To let the quote's settings write the plan instead, use
[Generate Quote Invoices](/api-reference/invoicing/generate-quote-invoices).

**Refusals.** A plan that does not add up returns
`422 finv2-quote-invoices-do-not-match-pricing`, naming each line that is
off and the fix. A create's payee the invoice type does not accept returns
`422 finv2-policy-create-payee-invalid`. A change that drops billing the
policy already has, or voids every invoice while billing still owes,
returns `400 finv2-policy-billing-required` or
`400 finv2-policy-invoices-required`. Nothing is saved. With policy
invoicing disabled, this returns `403 finv2-policy-invoicing-disabled`. A
bound or cancelled quote returns `409`.

**Required permission:** `quote.edit`




## OpenAPI

````yaml /openapi/generated-external-api.yaml put /api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/plan
openapi: 3.0.3
info:
  title: AI Insurance External API
  description: External API for AI Insurance platform
  version: 1.0.0
  contact:
    email: support@aiinsurance.io
servers:
  - url: https://go.aiinsurance.io
    description: Production
security:
  - ApiKeyAuth: []
paths:
  /api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/plan:
    put:
      tags:
        - Policy Invoicing
      summary: Attach Quote Invoice Plan
      description: >
        **Quote door.** A quote owns its invoices. This attaches a plan you
        wrote

        to the quote, replacing any plan on it, and binding the quote uses it.
        The

        settings stay as they are.


        The body is a `PolicyInvoiceTransactionPlan`: the policy's existing

        invoices to void, each with the `headJournalId` you read, and the
        invoices

        to create. A new business or renewal quote has no existing invoices.
        Before

        the plan is saved it gets the checks a bind runs on a quote's plan:

        billing continuity on an endorsement, cancellation or reinstatement;
        each

        create's payee; each void's watermark and whether the invoice can still
        be

        voided; invoice continuity; and that the kept and created invoices add
        up

        to the quote's `fullTermBillingInfo`, line item by line item. The plan
        is

        checked again when the quote is bound, against the invoices then
        current.


        To let the quote's settings write the plan instead, use

        [Generate Quote
        Invoices](/api-reference/invoicing/generate-quote-invoices).


        **Refusals.** A plan that does not add up returns

        `422 finv2-quote-invoices-do-not-match-pricing`, naming each line that
        is

        off and the fix. A create's payee the invoice type does not accept
        returns

        `422 finv2-policy-create-payee-invalid`. A change that drops billing the

        policy already has, or voids every invoice while billing still owes,

        returns `400 finv2-policy-billing-required` or

        `400 finv2-policy-invoices-required`. Nothing is saved. With policy

        invoicing disabled, this returns `403 finv2-policy-invoicing-disabled`.
        A

        bound or cancelled quote returns `409`.


        **Required permission:** `quote.edit`
      operationId: putQuoteInvoicePlan
      parameters:
        - $ref: '#/components/parameters/companyId'
        - $ref: '#/components/parameters/quoteIdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PolicyInvoiceTransactionPlan'
            examples:
              twoInstallments:
                summary: A hand-written plan of two installments
                value:
                  incurredDate: '2026-01-01'
                  voidInvoices: []
                  creates:
                    - group: Policy Invoice
                      dueDate: '2026-01-01'
                      scheduledDate: '2026-01-01'
                      payeeId: 550e8400-e29b-41d4-a716-446655440010
                      lineItems:
                        - label: Premium
                          amountCents: 250000
                    - group: Policy Invoice
                      dueDate: '2026-07-01'
                      scheduledDate: '2026-07-01'
                      payeeId: 550e8400-e29b-41d4-a716-446655440010
                      lineItems:
                        - label: Premium
                          amountCents: 250000
              endorsementReplan:
                summary: >-
                  An endorsement that voids an unpaid invoice and bills the new
                  total
                value:
                  incurredDate: '2026-07-01'
                  voidInvoices:
                    - invoiceId: 550e8400-e29b-41d4-a716-446655440700
                      headJournalId: 550e8400-e29b-41d4-a716-446655440900
                  creates:
                    - group: Policy Invoice
                      dueDate: '2026-07-01'
                      payeeId: 550e8400-e29b-41d4-a716-446655440010
                      lineItems:
                        - label: Premium
                          amountCents: 310000
      responses:
        '200':
          description: The quote's invoicing, with the attached plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteInvoicing'
              examples:
                attached:
                  summary: The plan is on the quote; the settings are unchanged
                  value:
                    quoteId: 550e8400-e29b-41d4-a716-446655440002
                    settings:
                      schedule:
                        paymentPeriod: quarterly
                        installmentCount: 4
                        firstDueDate: '2026-01-01'
                        owedLeadTimeDays: 14
                        avoidWeekendSends: true
                        downPayment: null
                      payees:
                        - group: Policy Invoice
                          payeeId: 550e8400-e29b-41d4-a716-446655440010
                      endorsementHandling:
                        mode: void
                        status: scheduled
                    settingsSource: quote
                    plan:
                      incurredDate: '2026-01-01'
                      voidInvoices: []
                      creates:
                        - group: Policy Invoice
                          dueDate: '2026-01-01'
                          scheduledDate: '2026-01-01'
                          payeeId: 550e8400-e29b-41d4-a716-446655440010
                          lineItems:
                            - label: Premium
                              amountCents: 250000
                        - group: Policy Invoice
                          dueDate: '2026-07-01'
                          scheduledDate: '2026-07-01'
                          payeeId: 550e8400-e29b-41d4-a716-446655440010
                          lineItems:
                            - label: Premium
                              amountCents: 250000
        '400':
          description: >-
            A malformed plan, the quote lacks the transaction data its billing
            needs (`finv2-invalid-quote-transaction-metadata`), or the plan
            breaks billing or invoice continuity on a change. Nothing is saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invoicesRequired:
                  summary: >-
                    An endorsement that voids every invoice while billing still
                    owes
                  value:
                    error:
                      code: finv2-policy-invoices-required
                      message: >-
                        This term already has invoices and its billing still
                        owes an amount. Keep or replace its invoices as part of
                        this change.
                      userMessages:
                        - >-
                          This term already has invoices and its billing still
                          owes an amount. Keep or replace its invoices as part
                          of this change.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ForbiddenQuoteInvoicing'
        '404':
          description: No quote with the given id exists for this company.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                quoteNotFound:
                  summary: Quote not found
                  value:
                    error:
                      code: NotFoundError
                      message: Quote not found
                      userMessages:
                        - Quote not found
        '409':
          $ref: '#/components/responses/QuoteInvoicingClosed'
        '422':
          description: >-
            The plan does not add up to the quote's billing and invoices, or a
            create's payee is not one its invoice type accepts. Nothing is
            saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                doesNotAddUp:
                  summary: The second installment is a cent short
                  value:
                    error:
                      code: finv2-quote-invoices-do-not-match-pricing
                      message: >-
                        The plan does not add up to this quote's billing and
                        invoices: “Premium” on “Policy Invoice” is off by 1
                        cents. Attach a corrected plan with PUT
                        /api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/plan,
                        or generate one with POST
                        /api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate.
                      userMessages:
                        - >-
                          The plan does not add up to this quote's billing and
                          invoices: “Premium” on “Policy Invoice” is off by 1
                          cents. Attach a corrected plan with PUT
                          /api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/plan,
                          or generate one with POST
                          /api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate.
                payeeNotAccepted:
                  summary: A payee the invoice type does not accept
                  value:
                    error:
                      code: finv2-policy-create-payee-invalid
                      message: Choose an allowed payee for Policy Invoice.
                      userMessages:
                        - Choose an allowed payee for Policy Invoice.
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  parameters:
    companyId:
      name: companyId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Company identifier
    quoteIdPath:
      name: quoteId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Quote identifier
  schemas:
    PolicyInvoiceTransactionPlan:
      type: object
      additionalProperties: false
      required:
        - incurredDate
        - voidInvoices
        - creates
      properties:
        incurredDate:
          type: string
          format: date
          description: >-
            Explicit recognition date for non-scheduled creates. It is never
            inferred from a transaction effective date or the server clock.
        voidInvoices:
          type: array
          items:
            $ref: '#/components/schemas/PolicyInvoiceBatchVoid'
        creates:
          type: array
          items:
            $ref: '#/components/schemas/PolicyInvoiceBatchCreate'
      description: >-
        A fully explicit, detached policy-invoice batch. Existing invoices not
        named in voidInvoices are kept. The complete kept-plus-created set must
        conserve each line item of the policy's stated billing. With invoicing
        enabled, a line item a kept invoice carries but billing omits conserves
        at 0: a create may credit it on the same line with a negative amount.
    QuoteInvoicing:
      type: object
      additionalProperties: false
      description: >-
        A quote's invoicing: the settings it generates invoices from and the
        plan saved on it. Binding the quote uses them. Every quote invoicing
        endpoint returns this.
      required:
        - quoteId
        - settings
        - settingsSource
        - plan
      properties:
        quoteId:
          type: string
          format: uuid
        settings:
          $ref: '#/components/schemas/QuoteInvoiceSettings'
        settingsSource:
          type: string
          enum:
            - quote
            - company-defaults
          description: >-
            Where `settings` come from. `quote` once the quote has settings of
            its own: saved with Replace Quote Invoice Settings, kept by Generate
            Quote Invoices, or saved in the app's Billing step. A plan attached
            without settings counts too, because its schedule is what `settings`
            shows. `company-defaults` while nothing on the quote sets them:
            `settings` are the company's payment defaults, applied to this
            quote.
        plan:
          description: The plan saved on the quote, or `null` when it holds none.
          anyOf:
            - $ref: '#/components/schemas/PolicyInvoiceTransactionPlan'
            - type: object
              nullable: true
              enum:
                - null
    ErrorResponse:
      type: object
      description: Standard error response for all external API endpoints
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code
              example: VALIDATION_ERROR
            message:
              type: string
              description: Human-readable error message
              example: 'submissionId: Required field is missing'
            userMessages:
              type: array
              description: >-
                Clean, verbatim-displayable messages — one entry per failure,
                free of error-code tags, field paths, and internal noise.
                Suitable for showing to end users as-is.
              items:
                type: string
              example:
                - Exposures of type 'company' require an address
            details:
              type: array
              description: Additional details for validation errors (field-level errors)
              items:
                type: object
                properties:
                  field:
                    type: string
                    description: The field that caused the error
                    example: submissionId
                  code:
                    type: string
                    description: Stable problem code for this individual validation failure
                    example: BLANK_LIST_ELEMENT
                  reason:
                    type: string
                    description: Stable reason the value violates its canonical contract
                    example: blank-list-element
                  expected:
                    type: string
                    description: The expected canonical value contract
                    example: nonblank trimmed string
                  message:
                    type: string
                    description: Description of the field error
                    example: Required field is missing
    PolicyInvoiceBatchVoid:
      type: object
      additionalProperties: false
      required:
        - invoiceId
        - headJournalId
      properties:
        invoiceId:
          type: string
          format: uuid
        headJournalId:
          type: string
          format: uuid
          description: >-
            The invoice watermark read while composing the plan. A stale
            watermark rejects the whole batch with 409.
    PolicyInvoiceBatchCreate:
      type: object
      additionalProperties: false
      required:
        - group
        - lineItems
      properties:
        group:
          type: string
          minLength: 1
          description: >-
            Policy invoice type name. Pricing-fallback plans use the fixed
            Policy Invoice type; Billing Aggregate plans use each line's native
            invoiceType.
        dueDate:
          type: string
          format: date
        scheduledDate:
          type: string
          format: date
          description: >-
            Installment recognition anchor. When present, incurredDate for this
            invoice is this date and the invoice remains scheduled until it
            arrives.
        payeeId:
          type: string
          format: uuid
          description: Canonical Person, Organization, or Exposure entity billed or paid.
        memo:
          type: string
        lineItems:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/PolicyInvoiceBatchCreateLine'
    QuoteInvoiceSettings:
      type: object
      additionalProperties: false
      description: >-
        The settings a quote generates its invoices from. A PUT sends every
        field and replaces them all. A GET returns the same shape, so you can
        change a field of a GET's `settings` and send the object back.
      required:
        - schedule
        - payees
        - endorsementHandling
      properties:
        schedule:
          type: object
          additionalProperties: false
          description: When the new invoices fall due and how they are sent.
          required:
            - paymentPeriod
            - installmentCount
            - firstDueDate
            - owedLeadTimeDays
            - avoidWeekendSends
            - downPayment
          properties:
            paymentPeriod:
              type: string
              enum:
                - upfront
                - quarterly
                - monthly
              description: How often installments fall due. `upfront` is a single payment.
            installmentCount:
              type: integer
              minimum: 1
              maximum: 120
              nullable: true
              description: >-
                How many installments. `null` schedules as many as fall due
                before the term ends. With `upfront`, send `1` or `null`.
            firstDueDate:
              type: string
              format: date
              description: >-
                The first installment's due date. Each later one falls due three
                months (quarterly) or one month (monthly) after the one before.
            owedLeadTimeDays:
              type: integer
              minimum: 0
              maximum: 3650
              description: >-
                How many days before its due date an installment is sent and
                becomes owed.
            avoidWeekendSends:
              type: boolean
              description: >-
                Move a send date that falls on a Saturday or Sunday back to the
                Friday before.
            downPayment:
              type: object
              nullable: true
              additionalProperties: false
              minProperties: 1
              maxProperties: 1
              description: >-
                A larger first installment, or `null` for equal installments.
                Send exactly one of `percent` and `amountCents`. A down payment
                needs at least two installments, so it must be `null` with
                `upfront` or with an `installmentCount` of 1.
              properties:
                percent:
                  type: number
                  minimum: 0
                  exclusiveMinimum: true
                  maximum: 100
                  description: >-
                    A percent of the receivable amount being invoiced, above 0
                    and at most 100, with up to two decimal places.
                amountCents:
                  type: integer
                  minimum: 1
                  description: An amount in cents, above 0.
        payees:
          type: array
          description: >-
            The payee chosen for each policy invoice type, by the type's name.
            List a type at most once; a type you leave out gets its payee when
            invoices are generated: the payee of the plan on the quote, then, on
            an endorsement, cancellation or reinstatement, the payee of the
            policy's current invoices of that type, then the type's configured
            payee. A GET lists only the payees chosen on the quote.
          items:
            type: object
            additionalProperties: false
            required:
              - group
              - payeeId
            properties:
              group:
                type: string
                minLength: 1
                description: A live policy invoice type's name.
              payeeId:
                type: string
                format: uuid
                description: >-
                  The Person, Organization or Exposure the type's invoices are
                  issued to: a record of this company of a kind the type's payee
                  settings allow.
        endorsementHandling:
          type: object
          description: >-
            What generating does with the policy's existing invoices on an
            endorsement, cancellation or reinstatement. `void` voids the
            invoices with the given status (`scheduled`, `owed`, or `all`);
            `keep` keeps them and voids the rest; `manual` keeps every invoice.
            Paid invoices and invoices with payments are never voided. Kept
            invoices count toward the billing, so new invoices bill only what
            they leave.
          oneOf:
            - type: object
              additionalProperties: false
              required:
                - mode
                - status
              properties:
                mode:
                  type: string
                  enum:
                    - void
                status:
                  type: string
                  enum:
                    - scheduled
                    - owed
                    - all
            - type: object
              additionalProperties: false
              required:
                - mode
                - status
              properties:
                mode:
                  type: string
                  enum:
                    - keep
                status:
                  type: string
                  enum:
                    - paid
                    - owed
                    - all
            - type: object
              additionalProperties: false
              required:
                - mode
              properties:
                mode:
                  type: string
                  enum:
                    - manual
    PolicyInvoiceBatchCreateLine:
      type: object
      additionalProperties: false
      required:
        - label
        - amountCents
      properties:
        label:
          type: string
          minLength: 1
          description: >-
            Line-item name on this invoice type: a line item the policy's stated
            billing names or, with invoicing enabled, one an existing kept
            invoice carries.
        amountCents:
          type: integer
          description: >-
            Signed integer cents in the configured line-item type's own frame. A
            negative amount reverses the line: a credit on the same line.
        memo:
          type: string
  responses:
    Unauthorized:
      description: Unauthorized - Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missingApiKey:
              summary: Missing API key
              value:
                error:
                  code: AuthenticationError
                  message: API key authentication required
                  userMessages:
                    - API key authentication required
            invalidApiKey:
              summary: >-
                Invalid API key (e.g. unknown key, or a Bearer token used
                instead of an API key)
              value:
                error:
                  code: AuthenticationError
                  message: Invalid API key
                  userMessages:
                    - Invalid API key
    ForbiddenQuoteInvoicing:
      description: >
        Forbidden. The API key lacks the endpoint's permission, or policy
        invoicing

        is disabled for the company (`finv2-policy-invoicing-disabled`),
        including

        companies awaiting their billing migration. Nothing is saved.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invoicingDisabled:
              summary: Policy invoicing is disabled
              value:
                error:
                  code: finv2-policy-invoicing-disabled
                  message: >-
                    Policy invoicing is not turned on for your company yet, so
                    policy invoices cannot be created or changed. Contact
                    support to enable it.
                  userMessages:
                    - >-
                      Policy invoicing is not turned on for your company yet, so
                      policy invoices cannot be created or changed. Contact
                      support to enable it.
            insufficientPermissions:
              summary: Insufficient permissions
              value:
                error:
                  code: AuthorizationError
                  message: User is not authorized to perform the requested action
                  userMessages:
                    - User is not authorized to perform the requested action
    QuoteInvoicingClosed:
      description: >-
        The quote's invoicing can no longer change. A `bound` quote returns
        `QuoteBoundImmutable` with `referencingPolicy`, the policy it is bound
        to: that policy holds its invoices now, and the policy invoice batch
        changes them. A `cancelled` quote returns `QuoteNotEditable`. Nothing is
        saved.
      content:
        application/json:
          schema:
            type: object
            required:
              - error
            properties:
              error:
                type: object
                required:
                  - code
                  - message
                properties:
                  code:
                    type: string
                    enum:
                      - QuoteBoundImmutable
                      - QuoteNotEditable
                    description: Machine-readable error code
                  message:
                    type: string
                    description: Human-readable error message, naming why and the fix
                  userMessages:
                    type: array
                    items:
                      type: string
                  referencingPolicy:
                    type: string
                    format: uuid
                    nullable: true
                    description: >-
                      `QuoteBoundImmutable` only: the policy the quote is bound
                      to.
          examples:
            quoteBound:
              summary: The quote is bound
              value:
                error:
                  code: QuoteBoundImmutable
                  message: >-
                    Quote 550e8400-e29b-41d4-a716-446655440002 is bound to
                    policy 550e8400-e29b-41d4-a716-446655440020, so its invoice
                    settings and plan can no longer change. The policy holds its
                    invoices now: change them with POST
                    /api/v1/companies/{companyId}/financials/policies/{policyId}/invoices/batch.
                  userMessages:
                    - >-
                      Quote 550e8400-e29b-41d4-a716-446655440002 is bound to
                      policy 550e8400-e29b-41d4-a716-446655440020, so its
                      invoice settings and plan can no longer change. The policy
                      holds its invoices now: change them with POST
                      /api/v1/companies/{companyId}/financials/policies/{policyId}/invoices/batch.
                  referencingPolicy: 550e8400-e29b-41d4-a716-446655440020
            quoteCancelled:
              summary: The quote is cancelled
              value:
                error:
                  code: QuoteNotEditable
                  message: >-
                    Quote 550e8400-e29b-41d4-a716-446655440002 is cancelled, so
                    its invoice settings and plan can no longer change. A
                    cancelled quote is closed: to invoice a variation, create a
                    new quote (POST /entities/quote, or Copy Quote in the app).
                  userMessages:
                    - >-
                      Quote 550e8400-e29b-41d4-a716-446655440002 is cancelled,
                      so its invoice settings and plan can no longer change. A
                      cancelled quote is closed: to invoice a variation, create
                      a new quote (POST /entities/quote, or Copy Quote in the
                      app).
    InternalServerError:
      description: Internal Server Error - Unexpected error occurred
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            internalError:
              summary: Unexpected server error
              value:
                error:
                  code: UncaughtActionError
                  message: Uncaught error occurred in <actionName>
                  userMessages:
                    - An unexpected error occurred. Please try again later.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key authentication. Send your raw API key as the `Authorization`
        header value with NO scheme prefix — `Authorization: YOUR-API-KEY`. Do
        NOT prefix it with `Bearer ` or `ApiKey `, and do not use an `X-API-Key`
        header; those are not accepted.

````

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