Skip to main content

Upsert Documents

Insert or update documents with your pre-computed vectors and JSON payload. Up to 1,000 documents per request.
Vector dimensions are validated against namespace config. If a document with the same ID exists, it is overwritten.

Large Imports

Repeat the upsert call in batches of up to 1,000 documents. There is no separate bulk-import endpoint.
Querying is unified through retrievers — Mixpeek has one query path, so there is no direct POST /v1/namespaces/{ns}/documents/search REST endpoint. The client.search(...) helper below is SDK sugar that authors and runs a retriever for you. From raw HTTP/curl, create a one-stage feature_search retriever and execute it — the verified BYO example immediately below does exactly that in three calls.

Query BYO vectors from raw HTTP (verified)

Bring your own vectors and query them with a raw query vector — no extractor, no re-processing. The query is an object ({"input_mode": "vector", "value": "{{INPUT.qv}}"}), and the retriever’s input_schema declares the input variable your execute call fills in.
cURL
The execute cache is invalidated by upserts — a query re-run after an upsert returns fresh results (cache_hit: false), so the write-then-verify loop is safe.

Dense (Vector) — SDK

BM25 (Keyword)

Requires a text index on the target field.

Sparse

Hybrid

Combine multiple query types with RRF or DBSF fusion.

Filtered

Add payload filters to any query type. Filters narrow results before scoring.

Document Operations

Only upsert and get-by-ID carry the namespace in the path. The rest read it from the X-Namespace header. Delete is collection-scoped, so a document you reach by namespace is deleted through its collection.

Read Many by ID

Resolve up to 1,000 documents in one call. The namespace comes from the X-Namespace header here, not from the path.
Match returned documents by document_id rather than by position. The response order does not track the order you sent.An id that does not resolve does not fail the call. It lands in not_found and every other id still returns, so read not_found rather than comparing lengths.

Media URLs

Stored media fields hold a raw storage URI: gs:// on Mixpeek Cloud, s3:// on S3-backed deployments. Whether you get a fetchable https:// URL back depends on the endpoint you called, not on the field name.
POST /v1/documents/list reads that flag from the request body only. A ?return_presigned_urls=true query string is ignored, and you get raw gs:// values back, which most HTTP clients reject with unknown url type: gs.
Selection works on the value, not the name. Any field whose value starts with gs:// or s3:// gets signed, whatever the field is called. These stay raw:
  • anything under metadata
  • values nested inside dicts or lists, on documents carrying a collection_id
  • original_url, source_blobs, and presigned_urls
  • any URI whose signing call fails
Signed URLs last 24 hours everywhere except the single-document GET above.

Update Vectors

Re-upsert the document through POST /v1/namespaces/{ns}/documents/upsert. Sending an existing document_id overwrites that document, vectors and payload together, so send the payload you want to keep alongside the new vectors. No endpoint replaces vectors while leaving the payload untouched.