---
title: "Upsert documents with BYO vectors"
method: POST
path: "/v1/namespaces/{namespace_id}/documents/upsert"
tags: ["BYO Documents"]
---

# Upsert documents with BYO vectors

`POST /v1/namespaces/{namespace_id}/documents/upsert`

Upsert documents with user-provided vectors directly into a namespace. This bypasses the collection/batch/extractor pipeline entirely. Documents go directly to the vector store. Maximum 1000 documents per call.

## Path parameters

- `namespace_id` string, required — The namespace to upsert documents into.

## Request body

- BYOUpsertRequest — Request body for BYO document upsert.
  - `collection_id` string, nullable — Target collection. Documents are tagged with this collection_id so they appear in collection-scoped queries, list, and clustering. When omitted a namespace-level default collection is used.
  - `documents` BYODocument[], required — Documents to upsert. Maximum 1000 per call.
    - `document_id` string, required — Unique document identifier. Upserting with an existing ID replaces the document.
    - `vectors` object, required — Named vectors as a map of vector_name -> embedding values. Example: {"text-embedding": [0.1, 0.2, ...], "image-embedding": [0.3, ...]}
    - `payload` object — Arbitrary JSON payload stored alongside the vectors.
    - `metadata` object, nullable — Document metadata stored in _internal.metadata. Filterable via attribute queries.
    - `source_type` 'bucket' | 'collection' | 'direct_upsert', nullable — Immediate-parent type. Defaults to 'direct_upsert' when omitted. Set 'bucket'/'collection' to import a document carrying real lineage.
    - `root_object_id` string, nullable — Root object id (decomposition-tree root). All documents derived from the same source object share it.
    - `root_bucket_id` string, nullable — Bucket id holding the root object.
    - `source_object_id` string, nullable — Immediate parent object id when source_type='bucket'.
    - `source_document_id` string, nullable — Immediate parent document id when source_type='collection'.
    - `source_collection_id` string, nullable — Immediate parent collection id when source_type='collection'.
    - `lineage_path` string, nullable — Materialized lineage path (e.g. 'bkt_123/col_456/col_789').
    - `lineage_chain` object[], nullable — Ordered processing steps from root object to this document; each step carries collection_id, feature_extractor_id, document_id, timestamp.
    - `content_hash` string, nullable — SHA256 content hash of the source object. Supplying it lets a later heal/reprocess recognise the cached derivation potency (LIN-02) and skip recompute. Stored at _internal.content_hash.
  - `options` UpsertOptions — Options controlling the upsert behavior.
    - `write_token` boolean — Return a WriteToken for read-your-writes consistency.
    - `idempotency_key` string, nullable — Deduplication key. A repeated call with the same key and an identical body returns the original cached response; the same key with a different body returns 409 Conflict.

## Response `200`

Successful Response

- BYOUpsertResponse — Response from a BYO document upsert.
  - `inserted` integer, required — Number of documents upserted.
  - `document_ids` string[], required — IDs of all upserted documents.
  - `write_token` string, nullable — Opaque token for read-your-writes consistency (only when requested).
  - `dropped_payload_fields` object — document_id -> payload field names that were REMOVED before storage because they collide with reserved internal field names. Their values are not stored anywhere and are not readable back. Rename the field (e.g. 'source_type' -> 'my_source_type') or nest it under 'metadata' to keep the value. Empty when nothing was dropped.
  - `consistency` WriteConsistency — How and when a write becomes visible to retriever reads.
    - `retriever_visible` string, required — Visibility model: 'eventual' (BYOV direct upsert — indexed within seconds) or 'after_processing' (managed ingestion — visible after a collection batch processes the object).
    - `recommended_header` string, nullable — Header to send on retriever execute for read-your-writes (BYOV). Set only when a write_token was actually issued; null when no token was minted (visibility is then automatic within expected_visible_within_ms).
    - `write_token_available` boolean — Whether a write_token was issued for read-your-writes.
    - `expected_visible_within_ms` integer, nullable — Typical upper bound for visibility (BYOV indexing). Null when visibility depends on asynchronous processing (managed ingestion).
    - `poll` object, nullable — How to poll for visibility when it depends on async processing: {endpoint, field, ready_when}.
    - `next_actions` object[] — Actionable next steps to reach retriever visibility.

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `422` — Validation Error
- `500` — Internal Server Error

---

[API](https://skmtc.net/mixpeek/apis/mixpeek-api.md) · [All operations](https://skmtc.net/mixpeek/apis/mixpeek-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mixpeek/mixpeek-api/revisions/c768d4d28e4c/schema)
