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

# Types

## Index configuration

These keyword arguments to [`client.create_index()`](./client/create-index) configure the index. There is no `index_config` argument and no `IndexIVFFlat` / `IndexIVFPQ` / `IndexIVFSQ` types.

| Parameter | Type | Default | Description |
| - | - | - | - |
| `dimension` | `int` | `None` (auto-detect) | Vector dimensionality. Taken from the first upsert, or from `embedding_model`, when omitted. |
| `metric` | `str` | `"euclidean"` | `"euclidean"`, `"squared_euclidean"`, or `"cosine"`. |
| `embedding_model` | `str` | `None` | Name of one of the service's built-in embedding models (listed by `GET /v1/embedding-models`), used for automatic embedding generation. |
| `storage_precision` | `str` | `"float32"` | `"float32"`, `"float16"`, or TurboQuant `"tq12"`, `"tq8"`, `"tq6"`, `"tq4"`. See [Storage precision](./client/create-index#storage-precision). |
| `metadata_schema` | `Dict[str, Dict[str, bool]]` | `None` | Per-field indexing policy. See [Metadata schema](./client/create-index#metadata-schema). |
| `text_fields` | `List[str]` | `None` | Fields to index for BM25 full-text search. |
| `bm25_k1` | `float` | `1.2` | BM25 term-frequency saturation. |
| `bm25_b` | `float` | `0.75` | BM25 length normalization. |

## Key management

| Parameter | Type | Notes |
| - | - | - |
| `index_key` | `bytes` | 32-byte key for the SDK-supplied-key path. Pass it again on every `load_index()`. |
| `kms_name` | `str` | Name of a `kms.registry` entry in the service YAML. The service generates and wraps the key; later calls omit `index_key`. |

Pass exactly one of the two to `create_index()`; passing both returns `ValidationError`.

## Vector item

The dict shape [`upsert()`](./encrypted-index/upsert) accepts:

```python theme={null}
vector_item = {
    "id": "unique_identifier",        # Required: str
    "vector": [0.1, 0.2, 0.3, 0.4],   # Optional: List[float]
    "contents": "text content",       # Optional: str or bytes
    "metadata": {                     # Optional: Dict[str, Any]
        "category": "research",
        "author": "Dr. Smith",
        "tags": ["ai", "ml"],
        "published_ms": 1767225600000,  # a date, as epoch milliseconds
    },
}
```

## Query result

[`query()`](./encrypted-index/query) returns a flat list for one query vector, and a list of lists for a batch:

```python theme={null}
# One query vector
[
    {"id": "doc1", "distance": 0.125, "metadata": {"category": "research"}},
    {"id": "doc2", "distance": 0.234, "metadata": {"category": "news"}},
]

# Batch: one inner list per query vector
[
    [{"id": "doc1", "distance": 0.125}, {"id": "doc2", "distance": 0.234}],
    [{"id": "doc3", "distance": 0.156}, {"id": "doc4", "distance": 0.278}],
]
```

Vector queries return `distance` (lower is closer). Hybrid queries (`text=`) return `score` instead (higher is more relevant).

## MetadataResult

The item type [`query_metadata()`](./encrypted-index/query-metadata) returns, importable as `cyborgdb.MetadataResult`:

```python theme={null}
{
    "id": str,      # Always present
    "score": float, # Only when text is set
}
```

## Field selection

`include` picks the fields returned besides `id`:

| Field | `get()` | `query()` / `query_binary()` |
| - | - | - |
| `vector` | Yes (default) | Not returned |
| `contents` | Yes (default) | Not returned |
| `metadata` | Yes (default) | Yes |
| `distance` | - | Yes |

`get()` defaults to `["vector", "contents", "metadata"]`; `query()` defaults to `[]`, which returns only `id`.

## Metadata filtering

`filters` on [`query()`](./encrypted-index/query), [`query_binary()`](./encrypted-index/query-binary), and [`query_metadata()`](./encrypted-index/query-metadata) uses MongoDB-style operators. Nested fields use dot-paths such as `"loc.city"`.

### Operators

| Operator | Meaning | Example |
| - | - | - |
| `$eq` | Equal (also the meaning of a bare value) | `{"category": "research"}` |
| `$ne` | Not equal | `{"status": {"$ne": "draft"}}` |
| `$gt`, `$gte` | Greater than, or equal | `{"year": {"$gte": 2020}}` |
| `$lt`, `$lte` | Less than, or equal | `{"price": {"$lt": 100}}` |
| `$in` | Value is in the list | `{"tag": {"$in": ["ai", "ml"]}}` |
| `$nin` | Value is not in the list | `{"category": {"$nin": ["spam", "deleted"]}}` |
| `$exists` | Field is present (`true`) or absent (`false`) | `{"reviewer": {"$exists": True}}` |
| `$regex` | String matches a regular expression | `{"title": {"$regex": "^intro"}}` |
| `$contains` | String contains a substring | `{"title": {"$contains": "guide"}}` |
| `$and` | All sub-filters match | `{"$and": [{"a": 1}, {"b": 2}]}` |
| `$or` | Any sub-filter matches | `{"$or": [{"x": 1}, {"y": 2}]}` |
| `$nor` | No sub-filter matches | `{"$nor": [{"status": "draft"}, {"status": "deleted"}]}` |
| `$not` | The sub-filter doesn't match. Takes one filter object, at the top level. | `{"$not": {"price": {"$gt": 100}}}` |

`$gt`, `$gte`, `$lt`, and `$lte` require a number; any other value returns `ValidationError`. `$not` can't be nested inside a field (`{"price": {"$not": ...}}` returns `ValidationError`); wrap the whole condition instead. `$regex` and `$contains` resolve from the index only on fields created with `pattern: True`: `query()` falls back to a slower post-filter otherwise, and `query_metadata()` rejects the filter.

### Examples

```python theme={null}
# Equality
simple_filter = {"category": "research"}

# Range
range_filter = {"published_year": {"$gte": 2020, "$lte": 2024}}

# Compound
complex_filter = {
    "$and": [
        {"category": "research"},
        {"confidence": {"$gte": 0.9}},
        {"$or": [{"language": "en"}, {"translated": True}]},
    ]
}
```

### Dates

CyborgDB has no date type. Store dates in metadata as integer milliseconds since the Unix epoch (UTC), so range operators work on them:

```python theme={null}
from datetime import datetime, timezone

published = datetime(2026, 1, 15, tzinfo=timezone.utc)
published_ms = int(published.timestamp() * 1000)

index.upsert([
    {"id": "doc1", "vector": [0.1, 0.2, 0.3, 0.4], "metadata": {"published_ms": published_ms}},
])

# Everything published on or after 2026-01-01
start_ms = int(datetime(2026, 1, 1, tzinfo=timezone.utc).timestamp() * 1000)
results = index.query_metadata(filters={"published_ms": {"$gte": start_ms}})
print(results)
# Output: [{'id': 'doc1'}]
```

Values come back as integers. Convert one back to a `datetime` with:

```python theme={null}
item = index.get(["doc1"], include=["metadata"])[0]
published = datetime.fromtimestamp(item["metadata"]["published_ms"] / 1000, tz=timezone.utc)
print(published)
# Output: 2026-01-15 00:00:00+00:00
```

A date stored as a string, such as `"2026-01-15"`, only works with equality filters. Range operators need a number, so `{"$gte": "2026-01-01"}` returns `ValidationError`.

## Distance metrics

| Metric | Description |
| - | - |
| `cosine` | Cosine distance. Suited to normalized embeddings. |
| `euclidean` | Euclidean (L2) distance. |
| `squared_euclidean` | Squared Euclidean distance. Same ranking as `euclidean`, without the square root. |


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