---
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).
  - `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/f507f74ec843/schema)
