Managed Cloud
Endee Serverless is the fully-managed version of Endee, a high-performance vector database for fast Approximate Nearest Neighbor (ANN) search with metadata, filtering, and hybrid search built in. There’s no Docker, no servers, and no infrastructure to maintain: you spin up a database from the dashboard, grab an auth token, and start upserting and searching from your application in minutes.
In Endee, a collection holds objects, and each object can carry values for several named, typed fields at once (dense vectors, sparse (keyword) vectors, and multi-vectors), so a single object can be searched many ways. This guide walks you from creating a database to your first search.
Create Your Database
Log in to the dashboard
Sign in at app.endee.io . Create an account first if you don’t have one.
Create a database
From the dashboard, create a new database. This is where your collections and objects will live.
Choose a plan
Select the plan that fits your workload: Starter, Pro, or Scale. See app.endee.io for current limits and pricing.
Get your auth token
Once payment is complete, the dashboard issues an auth token for your database. This token authenticates every request; keep it secret. You’ll use it to connect the SDK below, and you can manage collections and data either from the dashboard UI or programmatically with the SDK.
Prefer to run Endee yourself with Docker instead of the managed serverless platform? See v1 setup.
Install the SDK
Python
pip install endeeRequirements: Python 3.9+
Initialize the Client
Pass the auth token from your dashboard to connect the client to your serverless database. Serverless tokens encode the region (db_name:secret:region), so the client automatically targets the right endpoint. No base URL setup required.
Python
from endee import Endee
client = Endee("your-serverless-token")Keep your token out of source control. Load it from an environment variable or secrets manager. See Authentication for details.
Create a Collection
A collection is a set of named, typed fields. Here we create a collection with a single dense vector field, the most common starting point.
Python
client.create_collection(
name="my_collection",
fields=[
{
"name": "embedding",
"type": "vector",
"params": {"dimension": 384, "space_type": "cosine", "precision": "int8"},
},
],
)Field types:
| Type | Required keys | params |
|---|---|---|
vector | name, type | dimension, space_type, precision (+ optional M, ef_con) |
sparse | name, type, sparse_model | — |
multi_vector | name, type | dimension, space_type, precision, pooling (+ optional M, ef_con) |
space_type:cosine(default),l2,ip. Cosine vectors are L2-normalized client-side.precision:float32,float16,int16,int8,int8e,binary. See Precision.M/ef_con: optional HNSW build parameters (sensible defaults applied).
Other collection operations (list, get, describe, delete) are covered in Concepts → Collections.
Upsert Objects
Maximum 10,000 objects per upsert call. Dense vector dimensions must match the field’s configured dimension.
Each object has an id, optional meta and filter, and a fields map containing one entry per field you populate.
Python
collection = client.get_collection("my_collection")
collection.upsert([
{
"id": "doc1",
"meta": {"title": "First Document"},
"filter": {"category": "tech"},
"fields": {"embedding": [...]}, # 384-dim float list
},
{
"id": "doc2",
"meta": {"title": "Second Document"},
"filter": {"category": "science"},
"fields": {"embedding": [...]},
},
])Object fields:
| Field | Required | Description |
|---|---|---|
id | Yes | Unique string identifier (insert-or-replace key) |
fields | Yes | Map of field name → value (dense array, sparse {indices, values}, or multi-vector array of arrays) |
meta | No | Arbitrary metadata returned in search results |
filter | No | Key-value tags used for filtered search |
Search
search() queries one or more fields in a single request and returns ranked hits. Results are always keyed by field name. For a single field, read the list under that field’s name.
Python
res = collection.search(
fields={"embedding": {"query": [...], "limit": 5, "ef_search": 128}}, # query config
)
for item in res["results"]["embedding"]:
print(f"ID: {item['id']}, Similarity: {item['similarity']:.3f}")Both clients use the per-field config form { query, limit?, ef_search? } (query is required; there’s no bare-value shorthand) and always return results keyed by field name (res.results.embedding / res["results"]["embedding"]). See Search for the full shapes.
Search parameters:
| Parameter | Description | Default | Max |
|---|---|---|---|
fields | Map of field name → query config {query, limit?, ef_search?} (query required) | Required | - |
limit | (per field) Hits to return for that field | 10 | 4096 |
ef_search | (per field) Search quality (higher explores more candidates) | 128 | 1024 |
filter | Filter conditions | None | - |
Filtered Search
Python
res = collection.search(
fields={"embedding": {"query": [...], "limit": 5}},
filter=[
{"category": {"$eq": "tech"}},
{"score": {"$range": [80, 100]}},
],
)Filter operators:
| Operator | Description | Example |
|---|---|---|
$eq | Exact match | {“status”: {“$eq”: “published”}} |
$in | Match any value in list | {“tags”: {“$in”: [“ai”, “ml”]}} |
$range | Numeric range | {“score”: {“$range”: [70, 95]}} |
$gt / $gte | Greater than / or equal | {“price”: {“$gt”: 50}} |
$lt / $lte | Less than / or equal | {“price”: {“$lte”: 100}} |
Next Steps
- Concepts → Collections: field types, parameters, distance metrics
- Concepts → Objects: object fields, precision levels
- Concepts → Search: single/multi-field search, hybrid fusion (RRF), result fields
- Concepts → Filtering: filter operators and tuning
- Endee Tools → Sparse Vectors (BM25): hybrid search with keyword matching