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

# Documents & Search

> Upsert vectors, search with dense/sparse/BM25/hybrid, and manage documents

## Upsert Documents

Insert or update documents with your pre-computed vectors and JSON payload. Up to 1,000 documents per request.

<CodeGroup>
  ```python Python theme={null}
  from mixpeek import Mixpeek

  client = Mixpeek(api_key="mxp_sk_...")

  result = client.namespaces.documents.upsert(
      namespace_id="product-search",
      documents=[
          {
              "document_id": "prod-001",
              "vectors": {"text_embedding": [0.12, -0.34, 0.56]},  # 1536 floats
              "payload": {"title": "Noise-Canceling Headphones", "price": 149.99, "in_stock": True},
          },
          {
              "document_id": "prod-002",
              "vectors": {"text_embedding": [0.08, 0.22, -0.41]},  # 1536 floats
              "payload": {"title": "Bluetooth Speaker", "price": 59.99, "in_stock": True},
          },
      ],
  )
  # → {"inserted": 2, "document_ids": ["prod-001", "prod-002"]}
  ```

  ```bash cURL theme={null}
  curl -X POST "https://api.mixpeek.com/v1/namespaces/product-search/documents/upsert" \
    -H "Authorization: Bearer $MIXPEEK_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "documents": [{
        "document_id": "prod-001",
        "vectors": {"text_embedding": [0.12, -0.34, 0.56]},
        "payload": {"title": "Noise-Canceling Headphones", "price": 149.99}
      }]
    }'
  ```
</CodeGroup>

Vector dimensions are validated against namespace config. If a document with the same ID exists, it is overwritten.

### Bulk Import

For large datasets, stream NDJSON directly to shard WALs. Returns `202 Accepted` with a batch ID to poll.

```bash theme={null}
curl -X POST "https://api.mixpeek.com/v1/namespaces/product-search/bulk-import" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @products.ndjson
```

```json title="products.ndjson" theme={null}
{"document_id": "prod-001", "vectors": {"text_embedding": [0.12, ...]}, "payload": {"title": "..."}}
{"document_id": "prod-002", "vectors": {"text_embedding": [0.08, ...]}, "payload": {"title": "..."}}
```

## Search

<Note>
  **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.
</Note>

### 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.

```bash cURL theme={null}
# 1. Create a feature_search retriever over your BYO vector index ("my_vec").
#    Note: stage_type is "filter"; the operation is stage_id "feature_search".
curl -X POST "https://api.mixpeek.com/v1/retrievers" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" -H "X-Namespace: $NS" -H "Content-Type: application/json" \
  -d '{
    "retriever_name": "byo-knn",
    "input_schema": {"qv": {"type": "array", "required": true}},
    "stages": [{
      "stage_name": "knn", "stage_type": "filter",
      "config": {"stage_id": "feature_search", "parameters": {
        "searches": [{
          "feature_uri": "my_vec",
          "query": {"input_mode": "vector", "value": "{{INPUT.qv}}"}
        }],
        "final_top_k": 10
      }}
    }]
  }'
# → {"retriever_id": "ret_...", ...}

# 2. Execute it with your query vector. pagination.method is required.
curl -X POST "https://api.mixpeek.com/v1/retrievers/$RETRIEVER_ID/execute" \
  -H "Authorization: Bearer $MIXPEEK_API_KEY" -H "X-Namespace: $NS" -H "Content-Type: application/json" \
  -d '{"inputs": {"qv": [1,0,0,0,0,0,0,0]}, "pagination": {"method": "offset", "page_size": 10, "page_number": 1}}'
# → {"documents": [{"document_id": "d1", "score": 1.0, ...}, ...]}
```

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

```python theme={null}
results = client.search(
    namespace_id="product-search",
    queries=[{
        "vector_name": "text_embedding",
        "vector": query_embedding,
        "top_k": 10,
        "score_threshold": 0.7,
    }],
)
```

### BM25 (Keyword)

Requires a [text index](/docs/vector-store/namespaces#text-indexes-bm25) on the target field.

```python theme={null}
results = client.search(
    namespace_id="product-search",
    queries=[{"text": "wireless noise canceling", "top_k": 10}],
)
```

### Sparse

```python theme={null}
results = client.search(
    namespace_id="product-search",
    queries=[{"sparse_vector": {42: 0.8, 1337: 0.5, 9001: 0.3}, "top_k": 10}],
)
```

### Hybrid

Combine multiple query types with RRF or DBSF fusion.

```python theme={null}
results = client.search(
    namespace_id="product-search",
    queries=[
        {"vector_name": "text_embedding", "vector": query_embedding, "top_k": 20},
        {"text": "wireless headphones", "top_k": 20},
    ],
    fusion="rrf",
)
```

### Filtered

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

```python theme={null}
results = client.search(
    namespace_id="product-search",
    queries=[{
        "vector_name": "text_embedding",
        "vector": query_embedding,
        "top_k": 10,
        "filters": {
            "must": [
                {"key": "price", "range": {"lte": 100}},
                {"key": "in_stock", "match": {"value": True}}
            ]
        },
    }],
)
```

## Document Operations

| Operation         | Method   | Endpoint                                 |
| ----------------- | -------- | ---------------------------------------- |
| Get by ID         | `GET`    | `/v1/namespaces/{ns}/documents/{doc_id}` |
| Update payload    | `PATCH`  | `/v1/namespaces/{ns}/documents/{doc_id}` |
| Delete            | `DELETE` | `/v1/namespaces/{ns}/documents/{doc_id}` |
| Scroll (paginate) | `POST`   | `/v1/namespaces/{ns}/documents/scroll`   |

### Update Vectors

| Operation                    | Method  | Endpoint                                         |
| ---------------------------- | ------- | ------------------------------------------------ |
| Replace vectors (single doc) | `PATCH` | `/v1/namespaces/{ns}/documents/{doc_id}/vectors` |
| Batch replace vectors        | `POST`  | `/v1/namespaces/{ns}/documents/update-vectors`   |
| Add new vector index         | `POST`  | `/v1/namespaces/{ns}/documents/add-vectors`      |

Payload is untouched when updating vectors.

## Related

* [Namespace Configuration](/docs/vector-store/namespaces)
* [Promote to Managed](/docs/vector-store/promote)
