---
title: "Batch Update Documents"
method: POST
path: "/v1/collections/{collection_identifier}/documents/batch"
tags: ["Collection Documents"]
---

# Batch Update Documents

`POST /v1/collections/{collection_identifier}/documents/batch`

## Request

- Base URL: `https://api.mixpeek.com`
- URL: `https://api.mixpeek.com/v1/collections/{collection_identifier}/documents/batch`
- Auth: HTTP bearer and API key in header `X-Namespace`

Batch update multiple documents by explicit IDs or filters.

Supports TWO modes:
1. Explicit IDs mode: Provide 'updates' array with document_id + update_data for each document
   - Each document can have DIFFERENT update_data
   - Returns detailed per-document results

2. Filter mode: Provide 'filters' + 'update_data' to update all matching documents
   - All documents receive the SAME update_data
   - Returns total count only

Key Features:
- Update any document field except vectors (metadata, internal_metadata, source_blobs, etc.)
- Maximum 1000 documents per batch in explicit mode
- Per-document success/failure reporting in explicit mode
- Validates documents exist in the specified collection

Examples:
    Explicit IDs mode:
    ```json
    {
        "updates": [
            {"document_id": "doc_123", "update_data": {"metadata": {"status": "processed"}}},
            {"document_id": "doc_456", "update_data": {"metadata": {"status": "archived"}}}
        ]
    }
    ```

    Filter mode (logical AND/OR/NOT shape — NOT MVS-native must/key):
    ```json
    {
        "filters": {"AND": [{"field": "metadata.status", "operator": "eq", "value": "pending"}]},
        "update_data": {"metadata": {"status": "processed"}}
    }
    ```

## Path parameters

- `collection_identifier` string, required: The ID of the collection to update documents in.

## Request body

- BatchUpdateDocumentsRequest: Request model for batch updating multiple documents by explicit IDs or filters. Supports TWO modes: 1. Explicit IDs mode: Provide 'updates' array with document_id + update_data for each 2. Filter mode: Provide 'filters' + 'update_data' to update all matching documents Key difference from BulkUpdateDocumentsRequest: - Batch (this): Can apply DIFFERENT updates to SPECIFIC documents by ID - Bulk: Applies SAME update to ALL documents matching filters Use Cases: - Update 5 specific documents with different metadata values - Update documents by IDs with per-document update control - Combine with filters for targeted batch updates Requirements: - EITHER 'updates' (explicit mode) OR 'filters' + 'update_data' (filter mode) - NOT BOTH modes simultaneously
  - `updates` BatchDocumentUpdate[], nullable: OPTIONAL. List of document updates with explicit document IDs. Each entry specifies document_id and update_data. Use this mode when you know exact document IDs and want per-document control. Mutually exclusive with filters + update_data mode. Maximum 1000 documents per batch request.
    - `document_id` string, required: REQUIRED. Document ID to update. Must exist in the collection. Format: 'doc_' prefix + alphanumeric characters.
    - `update_data` object, required: REQUIRED. Fields to update for this specific document. Can update any document field except vectors. Supported fields: metadata, source_blobs, document_blobs, lineage fields (root_object_id, source_type, etc.), and any custom fields. Each document in the batch can have different update_data. A dotted key sets one nested field and keeps its siblings: {'metadata.status': 'processed'} changes only metadata.status. A key without a dot replaces that whole top-level field, so {'metadata': {'status': 'processed'}} replaces the entire metadata object and drops its other keys.
  - `filters` LogicalOperatorInput: Represents a logical operation (AND, OR, NOT) on filter conditions. Allows nesting with a defined depth limit. Also supports shorthand syntax where field names can be passed directly as key-value pairs for equality filtering (e.g., {"metadata.title": "value"}).
    - `AND` union[], nullable: Logical AND operation - all conditions must be true
      - union
        - LogicalOperatorInput (recursive)
        - FilterCondition: Represents a single filter condition. Attributes: field: The field to filter on operator: The comparison operator value: The value to compare against
          - `field` string, required: Field name to filter on
          - `operator` 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'contains' | 'starts_with' | 'ends_with' | 'regex' | 'exists' | 'is_null' | 'text' | 'phrase' | 'words' | 'geo_radius' | 'geo_bounding_box' | 'geo_polygon': Supported filter operators across database implementations. `text` is a case-insensitive substring match on the MVS vector store, in the in-memory evaluator and in the collections list filter; it does not tokenize or rank. On the Mongo query translator it becomes a Mongo `$text` search, which needs a collection text index and searches every indexed field. For whole-word matching on one field use `words`: every word of the value must appear as a whole word, compared on its English stem.
          - `value` union, required: Value to compare against
            - DynamicValue: A value that should be dynamically resolved from the query request.
              - …
            - unknown
    - `OR` union[], nullable: Logical OR operation - at least one condition must be true
      - union
        - LogicalOperatorInput (recursive)
        - FilterCondition: Represents a single filter condition. Attributes: field: The field to filter on operator: The comparison operator value: The value to compare against
          - `field` string, required: Field name to filter on
          - `operator` 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'contains' | 'starts_with' | 'ends_with' | 'regex' | 'exists' | 'is_null' | 'text' | 'phrase' | 'words' | 'geo_radius' | 'geo_bounding_box' | 'geo_polygon': Supported filter operators across database implementations. `text` is a case-insensitive substring match on the MVS vector store, in the in-memory evaluator and in the collections list filter; it does not tokenize or rank. On the Mongo query translator it becomes a Mongo `$text` search, which needs a collection text index and searches every indexed field. For whole-word matching on one field use `words`: every word of the value must appear as a whole word, compared on its English stem.
          - `value` union, required: Value to compare against
            - DynamicValue: A value that should be dynamically resolved from the query request.
              - …
            - unknown
    - `NOT` union[], nullable: Logical NOT operation - all conditions must be false
      - union
        - LogicalOperatorInput (recursive)
        - FilterCondition: Represents a single filter condition. Attributes: field: The field to filter on operator: The comparison operator value: The value to compare against
          - `field` string, required: Field name to filter on
          - `operator` 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'contains' | 'starts_with' | 'ends_with' | 'regex' | 'exists' | 'is_null' | 'text' | 'phrase' | 'words' | 'geo_radius' | 'geo_bounding_box' | 'geo_polygon': Supported filter operators across database implementations. `text` is a case-insensitive substring match on the MVS vector store, in the in-memory evaluator and in the collections list filter; it does not tokenize or rank. On the Mongo query translator it becomes a Mongo `$text` search, which needs a collection text index and searches every indexed field. For whole-word matching on one field use `words`: every word of the value must appear as a whole word, compared on its English stem.
          - `value` union, required: Value to compare against
            - DynamicValue: A value that should be dynamically resolved from the query request.
              - …
            - unknown
    - `case_sensitive` boolean, nullable: Whether to perform case-sensitive matching
  - `update_data` object, nullable: OPTIONAL. Update data to apply when using filters mode. Must be used with 'filters' field. All matched documents receive the same updates. Can update any document field except vectors. A dotted key sets one nested field and keeps its siblings: {'metadata.status': 'processed'} changes only metadata.status. A key without a dot replaces that whole top-level field, so {'metadata': {'status': 'processed'}} replaces the entire metadata object and drops its other keys.

## Response `200`

Successful Response

- BatchUpdateDocumentsResponse: Response model for batch document update operation. Provides detailed per-document results showing success/failure for each update.
  - `updated_count` integer, required: Total number of documents successfully updated
  - `failed_count` integer: Total number of documents that failed to update
  - `results` BatchDocumentUpdateResult[]: Detailed per-document results. Each entry shows document_id, success status, and error message (if failed). Empty list when using filter mode (only counts returned).
    - `document_id` string, required: Document ID that was updated
    - `success` boolean, required: Whether the update succeeded
    - `error` string, nullable: Error message if update failed
  - `message` string: Summary message of the operation

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found
- `422`: Unprocessable Entity
- `429`: Too Many Requests
- `500`: Internal Server Error
- `503`: Service Unavailable

## Changes

- **2026-10-09** `61a175e8eb9a`: 1 warning, 5 info
  - removed the optional property `detail` from the response with the `422` status
  - added the non-success response with the status `429`
  - added the non-success response with the status `503`
  - added the optional property `success` to the response with the `422` status
  - …2 more
- **2026-09-26** `5231c1d891e8`: 3 info
  - added the new `words` enum value to the request property `filters/anyOf[subschema #1: LogicalOperator]/AND/anyOf[subschema #1]/items/anyOf[subschema #2: FilterCondition]/operator`
  - added the new `words` enum value to the request property `filters/anyOf[subschema #1: LogicalOperator]/NOT/anyOf[subschema #1]/items/anyOf[subschema #2: FilterCondition]/operator`
  - added the new `words` enum value to the request property `filters/anyOf[subschema #1: LogicalOperator]/OR/anyOf[subschema #1]/items/anyOf[subschema #2: FilterCondition]/operator`
- **2026-08-09** `5d4c905106b4`: 1 info
  - the endpoint scheme security `BearerAuth AND NamespaceHeader` was added to the API
- …earlier changes not shown

[Operation history](https://skmtc.dev/mixpeek/apis/mixpeek-api/changes/v1/collections/:collection_identifier/documents/batch/post.md)

---

[API](https://skmtc.dev/mixpeek/apis/mixpeek-api.md) - [All operations](https://skmtc.dev/mixpeek/apis/mixpeek-api/llms.txt) - [OpenAPI document](https://skmtc.dev/mixpeek/apis/mixpeek-api/revisions/790bc16455f6?raw)
