Aetherfy vector database
What the Aetherfy vector database is
The Aetherfy vector database stores vectors with attached JSON payloads and answers nearest-neighbour queries over them. It is a managed service: you create collections, upsert points, and search. There are no nodes, shards, or index build settings to operate — collection creation configuration is fixed server-side, and Aetherfy owns it.
The unit of storage is a collection: a named set of points that all share one vector size and one distance metric. A point is an id, a vector, and an optional payload dictionary. Search returns points ordered by similarity score, optionally narrowed by a payload filter.
Every collection lives in one of your workspaces, and a
request names the workspace first:
/api/v1/workspaces/{workspace}/collections/{name}. Collection names are unique
per workspace, so two workspaces, or two accounts, can each have a collection
called articles without collision. You always use your own bare collection
name, and never prefix or namespace it yourself.
Qdrant compatibility in the Aetherfy vector database
The Aetherfy vector database exposes a Qdrant-compatible API. Everything under
/api/v1/workspaces/{workspace}/collections/{name}/points/** is forwarded to Qdrant verbatim, so
Qdrant’s filter DSL, point shapes, and query bodies work unchanged. If you have
written a Qdrant filter before, it is the same filter here.
Compatibility is not total, and Aetherfy is explicit about the edges:
| Qdrant behaviour | Status on Aetherfy |
|---|---|
PUT /collections/{name} (native create) | Not supported — 405 METHOD_NOT_ALLOWED; use POST /api/v1/workspaces/{workspace}/collections |
PATCH with optimizers_config / hnsw_config | Not supported — 400; only the name and description change |
POST /collections/{name}/points as upsert | Not upsert on Aetherfy — upsert is PUT; POST falls through to Qdrant’s batch retrieve, which expects body.ids |
Snapshots, /telemetry, /metrics, /cluster, /locks, shard endpoints | Not supported — 404 “Unsupported endpoint” |
Payload keys beginning __aetherfy_ | Reserved by Aetherfy and stripped from reads, except __aetherfy_agent_id and __aetherfy_deployment_id — the attested author and deployment, which are returned and which you may send back unchanged (Aetherfy ignores the values and sets them from your credential). The rest are rejected on write with 400 RESERVED_FIELD |
The full route list is on the REST API reference.
Authenticating against the Aetherfy vector database
Every request to the Aetherfy vector database carries an API key in an
Authorization: Bearer header. Keys look like afy_live_... or afy_test_...
and match the regex ^afy_(live|test)_[a-zA-Z0-9]{16,}$ — a permissive
client-side check, not the issued format, which is the prefix plus exactly 32
hexadecimal characters (see API keys). Create and revoke
keys at https://app.aetherfy.com/dashboard/settings/api-keys .
Both SDKs read the key from the environment when you do not pass one, checking
AETHERFY_API_KEY first and AETHERFY_VECTORS_API_KEY second.
A raw request against Aetherfy looks like this:
curl -X POST https://vectors.aetherfy.com/api/v1/workspaces/default/collections \
-H "Authorization: Bearer $AETHERFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"articles","vectors":{"size":4,"distance":"Cosine"}}'A missing or malformed header returns 401 MISSING_API_KEY; a key that does not
resolve returns 401 INVALID_API_KEY. See errors.
The Aetherfy client SDKs
Aetherfy ships two first-party clients over the same REST surface. They are distributed under the same name in each ecosystem and are both at version 1.2.2.
| Python | JavaScript / TypeScript | |
|---|---|---|
| Install | pip install aetherfy-vectors | npm install aetherfy-vectors |
| Runtime | Python >= 3.9 | Node >= 20 |
| Import packages | aetherfy_vectors, aetherfy_memory | package root only |
| Call style | Synchronous | async / await |
Python
import os
from aetherfy_vectors import AetherfyVectorsClient, Point
from aetherfy_vectors.models import VectorConfig, DistanceMetric
client = AetherfyVectorsClient(api_key=os.environ["AETHERFY_API_KEY"])
client.create_collection(
collection_name="articles",
vectors_config=VectorConfig(size=4, distance=DistanceMetric.COSINE),
)
client.upsert(
collection_name="articles",
points=[
Point(id=1, vector=[0.1, 0.2, 0.3, 0.4], payload={"title": "First"}),
Point(id=2, vector=[0.2, 0.1, 0.4, 0.3], payload={"title": "Second"}),
],
)
results = client.search("articles", query_vector=[0.1, 0.2, 0.3, 0.4], limit=2)
for hit in results:
print(hit.id, hit.score, hit.payload)
client.close()JavaScript / TypeScript
import { AetherfyVectorsClient, DistanceMetric } from 'aetherfy-vectors';
const client = new AetherfyVectorsClient({
apiKey: process.env.AETHERFY_API_KEY,
});
await client.createCollection('articles', {
size: 4,
distance: DistanceMetric.COSINE,
});
await client.upsert('articles', [
{ id: 1, vector: [0.1, 0.2, 0.3, 0.4], payload: { title: 'First' } },
{ id: 2, vector: [0.2, 0.1, 0.4, 0.3], payload: { title: 'Second' } },
]);
const results = await client.search('articles', [0.1, 0.2, 0.3, 0.4], {
limit: 2,
});
for (const hit of results) {
console.log(hit.id, hit.score, hit.payload);
}
client.dispose();The two SDKs are not mirror images of each other — defaults, units, and field names diverge in ways that change results. Those divergences are tabulated on the SDK reference.
From a shell, the Aetherfy CLI covers the same collection, payload-index and
read operations without writing SDK code — afy collections, afy index and
afy points, each with --json output — using the same API key. Loading
points stays the SDKs’ job. See /cli/vectors.
Regions and replication in the Aetherfy vector database
Where your data lives depends on your plan, and Aetherfy does not replicate every account’s collections.
| Plan | Regional behaviour |
|---|---|
| Free | One region per workspace, chosen when the workspace is created |
| Starter | One region per workspace, chosen when the workspace is created |
| Performance | Multi-region replication |
| Enterprise | Multi-region replication |
Multi-region replication begins at the plan named Performance. A collection is
created in its workspace’s regions: leave regions out to use all of them, or name
a subset. A region outside the workspace’s is refused with 422
COLLECTION_REGIONS_NOT_IN_SCOPE, which names missing_regions and
scope_regions; the workspace’s regions are set on the workspace. A collection that
already exists elsewhere returns 409 COLLECTION_EXISTS_IN_OTHER_REGION.
The regions the Aetherfy SDKs accept for an explicit regional client are
us-east-1, eu-central-1, and ap-southeast-1. The live region-to-URL map is
served by GET /api/v1/regions. Plan details are at
https://aetherfy.com/pricing .
Note that on a replicated plan, stored bytes are counted per replica — see limits.
Where to go next in the Aetherfy documentation
| Page | What it covers |
|---|---|
| /vectors/sdk | Full Python and JavaScript method surface, model shapes, point ID rules, and the per-language divergences |
| /cli/vectors | The same collection, index and read operations from the afy CLI, with --json output |
| /vectors/api | Every REST route, every one under a workspace (by name or by id), and the endpoints Aetherfy deliberately does not support |
| /vectors/filtering | Payload filter syntax — must, should, must_not, match and range conditions |
| /vectors/search-tuning | search_params / searchParams, including hnsw_ef, and how unknown options fail |
| /vectors/usage-and-metrics | The two analytics reads — plan usage and measured request telemetry, with the coverage rule that separates a real zero from an unobserved one |
| /vectors/limits | Per-request caps, per-plan caps, rate limiting, and storage accounting |
| /vectors/errors | The error envelope, every stable error code, and the SDK exception classes |
| /examples | Worked end-to-end examples |