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

# Import Entity

> Imports one record from another system, or one spreadsheet row sent as JSON,
as a claim (`Event`), exposure, quote, submission, person, or organization,
mapping your source fields with `transformations` and checking them with
`guards`. Use it to load or migrate records one at a time with an immediate
result; for a bulk load, store the rows with Import Rows
(`ingestFmv1ImportRows`) and map them with Queue Import Job
(`queueFmv1ImportJob`). The row is stored even when the import fails, so fix
it with Retry Import (`retryFmv1Import`) rather than sending it again.

Imports one record from another system as an FMV1 entity, in the shape you
hold it rather than the company's field model.

1. **`data` is stored as an import row**, as sent, before anything else can
   fail.
2. The **transformations** turn `data.<entityKey>` into an entity in this
   company's field model.
3. The **guards** run against the transformed entity.
4. If both succeeded, the entity is **created**, or **updated** when the
   transformed entity carries an `id`. Keys the field model does not declare
   are dropped first; the write is then held to every rule an ordinary
   entity create or update is, including the company's own invariants.

Every request that gets past validation stores its row and answers `201`
with the **import attempt** recording each step, whether or not the entity
was written: check `importAttempt.writeResult`. A refused write is reported
there as the error the entity endpoint would have answered with. The attempt
is the one Get Import Attempt returns; the request's `importBatch` is its
`attemptBatch`.

The attempt is recorded before the transformations run, and each step's
result is stored on it as the step completes. The entity write and its
`writeResult` commit together, so if the request fails part-way (a `5xx`
or a dropped connection), read the row's attempts: one whose guards passed
and whose `writeResult` is `null` wrote nothing, and retrying it cannot
leave two entities.

A malformed request is a `400`, and stores nothing.

There is no `Idempotency-Key`: sending the same request twice stores two
rows, and may write twice. To try a stored row again, retry it rather than
sending the request again.

**Required permission:** `<entityType>.import` for the request's
`entityType`, such as `submission.import` to import a Submission. The
permission is the target entity type's own `import` verb; one type's
permission does not import another type.




## OpenAPI

````yaml /openapi/generated-external-api.yaml post /api/v1/companies/{companyId}/imports
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}/imports:
    post:
      tags:
        - Imports
      summary: Import Entity
      description: >
        Imports one record from another system, or one spreadsheet row sent as
        JSON,

        as a claim (`Event`), exposure, quote, submission, person, or
        organization,

        mapping your source fields with `transformations` and checking them with

        `guards`. Use it to load or migrate records one at a time with an
        immediate

        result; for a bulk load, store the rows with Import Rows

        (`ingestFmv1ImportRows`) and map them with Queue Import Job

        (`queueFmv1ImportJob`). The row is stored even when the import fails, so
        fix

        it with Retry Import (`retryFmv1Import`) rather than sending it again.


        Imports one record from another system as an FMV1 entity, in the shape
        you

        hold it rather than the company's field model.


        1. **`data` is stored as an import row**, as sent, before anything else
        can
           fail.
        2. The **transformations** turn `data.<entityKey>` into an entity in
        this
           company's field model.
        3. The **guards** run against the transformed entity.

        4. If both succeeded, the entity is **created**, or **updated** when the
           transformed entity carries an `id`. Keys the field model does not declare
           are dropped first; the write is then held to every rule an ordinary
           entity create or update is, including the company's own invariants.

        Every request that gets past validation stores its row and answers `201`

        with the **import attempt** recording each step, whether or not the
        entity

        was written: check `importAttempt.writeResult`. A refused write is
        reported

        there as the error the entity endpoint would have answered with. The
        attempt

        is the one Get Import Attempt returns; the request's `importBatch` is
        its

        `attemptBatch`.


        The attempt is recorded before the transformations run, and each step's

        result is stored on it as the step completes. The entity write and its

        `writeResult` commit together, so if the request fails part-way (a `5xx`

        or a dropped connection), read the row's attempts: one whose guards
        passed

        and whose `writeResult` is `null` wrote nothing, and retrying it cannot

        leave two entities.


        A malformed request is a `400`, and stores nothing.


        There is no `Idempotency-Key`: sending the same request twice stores two

        rows, and may write twice. To try a stored row again, retry it rather
        than

        sending the request again.


        **Required permission:** `<entityType>.import` for the request's

        `entityType`, such as `submission.import` to import a Submission. The

        permission is the target entity type's own `import` verb; one type's

        permission does not import another type.
      operationId: createFmv1Import
      parameters:
        - $ref: '#/components/parameters/companyId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImportRequest'
            examples:
              create:
                summary: Create a submission, renaming a source field
                value:
                  entityType: Submission
                  data:
                    submission:
                      name: Acme Logistics
                      sourceSystemCode: SUB-1042
                  transformations:
                    submissionName: submission.name
                  importBatch: october-load
              update:
                summary: Update the entity a transformed id names
                value:
                  entityType: Submission
                  data:
                    submission:
                      name: Acme Logistics LLC
                    source:
                      fmv1Id: 6e2b8f14-3a7c-4d9e-b051-2c8a9f7d4e13
                  transformations:
                    id: source.fmv1Id
                    submissionName: submission.name
                  importBatch: october-renames
              updateViaLookup:
                summary: Update the entity LOOKUP finds by a field value
                description: >
                  `LOOKUP(entityType, filter)` returns the id of the one entity
                  whose

                  fields equal the filter, or `null` when none does (which
                  creates one

                  instead). Several matches fail the transformation.
                value:
                  entityType: Organization
                  data:
                    organization:
                      name: Acme Logistics LLC
                      taxId: 12-3456789
                  transformations:
                    id: 'LOOKUP(''Organization'', { taxId: organization.taxId })'
                  importBatch: october-renames
              mapOverWithAncillaryData:
                summary: Map a list of child objects and read ancillary data
                value:
                  entityType: Submission
                  data:
                    submission:
                      name: Acme Logistics
                      sites:
                        - region: CA
                          sqft: 12000
                        - region: NV
                          sqft: 8000
                    broker:
                      email: broker@example.com
                  transformations:
                    submissionName: submission.name
                    brokerEmail: broker.email
                    locations:
                      mapOver: submission.sites
                      values:
                        state: region
                        squareFootage: me.sqft
                  guards:
                    - condition: submissionName != null
                      errorMessage: A submission needs a name.
                  importBatch: october-load
              guardRefused:
                summary: A guard that refuses the record
                value:
                  entityType: Submission
                  data:
                    submission:
                      name: Acme Logistics
                      status: declined
                  guards:
                    - condition: status != 'declined'
                      errorMessage: Declined submissions are not imported.
                  importBatch: october-load
              transformationFailed:
                summary: A transformation that fails
                value:
                  entityType: Submission
                  data:
                    submission:
                      name: Acme Logistics
                      site:
                        region: CA
                  transformations:
                    locations:
                      mapOver: submission.site
                      values:
                        state: region
                  importBatch: october-load
      responses:
        '201':
          description: |
            The row was stored and an attempt recorded. Whether the entity was
            written is the attempt's `writeResult`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportResponse'
              examples:
                created:
                  summary: The entity was created
                  value:
                    importRowId: 9a1d4e7b-2c3f-4b8a-8d61-0e5f2a7b3c94
                    importAttempt:
                      id: 3f6c2a1e-8b4d-4c7a-9e21-5d0b7a9c1f42
                      importRowId: 9a1d4e7b-2c3f-4b8a-8d61-0e5f2a7b3c94
                      entityType: Submission
                      action: create
                      attemptBatch: october-load
                      transformations:
                        submissionName: submission.name
                      guards: []
                      transformationResult:
                        status: ok
                        entity:
                          name: Acme Logistics
                          sourceSystemCode: SUB-1042
                          submissionName: Acme Logistics
                      guardResult:
                        passed: true
                      writeResult:
                        status: ok
                        entityId: 6e2b8f14-3a7c-4d9e-b051-2c8a9f7d4e13
                        created: true
                      createdAt: '2026-10-23T14:58:02.087Z'
                      updatedAt: '2026-10-23T14:58:02.471Z'
                updated:
                  summary: The entity named by the transformed id was updated
                  value:
                    importRowId: 2c8e5a1f-7d3b-4f9a-b6e2-1a4d8c7f3e59
                    importAttempt:
                      id: 5d9a3e7c-1b4f-4a8e-9c62-8f0e2b7d4a13
                      importRowId: 2c8e5a1f-7d3b-4f9a-b6e2-1a4d8c7f3e59
                      entityType: Submission
                      action: update
                      attemptBatch: october-renames
                      transformations:
                        id: source.fmv1Id
                        submissionName: submission.name
                      guards: []
                      transformationResult:
                        status: ok
                        entity:
                          id: 6e2b8f14-3a7c-4d9e-b051-2c8a9f7d4e13
                          name: Acme Logistics LLC
                          submissionName: Acme Logistics LLC
                      guardResult:
                        passed: true
                      writeResult:
                        status: ok
                        entityId: 6e2b8f14-3a7c-4d9e-b051-2c8a9f7d4e13
                        created: false
                      createdAt: '2026-10-23T15:02:11.540Z'
                      updatedAt: '2026-10-23T15:02:11.924Z'
                updatedViaLookup:
                  summary: The entity LOOKUP found was updated
                  value:
                    importRowId: 5e1c8a4f-3b7d-4e2a-9f61-8d2b4c7e1a39
                    importAttempt:
                      id: 7c4a1e9d-2f6b-4d8a-b3e5-1a9c7f2d4b60
                      importRowId: 5e1c8a4f-3b7d-4e2a-9f61-8d2b4c7e1a39
                      entityType: Organization
                      action: update
                      attemptBatch: october-renames
                      transformations:
                        id: 'LOOKUP(''Organization'', { taxId: organization.taxId })'
                      guards: []
                      transformationResult:
                        status: ok
                        entity:
                          id: 4b9e2d7a-1c5f-4a3e-8d62-9f1b3e7c2a85
                          name: Acme Logistics LLC
                          taxId: 12-3456789
                      guardResult:
                        passed: true
                      writeResult:
                        status: ok
                        entityId: 4b9e2d7a-1c5f-4a3e-8d62-9f1b3e7c2a85
                        created: false
                      createdAt: '2026-10-23T15:03:26.114Z'
                      updatedAt: '2026-10-23T15:03:26.498Z'
                mappedWithAncillaryData:
                  summary: A mapped list and ancillary data, created
                  value:
                    importRowId: 7b3f1c9e-4a2d-4e8b-a7c5-3d1f9e6b2a80
                    importAttempt:
                      id: 8e4c2a6f-9d1b-4c3e-b8a7-5f2d1e9c4b36
                      importRowId: 7b3f1c9e-4a2d-4e8b-a7c5-3d1f9e6b2a80
                      entityType: Submission
                      action: create
                      attemptBatch: october-load
                      transformations:
                        submissionName: submission.name
                        brokerEmail: broker.email
                        locations:
                          mapOver: submission.sites
                          values:
                            state: region
                            squareFootage: me.sqft
                      guards:
                        - condition: submissionName != null
                          errorMessage: A submission needs a name.
                      transformationResult:
                        status: ok
                        entity:
                          name: Acme Logistics
                          sites:
                            - region: CA
                              sqft: 12000
                            - region: NV
                              sqft: 8000
                          submissionName: Acme Logistics
                          brokerEmail: broker@example.com
                          locations:
                            - state: CA
                              squareFootage: 12000
                            - state: NV
                              squareFootage: 8000
                      guardResult:
                        passed: true
                      writeResult:
                        status: ok
                        entityId: 1f8d3b7a-6e2c-4a9d-8b51-4c7e2a9f3d06
                        created: true
                      createdAt: '2026-10-23T15:04:37.902Z'
                      updatedAt: '2026-10-23T15:04:38.286Z'
                guardRefused:
                  summary: A guard refused the record, so nothing was written
                  value:
                    importRowId: 4e7a2d9c-3b1f-4c6e-9a85-2f8b1d7e3c41
                    importAttempt:
                      id: 6a2f8c4e-1d9b-4e7a-b3c6-9e5d2a8f1b74
                      importRowId: 4e7a2d9c-3b1f-4c6e-9a85-2f8b1d7e3c41
                      entityType: Submission
                      action: create
                      attemptBatch: october-load
                      transformations: {}
                      guards:
                        - condition: status != 'declined'
                          errorMessage: Declined submissions are not imported.
                      transformationResult:
                        status: ok
                        entity:
                          name: Acme Logistics
                          status: declined
                      guardResult:
                        passed: false
                        failures:
                          - index: 0
                            errorMessage: Declined submissions are not imported.
                            reason: refused
                      writeResult: null
                      createdAt: '2026-10-23T15:06:12.318Z'
                      updatedAt: '2026-10-23T15:06:12.702Z'
                transformationFailed:
                  summary: A transformation failed, so nothing ran after it
                  value:
                    importRowId: 9c5e1a3d-7f2b-4d8e-a6c4-1b9f3e7d2a58
                    importAttempt:
                      id: 1b7e9d3a-6c2f-4e8b-a5d0-7f3c1e9b2a68
                      importRowId: 9c5e1a3d-7f2b-4d8e-a6c4-1b9f3e7d2a58
                      entityType: Submission
                      action: null
                      attemptBatch: october-load
                      transformations:
                        locations:
                          mapOver: submission.site
                          values:
                            state: region
                      guards: []
                      transformationResult:
                        status: failed
                        entity:
                          name: Acme Logistics
                          site:
                            region: CA
                        errors:
                          - field: locations
                            code: IMPORT_MAP_OVER_NOT_A_LIST
                            message: >-
                              mapOver path 'submission.site' must resolve to a
                              list in data; found an object
                      guardResult: null
                      writeResult: null
                      createdAt: '2026-10-23T15:07:48.661Z'
                      updatedAt: '2026-10-23T15:07:49.045Z'
                writeRefused:
                  summary: The write was refused by one of the company's invariants
                  value:
                    importRowId: 3a9f7c1e-2d6b-4e8a-9b45-7c1e3f9d2b60
                    importAttempt:
                      id: 2d6b9f3a-8e1c-4a7d-b2e9-6f4c1a8d3e57
                      importRowId: 3a9f7c1e-2d6b-4e8a-9b45-7c1e3f9d2b60
                      entityType: Submission
                      action: create
                      attemptBatch: october-load
                      transformations: {}
                      guards: []
                      transformationResult:
                        status: ok
                        entity:
                          submissionName: Acme Logistics
                          effectiveDate: '2026-01-01'
                          expirationDate: '2025-01-01'
                      guardResult:
                        passed: true
                      writeResult:
                        status: failed
                        httpStatus: 400
                        code: TenantInvariantViolation
                        message: >-
                          fieldModelV1Data: The expiration date must be after
                          the effective date.
                        userMessages:
                          - >-
                            The expiration date must be after the effective
                            date.
                        details:
                          - field: fieldModelV1Data
                            message: >-
                              The expiration date must be after the effective
                              date.
                      createdAt: '2026-10-23T15:09:03.215Z'
                      updatedAt: '2026-10-23T15:09:03.599Z'
        '400':
          description: >
            Bad Request — the request is malformed, and nothing was stored: an

            `entityType` that cannot be imported (a Policy included), `data`
            that is

            not an object, a transformation or guard of the wrong shape, a blank

            `importBatch`, a body key this endpoint does not take, or any query

            parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidEntityType:
                  summary: An entity type that cannot be imported
                  value:
                    error:
                      code: INVALID_ENTITY_TYPE
                      message: >-
                        Invalid entityType: must be one of Event, Exposure,
                        Quote, Submission, Person, Organization. Policies cannot
                        be imported.
                      userMessages:
                        - >-
                          Invalid entityType: must be one of Event, Exposure,
                          Quote, Submission, Person, Organization. Policies
                          cannot be imported.
                unknownBodyKey:
                  summary: A body key this endpoint does not take
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: 'Unrecognized key: "attemptBatch"'
                      userMessages:
                        - 'Unrecognized key: "attemptBatch"'
                      details:
                        - message: 'Unrecognized key: "attemptBatch"'
                guardWithoutCondition:
                  summary: A guard without a condition
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: An import guard needs a condition.
                      userMessages:
                        - An import guard needs a condition.
                      details:
                        - field: guards.0.condition
                          message: An import guard needs a condition.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
components:
  parameters:
    companyId:
      name: companyId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Company identifier
  schemas:
    ImportRequest:
      type: object
      description: >
        One record to import. `data` is stored as an import row exactly as sent,
        before

        anything else can fail; the transformations and guards then run against
        it, and

        the entity is created or updated.
      required:
        - entityType
        - data
      additionalProperties: false
      properties:
        entityType:
          type: string
          enum:
            - Event
            - Exposure
            - Quote
            - Submission
            - Person
            - Organization
          description: >
            The entity type to import, in PascalCase. Policies and policy
            transactions

            cannot be imported.
        data:
          type: object
          additionalProperties: true
          description: >
            The source data. The entity lives under its **entity key**, the
            entity type

            in camelCase (`data.submission` for a Submission). Every other
            top-level

            key is ancillary data, such as `data.broker`, that transformations
            can read

            by name and that is never written to the entity.
        transformations:
          allOf:
            - $ref: '#/components/schemas/ImportTransformations'
          default: {}
        guards:
          allOf:
            - $ref: '#/components/schemas/ImportGuards'
          default: []
        importBatch:
          type: string
          nullable: true
          description: >
            Your key grouping requests for later review, such as one load's
            name.

            Stored on the import row, and as the `attemptBatch` of the attempt
            this

            request records. Omit it or send `null` for none; a blank key is
            refused.
    ImportResponse:
      type: object
      description: The stored import row's id and the attempt this request recorded.
      required:
        - importRowId
        - importAttempt
      properties:
        importRowId:
          type: string
          format: uuid
          description: >
            The import row storing `data` as sent. Read it with Get Import Row;
            a failed

            import is fixed by retrying this row, not by sending the data again.
        importAttempt:
          $ref: '#/components/schemas/ImportAttempt'
    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
    ImportTransformations:
      type: object
      description: >
        How `data.<entityKey>` becomes an entity in this company's field model:
        one

        entry per field reference id (camelCase). Each value is either a JEXL

        expression string that reads the data's top-level keys by name

        (`submission.name`, `broker.email`), or a mapping for a list of child

        objects:

        `{ "mapOver": "<data path>", "values": { "<childKey>": "<expression>" }
        }`.

        Inside `values`, bare names and `me` are the current element, `parent`
        is

        the object holding the list and `root` is the whole `data`. A child
        value may

        itself be a mapping; its `mapOver` path reads the current scope (for
        example

        `me.locations`). A `{ "values": { ... } }` constructor without `mapOver`
        builds

        one object in the surrounding scope and can contain mapped lists. At
        every

        depth, `root` remains the original data.


        Every field of `data.<entityKey>` without a transformation is kept as
        sent.

        A transformed entity with an `id` updates that entity; otherwise one is

        created. Keys the company's field model does not declare are dropped
        before

        an entity write. Policy jobs instead construct the whole-policy or
        single-transaction

        command envelope; envelope keys are validated by that contract.
      additionalProperties:
        oneOf:
          - type: string
            description: A JEXL expression.
          - type: object
            required:
              - mapOver
              - values
            additionalProperties: false
            properties:
              mapOver:
                type: string
                description: |
                  A dotted path into `data` that resolves to a list, such as
                  `submission.locations`; a numeric segment indexes a list.
              values:
                $ref: '#/components/schemas/ImportTransformations'
                type: object
                description: One expression or nested mapping per child object key.
          - type: object
            required:
              - values
            additionalProperties: false
            properties:
              values:
                $ref: '#/components/schemas/ImportTransformations'
                description: >-
                  Construct one object in the surrounding scope, including
                  nested mappings.
    ImportGuards:
      type: array
      description: >
        Conditions that must hold for the write to proceed, evaluated against
        the

        transformed entity, reading its fields by bare name. Only a strict
        `true`

        passes, and a condition that cannot be evaluated fails. They run in
        addition

        to the company's own entity invariants.
      items:
        type: object
        required:
          - condition
          - errorMessage
        additionalProperties: false
        properties:
          condition:
            type: string
            description: A JEXL condition.
          errorMessage:
            type: string
            description: Reported on the attempt when the condition does not hold.
    ImportAttempt:
      type: object
      description: >
        One **import attempt**: a single transform → guard → write pass over an

        import row. An `import` request records the first attempt on its row,
        and each

        `retryImport` records another. Attempts are stored whether or not the
        write

        happened.


        The attempt is recorded before its first step runs, with every result
        `null`,

        and each step's result is stored on it as the step completes:

        `transformationResult` and `action`, then `guardResult`, then
        `writeResult`.

        The `import` and `retryImport` responses answer with the finished
        attempt.


        `writeResult` is stored in the same transaction as the entity write, so
        the

        two commit together or not at all. An attempt whose `guardResult` passed
        and

        whose `writeResult` is `null` wrote no entity: it is still in progress,
        or it

        crashed before its write committed. Its import row can be retried; the
        retry

        cannot create a second entity alongside one the crashed attempt wrote.
      required:
        - id
        - importRowId
        - entityType
        - action
        - attemptBatch
        - transformations
        - guards
        - transformationResult
        - guardResult
        - writeResult
        - createdAt
        - updatedAt
      properties:
        jobId:
          type: string
          format: uuid
          nullable: true
          description: Owning transformation job, or null for a synchronous attempt.
        sourceRowIds:
          type: array
          nullable: true
          items:
            type: string
            format: uuid
          description: >-
            Every source row for this result, in evaluation order. Null for
            synchronous attempts; importRowId always identifies the first source
            row.
        id:
          type: string
          format: uuid
          description: The import attempt id.
        importRowId:
          type: string
          format: uuid
          description: The import row this attempt ran against.
        entityType:
          type: string
          enum:
            - Event
            - Exposure
            - Quote
            - Submission
            - Person
            - Organization
            - Policy
          description: >-
            The job target type, or the original row type for a synchronous
            attempt.
        action:
          type: string
          nullable: true
          enum:
            - create
            - update
            - null
          description: >
            `update` when the transformed entity carried an `id`, else `create`.

            `null` until the transformations succeed, and for good when they
            failed

            before the transformed entity existed.
        attemptBatch:
          type: string
          nullable: true
          description: >
            The caller's optional key grouping attempts. An attempt recorded by
            an

            `import` request takes that request's `importBatch`; a retry carries
            the

            `attemptBatch` it was sent with.
        transformations:
          type: object
          additionalProperties: true
          description: >
            The transformations the attempt ran with, as sent: one entry per
            FMV1

            field reference id, each a JEXL expression string or a

            `{ "mapOver": "<data path>", "values": { "<childKey>":
            "<expression>" } }`

            mapping. Stored even when they are invalid; the failure is then
            reported in

            `transformationResult`.
        guards:
          type: array
          description: |
            The guards the attempt ran with, as sent. Each is
            `{ "condition": "<JEXL>", "errorMessage": "<text>" }`.
          items: {}
        transformationResult:
          nullable: true
          description: >
            The outcome of applying the transformations; `null` until they have

            run. `status: ok` carries the

            transformed `entity`. `status: failed` carries a partial `entity`,
            with

            every failed field absent, and one entry in `errors` per failure.
          type: object
          required:
            - status
            - entity
          properties:
            status:
              type: string
              enum:
                - ok
                - failed
            entity:
              type: object
              additionalProperties: true
              description: The transformed entity, before it was written.
            errors:
              type: array
              description: Present only when `status` is `failed`.
              items:
                type: object
                required:
                  - field
                  - code
                  - message
                properties:
                  field:
                    type: string
                    description: >
                      The transformation's field reference id; empty when the
                      failure is

                      the whole input's, such as a missing entity key in `data`.
                  path:
                    type: string
                    description: >-
                      Where inside a `mapOver` field, such as
                      `locations[2].state`.
                  code:
                    type: string
                    description: >
                      Why it failed, such as `IMPORT_ENTITY_DATA_MISSING`,

                      `IMPORT_INVALID_TRANSFORMATIONS`,
                      `IMPORT_MAP_OVER_NOT_A_LIST` or

                      `JEXL_EVALUATION_ERROR`. A `LOOKUP` failure is

                      `IMPORT_LOOKUP_AMBIGUOUS` (several entities match),

                      `IMPORT_LOOKUP_FORBIDDEN` (the caller may not read the
                      entity

                      type) or `IMPORT_LOOKUP_INVALID` (arguments it cannot
                      run).
                  message:
                    type: string
        guardResult:
          nullable: true
          description: |
            The outcome of the guards; `null` until the guards have run, and for
            good when the transformations failed. `passed:
            false` lists every guard that did not hold, not only the first.
          type: object
          required:
            - passed
          properties:
            passed:
              type: boolean
            failures:
              type: array
              description: Present only when `passed` is `false`.
              items:
                type: object
                required:
                  - index
                  - errorMessage
                  - reason
                properties:
                  index:
                    type: integer
                    description: The guard's position in `guards`.
                  errorMessage:
                    type: string
                    description: >
                      For `refused`, the guard's `errorMessage`. For `error`,
                      the

                      guard could not be evaluated and the message is

                      `The entity invariant "<errorMessage>" could not be
                      checked.`
                  reason:
                    type: string
                    enum:
                      - refused
                      - error
                    description: >
                      `refused` — the condition gave anything but `true`.
                      `error` — the

                      condition could not be evaluated.
        writeResult:
          type: object
          nullable: true
          description: >
            The outcome of the create or update; `null` when no write was
            attempted,

            because the transformations or a guard failed, and until the write's

            outcome is stored. It is stored in the same transaction as the
            write, so

            `null` on an attempt whose guards passed means no entity was
            written:

            the attempt is in progress, or it crashed.


            `status: ok` names the entity written in `entityId`, and `created`
            says

            whether this attempt created it (`false`: it updated it). Policy
            writes also

            require a nonempty ordered list of committed transaction receipts.
            `status: validated` is a policy

            dry-run plan (refused for other entity types), with no entity or
            transaction IDs

            and no persisted policy writes.

            Whole-policy execution and dry runs produce these results. Both
            policy modes support execution and dry runs.

            `status: failed` is the refusal the entity create or update endpoint

            would have answered with: its `httpStatus`, and the error's `code`,

            `message`, `userMessages` and `details`.
          required:
            - status
          properties:
            status:
              type: string
              enum:
                - ok
                - failed
                - validated
            dryRun:
              type: boolean
              enum:
                - true
              description: Present only for a validated policy dry run.
            transactions:
              type: array
              minItems: 1
              description: >-
                Ordered committed receipts when status is ok; planned
                action/date entries when status is validated.
              items:
                oneOf:
                  - $ref: '#/components/schemas/PolicyImportTransactionReceipt'
                  - type: object
                    additionalProperties: false
                    required:
                      - action
                      - effectiveDate
                    properties:
                      action:
                        type: string
                        enum:
                          - NEW_BUSINESS
                          - ENDORSE
                          - CANCEL
                          - REINSTATE
                          - RENEW
                      effectiveDate:
                        type: string
                        format: date
            entityId:
              type: string
              description: Present only when `status` is `ok`.
            created:
              type: boolean
              description: Present only when `status` is `ok`.
            httpStatus:
              type: integer
              description: Present only when `status` is `failed`.
            code:
              type: string
              description: Present only when `status` is `failed`.
            message:
              type: string
              description: Present only when `status` is `failed`.
            userMessages:
              type: array
              description: Present only when `status` is `failed`.
              items:
                type: string
            details:
              type: array
              description: >
                May be present when `status` is `failed`: the same entries the
                entity

                endpoints' error responses carry.
              items:
                type: object
                required:
                  - message
                properties:
                  field:
                    type: string
                  code:
                    type: string
                  reason:
                    type: string
                  expected:
                    type: string
                  message:
                    type: string
        createdAt:
          type: string
          format: date-time
          description: When the attempt was recorded, before its first step ran.
        updatedAt:
          type: string
          format: date-time
          description: >
            When a step's result was last stored on the attempt. On an attempt
            with a

            `null` result still to come, an `updatedAt` long past means it
            crashed.
    PolicyImportTransactionReceipt:
      type: object
      additionalProperties: false
      required:
        - transactionId
        - policyId
        - policyVersion
        - action
        - effectiveDate
      properties:
        transactionId:
          type: string
          format: uuid
        policyId:
          type: string
          format: uuid
        policyVersion:
          type: integer
          minimum: 1
        action:
          type: string
          enum:
            - NEW_BUSINESS
            - ENDORSE
            - CANCEL
            - REINSTATE
            - RENEW
        effectiveDate:
          type: string
          format: date
  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.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        User-principal OAuth 2.0 Bearer authentication. Send a user-scoped Auth0
        access token (audience = the app API audience) as `Authorization: Bearer
        <jwt>`. The request resolves to the user's identity and is authorized by
        their Role on the `{companyId}` in the path — the same role-based
        permissions the web app enforces. This is the path the MCP connector
        uses to act on a user's behalf; endpoints that accept it list both
        `BearerAuth` and `ApiKeyAuth`.

````

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