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

# Manage chunk metadata

> Edit user-defined metadata on chunks and list or filter chunks by metadata.

User-defined metadata lets you attach structured business fields (such as `year`, `doc_type`, `department`, or `is_confidential`) to the chunks in a vector database, then retrieve and update those fields after ingestion. You can attach metadata when you ingest files (see [Create and populate a vector database](/flow/sdk/data-engine/create-and-populate-a-vector-database)), then use the methods here to browse chunks, filter them by metadata, and edit metadata in place.

## Metadata rules

The same rules apply wherever metadata is accepted (ingestion request, manual chunking blocks, and the edit method below):

* Metadata is a flat JSON object. Nested objects and arrays are not allowed.
* A metadata object has 20 or fewer keys.
* Keys are strings of 255 characters or fewer and cannot start with `_` (reserved for system fields).
* Values are strings, numbers, booleans, or datetimes. Numbers must be finite, and datetimes are stored as ISO 8601 strings.
* Keys and string values cannot be empty or whitespace-only. String values are trimmed, and embedded newlines become spaces.
* `null` is not a valid value. To leave a field unset, omit the key.

A request that breaks these rules returns a `422` validation error naming the offending key.

<Note>
  Validation is strict on the ingestion request and on `update_metadata`, where one invalid field rejects the whole call. Inside manual chunking blocks it is lenient, where an invalid field is dropped with a warning and ingestion continues.
</Note>

## List and filter chunks

Use `list_chunks` to return a paginated list of chunks from a vector database. Filter by file, by specific chunk IDs, or by metadata fields. When you provide more than one filter, results must match all of them.

<CodeGroup>
  ```python Python theme={null}
  from seekrai import SeekrFlow

  client = SeekrFlow()

  result = client.vector_database.list_chunks(
      database_id="<database-id>",
      metadata={"year": {"$gte": 2023}, "doc_type": "meeting_notes"},
      limit=20,
      offset=0,
  )

  print(f"{result.total} matching chunks")
  for chunk in result.data:
      print(chunk.chunk_id, chunk.metadata)
  ```
</CodeGroup>

**Parameters:**

| Parameter | Description |
| - | - |
| `database_id` | ID of the vector database. |
| `file_id` | Optional. Return only chunks from this file. |
| `chunk_ids` | Optional. Return only these chunk IDs. |
| `metadata` | Optional. Filter by metadata key-value pairs. |
| `limit` | Maximum results to return. Default 20, maximum 100. |
| `offset` | Pagination offset. Default 0. |

**Metadata filter operators:**

Match a value exactly by giving it directly (`{"doc_type": "SOP"}`), or use an operator object for comparisons:

| Operator | Meaning |
| - | - |
| `$in` | Value is one of a list, for example `{"severity": {"$in": ["P0", "P1"]}}`. |
| `$gt` | Greater than. |
| `$gte` | Greater than or equal to. |
| `$lt` | Less than. |
| `$lte` | Less than or equal to. |

String filters are case-sensitive and match the whole value. `{"region": "EMEA"}` matches `EMEA` but not `emea`, and `{"doc_type": "Annual Report"}` matches only the full two-word value. To discover the exact values and casing in a vector database, use the [metadata snapshot](/flow/sdk/data-engine/generate-metadata-snapshot). Comparison operators apply to numbers.

An empty or whitespace-only `file_id`, `chunk_ids` entry, or metadata filter value returns a `422` error rather than matching everything.

Each chunk in the response includes its `chunk_id`, `file_id`, `text`, `metadata`, `hierarchy`, and `locations`.

## Edit chunk metadata

Use `update_metadata` to overwrite the metadata on chunks in a vector database. Target the chunks with either `chunk_ids` or `file_ids`, but not both. Editing is scoped to the vector database, so updating a file's chunks here does not affect chunks of the same file in another vector database.

<CodeGroup>
  ```python Python theme={null}
  # Update specific chunks
  client.vector_database.update_metadata(
      database_id="<database-id>",
      chunk_ids=["chunk-1", "chunk-2"],
      metadata={"source": "manual_review", "category": "support_doc"},
  )

  # Update every chunk belonging to one or more files
  client.vector_database.update_metadata(
      database_id="<database-id>",
      file_ids=["file-abc123"],
      metadata={"department": "finance", "year": 2024},
  )
  ```
</CodeGroup>

<Danger>
  This operation is destructive. The metadata object you provide replaces all existing metadata on each targeted chunk, so include any fields you want to keep. To find the chunks and current metadata to edit, list them first with `list_chunks`.
</Danger>

If the `file_ids` or `chunk_ids` you provide are well-formed but match no chunks in the vector database, the call returns a `404` error instead of reporting success on an update that changed nothing.

## Clear metadata

An empty `metadata` object clears all metadata from the targeted chunks:

<CodeGroup>
  ```python Python theme={null}
  client.vector_database.update_metadata(
      database_id="<database-id>",
      file_ids=["file-abc123"],
      metadata={},
  )
  ```
</CodeGroup>

<Danger>
  Clearing metadata is irreversible, and it uses the same method as a normal edit. A metadata object that is empty by accident, such as one built by a loop that added no fields, wipes the metadata on every targeted chunk. Send `{}` only when you intend to clear.
</Danger>

## Delete metadata

Metadata is removed automatically when its chunks are deleted. Deleting a file from a vector database removes that file's chunks and their metadata. See [Create and populate a vector database](/flow/sdk/data-engine/create-and-populate-a-vector-database) for file deletion.


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