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

# New Business Transaction

> Creates a new policy via a NEW_BUSINESS transaction. This is the entry point for the
transaction-based policy lifecycle. The transaction produces a single segment covering
the full policy term.

The request body is the complete initial policy state in `data` — the policy-level fields
at the top level of that object. Any embedded exposure fields your company configuration
defines (e.g. `primaryInsured` / `additionalExposures` in the default configuration) ride
along as ordinary configured fields, validated per-field against the Exposure
configuration. The primary insured is derived from those exposures; you do not send it.

**Term bounds come solely from the policy's own root fields.** `policyStartDate` and
`policyEndDate` are read from `data.policyStartDate` and `data.policyEndDate` — there are
no top-level date parameters. The transaction's effective date is the policy start date.

**Policy invoices.** Optionally send `invoicePlan`, a fully explicit
keep/void/create plan. Nothing is defaulted or inferred; omission posts no
invoices. The plan is validated and committed atomically with the policy.

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




## OpenAPI

````yaml /openapi/generated-external-api.yaml post /api/v1/companies/{companyId}/policies/transaction/new-business
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}/policies/transaction/new-business:
    post:
      tags:
        - Field Model Policy Transactions
      summary: New Business Transaction
      description: >
        Creates a new policy via a NEW_BUSINESS transaction. This is the entry
        point for the

        transaction-based policy lifecycle. The transaction produces a single
        segment covering

        the full policy term.


        The request body is the complete initial policy state in `data` — the
        policy-level fields

        at the top level of that object. Any embedded exposure fields your
        company configuration

        defines (e.g. `primaryInsured` / `additionalExposures` in the default
        configuration) ride

        along as ordinary configured fields, validated per-field against the
        Exposure

        configuration. The primary insured is derived from those exposures; you
        do not send it.


        **Term bounds come solely from the policy's own root fields.**
        `policyStartDate` and

        `policyEndDate` are read from `data.policyStartDate` and
        `data.policyEndDate` — there are

        no top-level date parameters. The transaction's effective date is the
        policy start date.


        **Policy invoices.** Optionally send `invoicePlan`, a fully explicit

        keep/void/create plan. Nothing is defaulted or inferred; omission posts
        no

        invoices. The plan is validated and committed atomically with the
        policy.


        **Required permission:** `company.policy:create`
      operationId: newBusinessPolicyTransaction
      parameters:
        - $ref: '#/components/parameters/companyId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - data
              properties:
                transactionTimestamp:
                  type: string
                  format: date-time
                  description: >
                    When the business decision was made. Defaults to the current
                    time if omitted.

                    Set explicitly for imports (e.g., aligning to a bordereau
                    booking date).
                displayAuthor:
                  type: string
                  maxLength: 255
                  description: >-
                    Optional user-visible author label (trimmed; must be
                    non-empty). When set, the transaction is displayed as filed
                    by this label (e.g. "Data Import") instead of the acting
                    user; audit attribution (`createdBy`) stays server-set.
                data:
                  type: object
                  description: >
                    The policy-level fields, at the top level of this object.
                    Must include

                    `policyStatus`, `policyStartDate` and `policyEndDate`. May
                    also include

                    `fullTermPricingInfo`, `fullTermPolicyRatingResult` and any
                    custom

                    fields defined in your field configuration — including
                    embedded exposure

                    fields (the default configuration models a `primaryInsured`
                    object + an

                    `additionalExposures` list, but the platform imposes no
                    structural exposure

                    shape).


                    Custom fields — including the values of any embedded
                    exposure fields — are

                    validated against your company's field configuration.
                    Unknown fields are

                    rejected, required fields must be present, and values must
                    match their

                    configured types (including option set membership). Embedded
                    exposure

                    values are validated per-field against that exposure's own
                    configuration.


                    Before 2026-08-05 these same fields were sent one level
                    deeper, inside

                    `fieldModelV1Data.policy`. Send `data.policyNumber` where
                    you sent

                    `fieldModelV1Data.policy.policyNumber`.
                  required:
                    - policyStatus
                    - policyStartDate
                    - policyEndDate
                  properties:
                    policyStatus:
                      type: string
                      enum:
                        - active
                        - cancelled
                      description: >
                        Segment-scoped policy status (lowercase). On
                        NEW_BUSINESS this is `active`

                        for the whole term. It is a plain per-segment field
                        because it differs

                        across a cancellation boundary.
                    policyStartDate:
                      description: >
                        Policy term start date — defines the lower term bound.
                        Invariant across

                        every segment of the term. Accepts either:

                        - An ISO date string (e.g. `"2025-01-01"` or
                        `"2025-01-01T00:00:00-05:00"`).
                          Timezone is inferred from the UTC offset if present
                          (`-05:00` → `America/New_York`, `-08:00` → `America/Los_Angeles`),
                          otherwise defaults to `America/New_York`. Converted to structured form internally.
                        - A structured date object with explicit
                        day/month/year/timezone fields.
                      oneOf:
                        - type: string
                          format: date
                        - $ref: '#/components/schemas/Fmv1Date'
                    policyEndDate:
                      description: >
                        Policy term end date — defines the upper term bound.
                        Must be after

                        `policyStartDate`. Invariant across every segment of the
                        term. Same

                        accepted forms as `policyStartDate`.
                      oneOf:
                        - type: string
                          format: date
                        - $ref: '#/components/schemas/Fmv1Date'
                    policyNumber:
                      type: string
                      description: >
                        The policy number. Invariant across every segment of the
                        term. Omit it

                        when your configuration mints one; a minted number is
                        preserved from the

                        prior version on later writes, so an endorsement that
                        omits it does not

                        mint a second number.
                    fullTermPricingInfo:
                      type: object
                      description: >
                        The policy's full-term pricing contract. Caller-supplied
                        — the

                        transaction API never rates. Supply `pricingComponents`;
                        the five

                        rollups (`premium`, `taxes`, `fees`, `brokerCommission`,

                        `programCommission`) are computed by the platform from
                        the

                        components — caller-supplied rollup values are ignored
                        and

                        recomputed.
                      properties:
                        pricingComponents:
                          type: array
                          nullable: true
                          description: >
                            The priced charges. Each component carries `label`
                            (display

                            text), `group` (the invoice-grouping name), `kind`
                            (the

                            framework classifier the rollups are summed by — one
                            of

                            `Premium`, `Taxes`, `Fees`, `BrokerCommission`,

                            `ProgramCommission`, `Other`), `value` (a plain
                            number, USD),

                            and optionally `earningBasis` (`pro-rata` or

                            `fully-earned-at-inception`; omitted means pro-rata,
                            and a

                            basis is rejected on kind `Other`).
                          items:
                            type: object
                            required:
                              - label
                              - group
                              - kind
                              - value
                            properties:
                              label:
                                type: string
                              group:
                                type: string
                              kind:
                                type: string
                                enum:
                                  - Premium
                                  - Taxes
                                  - Fees
                                  - BrokerCommission
                                  - ProgramCommission
                                  - Other
                              value:
                                type: number
                              earningBasis:
                                type: string
                                nullable: true
                                enum:
                                  - pro-rata
                                  - fully-earned-at-inception
                            additionalProperties: true
                      additionalProperties: true
                    fullTermPolicyRatingResult:
                      type: object
                      description: >
                        Optional canonical policy-level rating result for the
                        full term. Caller-supplied.

                        Invariant across every segment. Element-level rating
                        output is placed inline at its

                        host instead (e.g. an embedded exposure's
                        `crossSegmentRatingOutputs`).
                      additionalProperties: true
                  additionalProperties: true
                invoicePlan:
                  $ref: '#/components/schemas/PolicyInvoiceTransactionPlan'
            examples:
              medicalFacility:
                summary: Medical facility policy
                description: >
                  Only the framework fields are universal: `policyStatus`,

                  `policyStartDate` and `policyEndDate`. The remaining fields
                  shown

                  here — `annualPremium`, the embedded `primaryInsured`

                  (`exposureType`, `bedCount`), and `additionalExposures` — are

                  **specific to the default tenant configuration**, not part of

                  the framework contract. They validate only on a company whose

                  configuration defines them; your own configuration will have

                  different custom fields. The `fullTermPricingInfo` object is

                  framework-optional; when present, supply `pricingComponents` —

                  the five rollups are computed by the platform.
                value:
                  data:
                    policyStatus: active
                    annualPremium: 85000
                    policyStartDate:
                      year: 2025
                      month: 1
                      day: 1
                      timezone: America/New_York
                    policyEndDate:
                      year: 2026
                      month: 1
                      day: 1
                      timezone: America/New_York
                    fullTermPricingInfo:
                      pricingComponents:
                        - label: Policy Premium
                          group: Policy Invoice
                          kind: Premium
                          value: 85000
                        - label: Policy Fee
                          group: Policy Invoice
                          kind: Fees
                          value: 500
                    primaryInsured:
                      id: 550e8400-e29b-41d4-a716-446655440010
                      exposureType: MedicalFacility
                      bedCount: 120
                    additionalExposures: []
      responses:
        '201':
          description: Policy created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyTransactionVersionResponse'
              examples:
                success:
                  summary: New business transaction response
                  value:
                    policyId: 550e8400-e29b-41d4-a716-446655440001
                    policyVersion: 1
                    transactionId: 550e8400-e29b-41d4-a716-446655440002
                    startDate: '2025-01-01'
                    endDate: '2026-01-01'
                    createdAt: '2025-01-15T10:30:00.000Z'
                    primaryInsuredName: Mercy General Hospital
                    primaryInsuredId: 550e8400-e29b-41d4-a716-446655440010
                    policyNumber: POL-2025-000123
                    policyStartDate:
                      year: 2025
                      month: 1
                      day: 1
                      timezone: America/New_York
                    policyEndDate:
                      year: 2026
                      month: 1
                      day: 1
                      timezone: America/New_York
                    fullTermPricingInfo:
                      premium: 85000
                      taxes: 0
                      fees: 500
                      brokerCommission: 0
                      programCommission: 0
                      pricingComponents:
                        - label: Policy Premium
                          group: Policy Invoice
                          kind: Premium
                          earningBasis: null
                          value: 85000
                        - label: Policy Fee
                          group: Policy Invoice
                          kind: Fees
                          earningBasis: null
                          value: 500
                    fullTermPolicyRatingResult: null
                    segments:
                      - startDate: '2025-01-01'
                        endDate: '2026-01-01'
                        data:
                          policyStatus: active
                          policyNumber: POL-2025-000123
                          policyStartDate:
                            year: 2025
                            month: 1
                            day: 1
                            timezone: America/New_York
                          policyEndDate:
                            year: 2026
                            month: 1
                            day: 1
                            timezone: America/New_York
                          primaryInsuredId: 550e8400-e29b-41d4-a716-446655440010
                          primaryInsuredName: Mercy General Hospital
                          annualPremium: 85000
                          fullTermPricingInfo:
                            premium: 85000
                            taxes: 0
                            fees: 500
                            brokerCommission: 0
                            programCommission: 0
                            pricingComponents:
                              - label: Policy Premium
                                group: Policy Invoice
                                kind: Premium
                                earningBasis: null
                                value: 85000
                              - label: Policy Fee
                                group: Policy Invoice
                                kind: Fees
                                earningBasis: null
                                value: 500
                          primaryInsured:
                            id: 550e8400-e29b-41d4-a716-446655440010
                            exposureType: MedicalFacility
                            bedCount: 120
                          additionalExposures: []
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidDateRange:
                  summary: End date before start date
                  value:
                    error:
                      code: InvalidDateRange
                      message: policyEndDate must be after policyStartDate
                missingFrameworkFields:
                  summary: Missing required framework fields
                  value:
                    error:
                      code: InvalidPolicyData
                      message: >-
                        'policyStatus' is required (string); 'policyStartDate'
                        is required (Date object); 'policyEndDate' is required
                        (Date object)
                termOnlyInContainer:
                  summary: Term stated only in the read-only mirror
                  value:
                    error:
                      code: InvalidPolicyData
                      message: >-
                        'policyStartDate' is required (Date object);
                        'policyEndDate' is required (Date object)
                fieldConfigValidation:
                  summary: Field value fails company configuration validation
                  value:
                    error:
                      code: InvalidFieldModelV1Data
                      message: >-
                        Unknown field 'nonExistentField'; Field 'bedCount'
                        expected number, got string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: An invoice referenced by invoicePlan was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            A void watermark in invoicePlan is stale; no policy version or
            invoice action was committed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            invoicePlan failed policy-invoice binding, conservation,
            payment-lock, or restating preconditions; no policy version or
            invoice action was committed.
          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
  schemas:
    Fmv1Date:
      type: object
      description: >
        Field Model V1 object primitive representing a calendar date with an

        explicit timezone.


        `day`, `month`, and `year` are required when this object is provided in
        a

        write payload; `timezone` is optional. Partial date components are

        rejected with `400`.


        **Two accepted input shapes** — the API canonicalizes both into the

        internal `{ day, month, year, timezone }` form before storage:

        * `{ date: "YYYY-MM-DD", timezone: "America/New_York" }` — ISO form

        * `{ day, month, year, timezone }` — DMY form (returned in responses)


        Day, month, and year are 1-based integers. `timezone` is an IANA tz

        database identifier (e.g. "America/New_York", "UTC").
      required:
        - day
        - month
        - year
      properties:
        day:
          type: integer
          minimum: 1
          maximum: 31
          description: Day of month, 1-based (1-31)
        month:
          type: integer
          minimum: 1
          maximum: 12
          description: Month, 1-based (1=January, 12=December)
        year:
          type: integer
          description: Four-digit calendar year (e.g. 2026)
        timezone:
          type: string
          description: IANA timezone identifier (e.g. "America/New_York", "UTC")
    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 every bound component of the policy's current pricing contract.
    PolicyTransactionVersionResponse:
      type: object
      description: >
        Response returned by policy transaction endpoints. Contains the policy
        version

        produced by the transaction, including all derived segments.
      required:
        - policyId
        - policyVersion
        - transactionId
        - startDate
        - endDate
        - createdAt
        - segments
      properties:
        policyId:
          type: string
          format: uuid
          description: Policy identifier
        policyVersion:
          type: integer
          description: Sequential version number produced by this transaction
        transactionId:
          type: string
          format: uuid
          description: Identifier of the transaction that produced this version
        startDate:
          type: string
          format: date
          description: Policy term start date (ISO 8601)
        endDate:
          type: string
          format: date
          description: Policy term end date (ISO 8601)
        createdAt:
          type: string
          format: date-time
          description: When the transaction was created (ISO 8601)
        primaryInsuredName:
          type: string
          nullable: true
          description: >
            Plain-text primary-insured name, read from the policy's own

            `primaryInsuredName` field — the source of truth for the primary
            insured.

            Reported as of the END of

            the term, so a policy whose insured changed mid-term returns the
            later name;

            `segments[]` carries the per-segment history. Null only when the
            version

            carries no policy data.
        primaryInsuredId:
          type: string
          nullable: true
          description: |
            Id of the entity behind `primaryInsuredName`. Null when the policy's
            configuration does not populate it.
        policyNumber:
          type: string
          nullable: true
          description: >
            The policy number, read from the policy's own `policyNumber` field —
            the

            source of truth, invariant across the whole term. Null only when the
            version

            carries no policy data.
        policyStartDate:
          type: object
          nullable: true
          description: >
            Policy term start date as the structured date object, read from the
            policy's

            own `policyStartDate` field — the source of truth, invariant across
            the whole

            term. This is **not** `startDate` above: that is the ISO

            span this version covers, which a cancellation makes shorter than
            the term.

            Null only when the version carries no policy data.
          allOf:
            - $ref: '#/components/schemas/Fmv1Date'
        policyEndDate:
          type: object
          nullable: true
          description: >
            Policy term end date as the structured date object, read from the
            policy's own

            `policyEndDate` field — the source of truth, invariant across the
            whole term.

            This is **not** `endDate` above: that is the ISO

            span this version covers. Null only when the version carries no
            policy data.
          allOf:
            - $ref: '#/components/schemas/Fmv1Date'
        fullTermPricingInfo:
          type: object
          nullable: true
          description: >
            The policy's full-term pricing contract, hoisted as a read-once
            convenience

            (also duplicated in every segment): `pricingComponents` (each

            `{label, group, kind, value[, earningBasis]}`) plus the five
            server-computed,

            read-only rollups (`premium`, `taxes`, `fees`, `brokerCommission`,

            `programCommission` — each the sum of its kind's components).
          additionalProperties: true
        fullTermPolicyRatingResult:
          type: object
          nullable: true
          description: >
            Derived canonical policy-level rating result for the full term,
            hoisted as a

            read-once convenience (also duplicated in every segment).
            Element-level rating

            output (`crossSegmentRatingOutputs`) stays inline at its host and is
            not hoisted.
          additionalProperties: true
        segments:
          type: array
          description: >
            Derived segments for this policy version. Each segment represents a
            maximal contiguous

            date range where policy state is identical. Adjacent segments with
            identical data are

            automatically merged.
          items:
            $ref: '#/components/schemas/PolicyTransactionSegmentResponse'
    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
    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, matching a pricing component group.
        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'
    PolicyTransactionSegmentResponse:
      type: object
      description: >
        A derived policy segment representing a date range where policy state is
        identical.

        Contains the full policy data (policy-level fields and nested exposures)
        for this period.
      required:
        - startDate
        - endDate
        - data
      properties:
        startDate:
          type: string
          format: date
          description: Segment start date (ISO 8601)
        endDate:
          type: string
          format: date
          description: Segment end date (ISO 8601)
        data:
          type: object
          description: >
            Policy state for this segment: the policy-level fields and their
            nested

            exposure containers, at the top level of this object.


            Before 2026-08-05 this member was named `fieldModelV1Data` and
            wrapped the

            same fields in an extra `policy` key. Read `data.policyNumber` where
            you

            read `fieldModelV1Data.policy.policyNumber`.
          additionalProperties: true
    PolicyInvoiceBatchCreateLine:
      type: object
      additionalProperties: false
      required:
        - label
        - amountCents
      properties:
        label:
          type: string
          minLength: 1
          description: Line-item label from the pricing contract and bound invoice type.
        amountCents:
          type: integer
          description: Signed integer cents in the configured line-item type's own frame.
        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
    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.

````