> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gominerva.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Preview a file

> Queues a dry-run preview of a CSV or XLSX file; nothing is written to the working set. For multipart uploads, a tenant without the custom-list entitlement is also refused (`Custom lists are not enabled for this tenant.`). Requires an admin API key, the **Admin (tenant-wide)** key type, which only an owner or admin of this organization can create. **Workspace scoped** and **Tenant scoped** keys are refused with 403. The `x-user-token` scheme is the Minerva dashboard session token; with it, writes require an owner or admin.



## OpenAPI

````yaml /api-reference/admin-api.json post /custom-lists/v2/organizations/{orgId}/{listId}/uploads/preview/file
openapi: 3.0.0
info:
  version: 1.0.0
  title: MinervaAI Admin API
  description: Admin endpoints for the Minerva application suite.
servers:
  - url: https://api.gominerva.com
    description: The production API server for Minerva.
security:
  - ApiKeyAuth: []
tags: []
paths:
  /custom-lists/v2/organizations/{orgId}/{listId}/uploads/preview/file:
    post:
      tags:
        - Custom Lists
      summary: Preview a file
      description: >-
        Queues a dry-run preview of a CSV or XLSX file; nothing is written to
        the working set. For multipart uploads, a tenant without the custom-list
        entitlement is also refused (`Custom lists are not enabled for this
        tenant.`). Requires an admin API key, the **Admin (tenant-wide)** key
        type, which only an owner or admin of this organization can create.
        **Workspace scoped** and **Tenant scoped** keys are refused with 403.
        The `x-user-token` scheme is the Minerva dashboard session token; with
        it, writes require an owner or admin.
      parameters:
        - in: path
          name: orgId
          required: true
          schema:
            type: string
          description: >-
            The organization (tenant) id. Must equal the tenant of the admin
            key.
        - in: path
          name: listId
          required: true
          schema:
            type: string
          description: The custom list id.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CustomListFileUploadRequest'
        description: >-
          Multipart form with exactly three fields: `file` (a CSV or XLSX file
          within the tenant upload limit), `merge_mode` (`upsert_only`,
          `full_replace` or `validate_only`) and `record_id_column` (the column
          holding each record id). Any other field is 400.
      responses:
        '202':
          description: Accepted; the preview is queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomListUploadJobResponse'
              examples:
                accepted:
                  summary: The file preview is queued.
                  value:
                    data:
                      id: 5b4c3d2e-7f8a-4b5c-8d9e-7f6a5b4c3d2e
                      tenant_id: 123e4567-e89b-12d3-a456-426614174000
                      list_id: 3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c
                      status: validating
                      merge_mode: validate_only
                      record_id_column: record_uid
                      parsed_record_count: 1
                      adds: 1
                      updates: 0
                      unchanged: 0
                      archives: 0
                      preview_rows: []
                      validation_errors: []
                      job_id: 6c5d4e3f-6a7b-4c4d-9e8f-8a7b6c5d4e3f
                      created_by: 64b1c0de00000000000000a1
                      created_at: '2026-11-05T20:35:23.282Z'
                      updated_at: '2026-11-05T20:35:23.282Z'
        '400':
          description: >-
            Invalid request: a required field is missing or a value is invalid.
            Some validation errors (for example `name is required.`) are plain
            text; others (`error` is `validation_failed`) are a JSON
            `CustomListError`. Branch on `Content-Type`.
          content:
            text/plain:
              schema:
                type: string
                example: merge_mode is required.
            application/json:
              schema:
                $ref: '#/components/schemas/CustomListError'
              examples:
                validation:
                  summary: Validation failed.
                  value:
                    error: validation_failed
                    message: >-
                      custom-list: validation failed: invalid merge mode
                      "invalid-mode"
        '403':
          description: >-
            No credentials were sent; the API key was revoked, has expired, or
            its application is deactivated (`API-key authentication was
            denied.`); the key is not an admin application key (**Workspace
            scoped** and **Tenant scoped** keys are refused); it belongs to
            another organization; or its creator is no longer an owner or admin.
            For a user token, the user is not a member, or is not an owner or
            admin on a write. If the tenant is not entitled to custom lists, the
            body is a JSON `CustomListError` with `error: not_enabled` (`Custom
            lists are not enabled for this tenant.`); every other 403 is plain
            text. Branch on `Content-Type`.
          content:
            text/plain:
              schema:
                type: string
                example: 'Missing Authorization: Api-Key or x-api-key header.'
            application/json:
              schema:
                $ref: '#/components/schemas/CustomListError'
              examples:
                not-enabled:
                  summary: Tenant not entitled.
                  value:
                    error: not_enabled
                    message: Custom lists are not enabled for this tenant.
        '404':
          description: >-
            Custom list management is not enabled (`Custom list management is
            not enabled.`); the list, record, upload, job or workspace is not in
            this organization; or the application API key (`mrva-…`) is unknown
            (`API-key authentication was denied.`).
          content:
            text/plain:
              schema:
                type: string
                example: Custom list management is not enabled.
        '408':
          description: >-
            The multipart request did not complete in time (`Custom List upload
            timed out before the request was complete.`). Retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomListError'
              examples:
                timeout:
                  summary: The upload did not complete.
                  value:
                    error: upload_request_timeout
                    message: >-
                      Custom List upload timed out before the request was
                      complete.
                    retryable: true
        '413':
          description: >-
            The file exceeds the tenant's `maxUploadFileSize`, or the request
            exceeds `maxUploadRequestSize` (`Custom list limit exceeded: …`).
            JSON body with `error` and the limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomListError'
              examples:
                too-large:
                  summary: The file is too large.
                  value:
                    error: limit_exceeded
                    limit: maxUploadFileSize
                    max: 100000000
                    message: >-
                      Custom list limit exceeded: maxUploadFileSize (maximum
                      100000000).
        '429':
          description: >-
            The service is busy and upload capacity is temporarily full (`Custom
            List upload capacity is currently full. Please retry.`). Retry with
            backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomListError'
              examples:
                busy:
                  summary: Upload capacity is full.
                  value:
                    error: upload_capacity_exceeded
                    message: >-
                      Custom List upload capacity is currently full. Please
                      retry.
                    retryable: true
        '503':
          description: >-
            The authentication service is temporarily unavailable
            (`Authentication service is unavailable.`). Nothing was changed;
            retry with backoff.
          content:
            text/plain:
              schema:
                type: string
                example: Authentication service is unavailable.
      security:
        - AdminApiKeyAuth: []
        - UserTokenAuth: []
components:
  schemas:
    CustomListFileUploadRequest:
      type: object
      description: >-
        Multipart form. Only these three fields are accepted; any other field is
        400.
      required:
        - file
        - merge_mode
        - record_id_column
      properties:
        file:
          type: string
          format: binary
          description: A CSV or XLSX file within the tenant upload limit.
        merge_mode:
          type: string
          enum:
            - upsert_only
            - full_replace
            - validate_only
          description: >-
            `upsert_only` adds and updates; `full_replace` also archives records
            missing from the upload; `validate_only` checks without staging
            changes.
        record_id_column:
          type: string
    CustomListUploadJobResponse:
      type: object
      description: '`{ data: CustomListUploadJob }`'
      properties:
        data:
          $ref: '#/components/schemas/CustomListUploadJob'
      required:
        - data
    CustomListError:
      type: object
      properties:
        error:
          type: string
          description: >-
            Machine-readable code, e.g. `validation_failed`, `limit_exceeded`,
            `conflict`, `not_enabled`, `upload_capacity_exceeded`,
            `upload_request_timeout`.
        message:
          type: string
        limit:
          type: string
          description: >-
            For `limit_exceeded`: the entitlement limit, e.g.
            `maxRecordsPerList`.
        max:
          type: integer
          description: 'For `limit_exceeded`: the configured maximum.'
        retryable:
          type: boolean
      additionalProperties: true
    CustomListUploadJob:
      type: object
      properties:
        id:
          type: string
        tenant_id:
          type: string
        list_id:
          type: string
        status:
          type: string
          enum:
            - uploaded
            - validating
            - ready_for_review
            - publishing
            - published
            - failed
        merge_mode:
          type: string
          enum:
            - upsert_only
            - full_replace
            - validate_only
        record_id_column:
          type: string
        parsed_record_count:
          type: integer
        adds:
          type: integer
        updates:
          type: integer
        unchanged:
          type: integer
        archives:
          type: integer
        preview_rows:
          type: array
          items:
            type: object
            properties:
              row:
                type: integer
              action:
                type: string
              record_uid:
                type: string
              name:
                type: string
              entity_type:
                type: string
              aliases:
                type: array
                items:
                  type: string
              countries:
                type: array
                items:
                  type: string
              reason:
                type: string
              custom_fields:
                type: object
                additionalProperties:
                  type: string
              validation_errors:
                type: array
                items:
                  type: object
                  properties:
                    row:
                      type: integer
                    column:
                      type: string
                    code:
                      type: string
                    message:
                      type: string
                  required:
                    - code
                    - message
            required:
              - aliases
              - countries
              - custom_fields
              - validation_errors
        validation_errors:
          type: array
          items:
            type: object
            properties:
              row:
                type: integer
              column:
                type: string
              code:
                type: string
              message:
                type: string
            required:
              - code
              - message
        job_id:
          type: string
          description: Worker job id; poll `GET /jobs/{jobId}`.
        correlation_id:
          type: string
        failure_reason:
          type: string
        failure_stage:
          type: string
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - list_id
        - status
        - merge_mode
        - record_id_column
        - parsed_record_count
        - adds
        - updates
        - unchanged
        - archives
        - preview_rows
        - validation_errors
        - created_by
        - created_at
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Admin API key for authentication. Manage API keys in the Minerva
        dashboard under Administration > Developers.
    AdminApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        An admin application key: `Authorization: Api-Key <token>` (or legacy
        `x-api-key`). Only tenant owners and admins can create one. Standard
        keys are refused with 403 on workspace management and tenant
        configuration routes.
    UserTokenAuth:
      type: apiKey
      in: header
      name: x-user-token
      description: Firebase user token for authentication

````

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