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

# Create Entity Batch

> Creates a linked set of new records in one request: exposures,
submissions, and new-business or renewal quotes. Every record is saved,
or none is: a refused record leaves nothing behind.

Each entry names itself with `ref`: 1 to 64 letters, digits, `-` or `_`,
unique in the batch. A later entry links to it by writing
`"ref:<name>"` where a record id goes: in a relationship field, such as a
quote's `referencingSubmission`, or as the `id` of an embedded exposure.
Entries save in the order they are listed, so a link must name an earlier
entry of the type the field holds, in a field the caller can write;
anything else returns `400 INVALID_BATCH_REFERENCE` before anything is
saved. Text in any other field that starts with `ref:` stays text. The
response gives each entry's new `id`, in request order.

Each entry is saved as [Create Entity](/api-reference/entities/create-entity)
saves one record, with the same checks and refusals. A refused entry
answers with the error that create would return, plus `entity`, which
names the entry's `index`, `ref` and `entityType`, and nothing is saved.

**Idempotency.** A save needs `batchCreateOptions.idempotencyKey`, a
UUID. Sending the same body again with the same key returns `201` with
the same ids and `created: false`, and saves nothing. The same key with a
different body, or for a batch whose records have since been deleted,
returns `409 IDEMPOTENCY_KEY_REUSED`.

**Dry run.** `?dryRun=true` runs every check a save runs and saves
nothing. It returns `200` with each entry's `ref` and `entityType` when
the save would succeed, or the error the save would return. A dry run
takes no idempotency key.

**Entries.** An entry takes `entityData` as Create Entity does and, for a
quote, `entityCreateOptions.autoAddForms`. The batch has one key, so an
entry takes no `idempotencyKey` or `idempotencyOwner` of its own, and no
`pricingSetup`: set a quote's pricing setup once the batch is saved. A
batch creates no endorsement, cancellation or reinstatement quotes, which
change an existing policy. A batch holds up to 2,100 entries.

Work that follows a save, such as a quote's recommended forms and
automatic OFAC screening, starts once the whole batch is saved. A refused
batch or a dry run starts none.

See [Batch create](/api-reference/entities/overview#batch-create).

**Required permission:** the create permission of every entity type in
the batch: `exposure.create`, `submission.create` and `quote.create` for
a batch that holds all three.




## OpenAPI

````yaml /openapi/generated-external-api.yaml post /api/v1/companies/{companyId}/entities/batch
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}/entities/batch:
    post:
      tags:
        - Entities
      summary: Create Entity Batch
      description: >
        Creates a linked set of new records in one request: exposures,

        submissions, and new-business or renewal quotes. Every record is saved,

        or none is: a refused record leaves nothing behind.


        Each entry names itself with `ref`: 1 to 64 letters, digits, `-` or `_`,

        unique in the batch. A later entry links to it by writing

        `"ref:<name>"` where a record id goes: in a relationship field, such as
        a

        quote's `referencingSubmission`, or as the `id` of an embedded exposure.

        Entries save in the order they are listed, so a link must name an
        earlier

        entry of the type the field holds, in a field the caller can write;

        anything else returns `400 INVALID_BATCH_REFERENCE` before anything is

        saved. Text in any other field that starts with `ref:` stays text. The

        response gives each entry's new `id`, in request order.


        Each entry is saved as [Create
        Entity](/api-reference/entities/create-entity)

        saves one record, with the same checks and refusals. A refused entry

        answers with the error that create would return, plus `entity`, which

        names the entry's `index`, `ref` and `entityType`, and nothing is saved.


        **Idempotency.** A save needs `batchCreateOptions.idempotencyKey`, a

        UUID. Sending the same body again with the same key returns `201` with

        the same ids and `created: false`, and saves nothing. The same key with
        a

        different body, or for a batch whose records have since been deleted,

        returns `409 IDEMPOTENCY_KEY_REUSED`.


        **Dry run.** `?dryRun=true` runs every check a save runs and saves

        nothing. It returns `200` with each entry's `ref` and `entityType` when

        the save would succeed, or the error the save would return. A dry run

        takes no idempotency key.


        **Entries.** An entry takes `entityData` as Create Entity does and, for
        a

        quote, `entityCreateOptions.autoAddForms`. The batch has one key, so an

        entry takes no `idempotencyKey` or `idempotencyOwner` of its own, and no

        `pricingSetup`: set a quote's pricing setup once the batch is saved. A

        batch creates no endorsement, cancellation or reinstatement quotes,
        which

        change an existing policy. A batch holds up to 2,100 entries.


        Work that follows a save, such as a quote's recommended forms and

        automatic OFAC screening, starts once the whole batch is saved. A
        refused

        batch or a dry run starts none.


        See [Batch create](/api-reference/entities/overview#batch-create).


        **Required permission:** the create permission of every entity type in

        the batch: `exposure.create`, `submission.create` and `quote.create` for

        a batch that holds all three.
      operationId: createEntityBatch
      parameters:
        - $ref: '#/components/parameters/companyId'
        - name: dryRun
          in: query
          required: false
          schema:
            type: boolean
          description: |
            `true` checks the batch exactly as a save would, and saves nothing.
            Leave it out to save. Any other value returns `400 INVALID_DRY_RUN`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - entities
              properties:
                entities:
                  type: array
                  minItems: 1
                  maxItems: 2100
                  description: The records to create, saved in this order.
                  items:
                    type: object
                    additionalProperties: false
                    required:
                      - ref
                      - entityType
                      - entityData
                    properties:
                      ref:
                        type: string
                        pattern: ^[A-Za-z0-9_-]{1,64}$
                        description: >-
                          The entry's name in this batch. A later entry links to
                          it as "ref:<name>".
                      entityType:
                        type: string
                        enum:
                          - exposure
                          - submission
                          - quote
                      entityData:
                        type: object
                        additionalProperties: true
                        description: >-
                          The record's fields, keyed by field referenceId, as
                          Create Entity takes them. Where a record id goes, a
                          "ref:<name>" links to an earlier entry.
                      entityCreateOptions:
                        type: object
                        additionalProperties: false
                        properties:
                          autoAddForms:
                            type: boolean
                            description: >-
                              Quotes only. False creates the quote without its
                              recommended forms; true, the default, adds them
                              once the batch is saved.
                batchCreateOptions:
                  type: object
                  additionalProperties: false
                  properties:
                    idempotencyKey:
                      type: string
                      format: uuid
                      description: >-
                        Required for a save, refused on a dry run. A retry with
                        the same key and body returns the same ids.
            examples:
              submissionGraph:
                summary: An insured, its submission and a quote, linked
                value:
                  entities:
                    - ref: insured
                      entityType: exposure
                      entityData:
                        exposureName: Acme Corp HQ
                        exposureType: company
                    - ref: submission
                      entityType: submission
                      entityData:
                        submissionType: newBusiness
                    - ref: quote
                      entityType: quote
                      entityData:
                        quoteType: newBusiness
                        referencingSubmission: ref:submission
                        exposures:
                          - id: ref:insured
                            policyRelationshipType: primary
                      entityCreateOptions:
                        autoAddForms: false
                  batchCreateOptions:
                    idempotencyKey: 7f3c9a2e-4b1d-4c8e-9f6a-2d5b8e1c0a47
              dryRun:
                summary: Check a batch without saving it (with ?dryRun=true)
                value:
                  entities:
                    - ref: insured
                      entityType: exposure
                      entityData:
                        exposureName: Acme Corp HQ
                        exposureType: company
      responses:
        '200':
          description: 'Dry run: the batch would be saved. Nothing was saved.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  dryRun:
                    type: boolean
                    enum:
                      - true
                  entities:
                    type: array
                    items:
                      type: object
                      properties:
                        ref:
                          type: string
                        entityType:
                          type: string
              examples:
                checked:
                  summary: The batch passed every check
                  value:
                    dryRun: true
                    entities:
                      - ref: insured
                        entityType: exposure
        '201':
          description: Every record was created, or a retry replayed them.
          content:
            application/json:
              schema:
                type: object
                properties:
                  created:
                    type: boolean
                    description: >-
                      True when this request created the records; false for a
                      retry with the same key, which created nothing.
                  entities:
                    type: array
                    description: Each entry's new record, in request order.
                    items:
                      type: object
                      properties:
                        ref:
                          type: string
                        entityType:
                          type: string
                        id:
                          type: string
                          format: uuid
              examples:
                saved:
                  summary: The linked records were created
                  value:
                    created: true
                    entities:
                      - ref: insured
                        entityType: exposure
                        id: 550e8400-e29b-41d4-a716-446655440201
                      - ref: submission
                        entityType: submission
                        id: 550e8400-e29b-41d4-a716-446655440100
                      - ref: quote
                        entityType: quote
                        id: 550e8400-e29b-41d4-a716-446655440301
        '400':
          description: |
            Nothing was saved. A refused entry answers with the error Create
            Entity would return for it, plus `entity`. The batch's own refusals:
            `INVALID_BATCH_REFERENCE` (a bad `ref` or link),
            `INVALID_BATCH_ENTRY` (an entity or quote type a batch does not
            create), `ENTITY_BATCH_TOO_LARGE`, `IDEMPOTENCY_KEY_REQUIRED`,
            `INVALID_DRY_RUN`, and the body refusals of Create Entity
            (`INVALID_BODY`, `ENTITY_DATA_REQUIRED`, `ENTITY_OPTION_MOVED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EntityBatchErrorResponse'
              examples:
                refusedEntry:
                  summary: An entry Create Entity would refuse
                  value:
                    error:
                      code: InvalidEntityShape
                      message: 'fieldModelV1Data: ''exposureType'' is required but null'
                      userMessages:
                        - '''exposureType'' is required but null'
                      details:
                        - field: fieldModelV1Data
                          message: '''exposureType'' is required but null'
                      entity:
                        index: 0
                        ref: insured
                        entityType: exposure
                linkToLaterEntry:
                  summary: A link to an entry listed after it
                  value:
                    error:
                      code: INVALID_BATCH_REFERENCE
                      message: >-
                        entities[1].entityData.referencingSubmission links to
                        "submission", which comes later in the batch: link only
                        to an earlier entry.
                      userMessages:
                        - >-
                          entities[1].entityData.referencingSubmission links to
                          "submission", which comes later in the batch: link
                          only to an earlier entry.
                      entity:
                        index: 1
                        ref: quote
                        entityType: quote
                endorsementQuote:
                  summary: A quote type a batch does not create
                  value:
                    error:
                      code: INVALID_BATCH_ENTRY
                      message: >-
                        entities[2] has quoteType endorsement: a batch creates
                        new-business and renewal quotes, since the others change
                        an existing policy.
                      userMessages:
                        - >-
                          entities[2] has quoteType endorsement: a batch creates
                          new-business and renewal quotes, since the others
                          change an existing policy.
                      entity:
                        index: 2
                        ref: quote
                        entityType: quote
                keyRequired:
                  summary: A save without an idempotency key
                  value:
                    error:
                      code: IDEMPOTENCY_KEY_REQUIRED
                      message: >-
                        A batch save needs batchCreateOptions.idempotencyKey, so
                        that a retry replays it instead of saving every record
                        twice.
                      userMessages:
                        - >-
                          A batch save needs batchCreateOptions.idempotencyKey,
                          so that a retry replays it instead of saving every
                          record twice.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: >-
            The idempotency key was already used for a different batch, or its
            batch's records have since been deleted (`IDEMPOTENCY_KEY_REUSED`).
            Nothing was saved. Send a new key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                keyReused:
                  summary: The key was used for a different batch
                  value:
                    error:
                      code: IDEMPOTENCY_KEY_REUSED
                      message: >-
                        This idempotency key was already used for a different
                        batch.
                      userMessages:
                        - >-
                          This idempotency key was already used for a different
                          batch.
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  parameters:
    companyId:
      name: companyId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Company identifier
  schemas:
    EntityBatchErrorResponse:
      type: object
      description: >-
        A refused batch create. Nothing was saved. When one entry is refused,
        the error is the one Create Entity returns for that record, with
        `entity` naming the entry.
      required:
        - error
      additionalProperties: false
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code.
            message:
              type: string
              description: Human-readable error message.
            userMessages:
              type: array
              description: Clean messages suitable for displaying to an end user.
              items:
                type: string
            details:
              type: array
              description: Field-level errors, as Create Entity returns them.
              items:
                type: object
                properties:
                  field:
                    type: string
                  code:
                    type: string
                  reason:
                    type: string
                  expected:
                    type: string
                  message:
                    type: string
            entity:
              type: object
              description: >-
                The refused entry. Absent when the refusal is about the batch as
                a whole, such as a missing key.
              properties:
                index:
                  type: integer
                  description: The entry's position in `entities`, from 0.
                ref:
                  type: string
                  description: The entry's `ref`.
                entityType:
                  type: string
                  description: The entry's `entityType`.
    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
  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.

````

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