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

# Renew Policy Transaction

> Creates a new policy via a RENEW transaction, linking it to a previous policy.
RENEW is NEW_BUSINESS plus a renewal link: the new policy term must start on or
after the previous policy's end date.

The request body is the complete initial policy state in `data`, exactly like
NEW_BUSINESS. **Term bounds and the renewal link all live at the policy root** —
`policyStartDate`, `policyEndDate` and `previousPolicy` are read from `data`. There are
no top-level parameters. The transaction produces a new policy record with a single
segment covering the full renewal term.

**Policy invoices.** Optionally send `invoicePlan`, a fully explicit
keep/void/create plan. Nothing is defaulted or inferred; omission posts no
invoices on the new renewal term.

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




## OpenAPI

````yaml /openapi/generated-external-api.yaml post /api/v1/companies/{companyId}/policies/transaction/renew
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/renew:
    post:
      tags:
        - Field Model Policy Transactions
      summary: Renew Policy Transaction
      description: >
        Creates a new policy via a RENEW transaction, linking it to a previous
        policy.

        RENEW is NEW_BUSINESS plus a renewal link: the new policy term must
        start on or

        after the previous policy's end date.


        The request body is the complete initial policy state in `data`, exactly
        like

        NEW_BUSINESS. **Term bounds and the renewal link all live at the policy
        root** —

        `policyStartDate`, `policyEndDate` and `previousPolicy` are read from
        `data`. There are

        no top-level parameters. The transaction produces a new policy record
        with a single

        segment covering the full renewal term.


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

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

        invoices on the new renewal term.


        **Required permission:** `company.policy:create`
      operationId: renewPolicyTransaction
      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 renewal policy's policy-level fields, at the top level
                    of this object.

                    Must include `policyStatus`, `policyStartDate`,
                    `policyEndDate` and

                    `previousPolicy`. 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
                    - previousPolicy
                  properties:
                    policyStatus:
                      type: string
                      enum:
                        - active
                        - cancelled
                      description: >
                        Segment-scoped policy status (lowercase). `active` for
                        the whole renewal

                        term. A plain per-segment field.
                    policyStartDate:
                      description: >
                        Renewal term start date — the lower term bound. Must be
                        on or after the

                        previous policy's end date. Accepts either:

                        - An ISO date string (e.g. `"2026-01-01"` or
                        `"2026-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`.
                        - A structured date object with explicit
                        day/month/year/timezone fields.
                      oneOf:
                        - type: string
                          format: date
                        - $ref: '#/components/schemas/Fmv1Date'
                    policyEndDate:
                      description: >
                        Renewal term end date — the upper term bound. Must be
                        after

                        `policyStartDate`. Same accepted forms as
                        `policyStartDate`.
                      oneOf:
                        - type: string
                          format: date
                        - $ref: '#/components/schemas/Fmv1Date'
                    previousPolicy:
                      type: string
                      format: uuid
                      description: >
                        The ID of the policy being renewed — the renewal lineage
                        link. Required

                        for RENEW. Must be an existing policy with at least one
                        transaction; the

                        new policy is linked to it. This link — and the

                        `Policy<N:1:previousPolicy>Policy` relationship it
                        writes — is

                        the only record of the renewal chain.
                    policyNumber:
                      type: string
                      description: >
                        The renewal term's policy number. Invariant across every
                        segment of the

                        term. Omit it when your configuration mints one.
                    fullTermPricingInfo:
                      type: object
                      description: >
                        The renewal term's 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
                        renewal term. Caller-supplied.
                      additionalProperties: true
                  additionalProperties: true
                invoicePlan:
                  $ref: '#/components/schemas/PolicyInvoiceTransactionPlan'
            examples:
              annualRenewal:
                summary: Annual policy renewal
                value:
                  data:
                    policyStatus: active
                    annualPremium: 90000
                    policyStartDate:
                      year: 2026
                      month: 1
                      day: 1
                      timezone: America/New_York
                    policyEndDate:
                      year: 2027
                      month: 1
                      day: 1
                      timezone: America/New_York
                    previousPolicy: 550e8400-e29b-41d4-a716-446655440001
                    fullTermPricingInfo:
                      pricingComponents:
                        - label: Policy Premium
                          group: Policy Invoice
                          kind: Premium
                          value: 90000
                        - 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: Renewal policy created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyTransactionVersionResponse'
              examples:
                success:
                  summary: Renewal transaction response
                  value:
                    policyId: 550e8400-e29b-41d4-a716-446655440060
                    policyVersion: 1
                    transactionId: 550e8400-e29b-41d4-a716-446655440061
                    startDate: '2026-01-01'
                    endDate: '2027-01-01'
                    createdAt: '2025-12-15T10:30:00.000Z'
                    primaryInsuredName: Mercy General Hospital
                    primaryInsuredId: 550e8400-e29b-41d4-a716-446655440010
                    policyNumber: POL-2026-000456
                    policyStartDate:
                      year: 2026
                      month: 1
                      day: 1
                      timezone: America/New_York
                    policyEndDate:
                      year: 2027
                      month: 1
                      day: 1
                      timezone: America/New_York
                    fullTermPricingInfo:
                      premium: 90000
                      taxes: 0
                      fees: 500
                      brokerCommission: 0
                      programCommission: 0
                      pricingComponents:
                        - label: Policy Premium
                          group: Policy Invoice
                          kind: Premium
                          earningBasis: null
                          value: 90000
                        - label: Policy Fee
                          group: Policy Invoice
                          kind: Fees
                          earningBasis: null
                          value: 500
                    fullTermPolicyRatingResult: null
                    segments:
                      - startDate: '2026-01-01'
                        endDate: '2027-01-01'
                        data:
                          policyStatus: active
                          policyNumber: POL-2026-000456
                          policyStartDate:
                            year: 2026
                            month: 1
                            day: 1
                            timezone: America/New_York
                          policyEndDate:
                            year: 2027
                            month: 1
                            day: 1
                            timezone: America/New_York
                          previousPolicy: 550e8400-e29b-41d4-a716-446655440001
                          primaryInsuredId: 550e8400-e29b-41d4-a716-446655440010
                          primaryInsuredName: Mercy General Hospital
                          annualPremium: 90000
                          fullTermPricingInfo:
                            premium: 90000
                            taxes: 0
                            fees: 500
                            brokerCommission: 0
                            programCommission: 0
                            pricingComponents:
                              - label: Policy Premium
                                group: Policy Invoice
                                kind: Premium
                                earningBasis: null
                                value: 90000
                              - 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
                startDateBeforePreviousEnd:
                  summary: Renewal starts before previous policy ends
                  value:
                    error:
                      code: InvalidRequest
                      message: >-
                        policyStartDate (2025-06-01) must be >= previous policy
                        end date (2025-12-31)
                missingPreviousPolicy:
                  summary: previousPolicy missing from the policy root
                  value:
                    error:
                      code: InvalidRequest
                      message: previousPolicy is required for RENEW (uuid)
                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)
                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: Previous policy or an invoice referenced by invoicePlan not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                previousPolicyNotFound:
                  summary: Previous policy does not exist
                  value:
                    error:
                      code: NOT_FOUND
                      message: Policy 550e8400-e29b-41d4-a716-446655440099 not found
        '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.

````