Skip to Content
v2Quick StartManaged Cloud

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

pip install endee

Requirements: 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.

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.

client.create_collection( name="my_collection", fields=[ { "name": "embedding", "type": "vector", "params": {"dimension": 384, "space_type": "cosine", "precision": "int8"}, }, ], )

Field types:

TypeRequired keysparams
vectorname, typedimension, space_type, precision (+ optional M, ef_con)
sparsename, type, sparse_model
multi_vectorname, typedimension, 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.

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:

FieldRequiredDescription
idYesUnique string identifier (insert-or-replace key)
fieldsYesMap of field name → value (dense array, sparse {indices, values}, or multi-vector array of arrays)
metaNoArbitrary metadata returned in search results
filterNoKey-value tags used for filtered 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.

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:

ParameterDescriptionDefaultMax
fieldsMap of field name → query config {query, limit?, ef_search?} (query required)Required-
limit(per field) Hits to return for that field104096
ef_search(per field) Search quality (higher explores more candidates)1281024
filterFilter conditionsNone-
res = collection.search( fields={"embedding": {"query": [...], "limit": 5}}, filter=[ {"category": {"$eq": "tech"}}, {"score": {"$range": [80, 100]}}, ], )

Filter operators:

OperatorDescriptionExample
$eqExact match{“status”: {“$eq”: “published”}}
$inMatch any value in list{“tags”: {“$in”: [“ai”, “ml”]}}
$rangeNumeric range{“score”: {“$range”: [70, 95]}}
$gt / $gteGreater than / or equal{“price”: {“$gt”: 50}}
$lt / $lteLess than / or equal{“price”: {“$lte”: 100}}

Next Steps