> ## 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.

# Bind Quote

> Binds a quote into a policy in a single, atomic call — the one-call
convenience over hand-rolling a `new-business` transaction from the quote's
data. The quote is read server-side; the body is optional.

On success the quote is linked to the resulting policy (`quoteStatus` becomes
`bound`, and the quote points at the policy) and the policy is created — both
in one transaction, so a quote can never end up bound to a policy that was
not created, or vice versa.

**Which quote types can bind.** The endpoint dispatches on the quote's type,
and **all five types bind here**. `newBusiness` and `renewal` mint a
brand-new policy (a renewal's new policy is linked back to the expiring
term); `endorsement`, `cancellation`, and `reinstatement` transact against
their existing source policy in place. The response `policyId` is the policy
the transaction landed on — the new policy for `newBusiness` / `renewal`, the
existing source policy for the in-place types.

**Bindable states.** A quote binds from `inProgress` or `complete`. A quote
that is already `bound` returns `409` — the error body carries
`referencingPolicy` (the policy it is already bound to) so you can recover the
id without another call. A `cancelled` quote returns `409`.

**Validation.** The quote must satisfy the same policy-create rules a
`new-business` transaction enforces — notably the term bounds on the quote's
own `policyStartDate` and `policyEndDate` root fields, and a resolvable
primary insured among its exposures. A quote that fails them returns a
structured `400`.

**Invoice convenience.** Send `{ "generateInvoices": true }` to build an
explicit invoice plan server-side from the resolved policy-invoice presets,
then validate and post it through the same policy-invoice batch as any
caller-authored plan. For in-place transactions it keeps existing active
invoices and adds the difference; new-business and renewal terms start from
zero. It uses the term start as the first due date and repeats monthly.
Primary-insured payees resolve from the quote's canonical framework party.
A preset requiring a broker fails closed with `422` because the framework
has no canonical broker/producer party; use a transaction endpoint with an
explicit `invoicePlan` and `payeeId` instead. Omit the body (or send `{}`) to
preserve ordinary bind behavior with no invoices.

**Required permission:** `company.policy:create`




## OpenAPI

````yaml /openapi/generated-external-api.yaml post /api/v1/companies/{companyId}/quotes/{quoteId}/bind
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}/bind:
    post:
      tags:
        - Field Model Policy Transactions
      summary: Bind Quote
      description: >
        Binds a quote into a policy in a single, atomic call — the one-call

        convenience over hand-rolling a `new-business` transaction from the
        quote's

        data. The quote is read server-side; the body is optional.


        On success the quote is linked to the resulting policy (`quoteStatus`
        becomes

        `bound`, and the quote points at the policy) and the policy is created —
        both

        in one transaction, so a quote can never end up bound to a policy that
        was

        not created, or vice versa.


        **Which quote types can bind.** The endpoint dispatches on the quote's
        type,

        and **all five types bind here**. `newBusiness` and `renewal` mint a

        brand-new policy (a renewal's new policy is linked back to the expiring

        term); `endorsement`, `cancellation`, and `reinstatement` transact
        against

        their existing source policy in place. The response `policyId` is the
        policy

        the transaction landed on — the new policy for `newBusiness` /
        `renewal`, the

        existing source policy for the in-place types.


        **Bindable states.** A quote binds from `inProgress` or `complete`. A
        quote

        that is already `bound` returns `409` — the error body carries

        `referencingPolicy` (the policy it is already bound to) so you can
        recover the

        id without another call. A `cancelled` quote returns `409`.


        **Validation.** The quote must satisfy the same policy-create rules a

        `new-business` transaction enforces — notably the term bounds on the
        quote's

        own `policyStartDate` and `policyEndDate` root fields, and a resolvable

        primary insured among its exposures. A quote that fails them returns a

        structured `400`.


        **Invoice convenience.** Send `{ "generateInvoices": true }` to build an

        explicit invoice plan server-side from the resolved policy-invoice
        presets,

        then validate and post it through the same policy-invoice batch as any

        caller-authored plan. For in-place transactions it keeps existing active

        invoices and adds the difference; new-business and renewal terms start
        from

        zero. It uses the term start as the first due date and repeats monthly.

        Primary-insured payees resolve from the quote's canonical framework
        party.

        A preset requiring a broker fails closed with `422` because the
        framework

        has no canonical broker/producer party; use a transaction endpoint with
        an

        explicit `invoicePlan` and `payeeId` instead. Omit the body (or send
        `{}`) to

        preserve ordinary bind behavior with no invoices.


        **Required permission:** `company.policy:create`
      operationId: bindQuote
      parameters:
        - $ref: '#/components/parameters/companyId'
        - $ref: '#/components/parameters/quoteIdPath'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                generateInvoices:
                  type: boolean
                  enum:
                    - true
                  description: Generate a preset-backed explicit invoice plan.
            examples:
              ordinaryBind:
                summary: Bind without generating invoices
                value: {}
              generateInvoices:
                summary: Bind and generate policy invoices atomically
                value:
                  generateInvoices: true
      responses:
        '201':
          description: The quote was bound. Returns the id of the resulting policy.
          content:
            application/json:
              schema:
                type: object
                required:
                  - policyId
                properties:
                  policyId:
                    type: string
                    format: uuid
                    description: The policy the bind created (or landed on).
              examples:
                bound:
                  summary: Quote bound to a new policy
                  value:
                    policyId: 550e8400-e29b-41d4-a716-446655440010
        '400':
          description: |
            The quote failed policy-create validation (e.g. the root
            `primaryInsuredId` is missing or does not reference an existing
            Exposure).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No quote with the given id exists for this company.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >
            The quote cannot be bound: it is already `bound` (the error carries

            `referencingPolicy`, the policy it is bound to) or it is in a
            terminal

            state (`cancelled`).
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code
                      message:
                        type: string
                        description: Human-readable error message
                      userMessages:
                        type: array
                        items:
                          type: string
                      referencingPolicy:
                        type: string
                        format: uuid
                        nullable: true
                        description: >
                          Present when the conflict is an already-bound quote:
                          the

                          id of the policy it is already bound to.
              examples:
                alreadyBound:
                  summary: Quote is already bound
                  value:
                    error:
                      code: QuoteAlreadyBound
                      message: >-
                        Quote 550e8400-e29b-41d4-a716-446655440002 is already
                        bound to policy 550e8400-e29b-41d4-a716-446655440010
                      userMessages:
                        - >-
                          Quote 550e8400-e29b-41d4-a716-446655440002 is already
                          bound to policy 550e8400-e29b-41d4-a716-446655440010
                      referencingPolicy: 550e8400-e29b-41d4-a716-446655440010
        '422':
          description: >-
            Invoice generation could not resolve binding or a preset payee, or
            the generated plan failed the policy-invoice batch.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '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:
    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
                  message:
                    type: string
                    description: Description of the field error
                    example: Required field is missing
  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
    Forbidden:
      description: Forbidden - Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            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
            companyMismatch:
              summary: A valid API key naming another company in the URL
              value:
                error:
                  code: AuthorizationError
                  message: API key is not scoped to the requested company
                  userMessages:
                    - API key is not scoped to the requested company
    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.

````