Skip to Content
ExamplesCollection lifecycle & schema
Raw

Collection lifecycle and payload schema

Everything that operates on a collection as a whole: listing what exists, checking for one, reading its configuration, deleting it — plus the payload mutation calls and the optional payload schema.

export AETHERFY_API_KEY="afy_live_your_key_here"

The Aetherfy collection lifecycle methods

OperationPythonJavaScriptReturns
Createcreate_collection(collection_name, vectors_config, distance=None, description=None, regions=None)createCollection(collectionName, vectorsConfig, description?, regions?)Collection
List allget_collections()getCollections()List[Collection] / Promise<Collection[]>
Existscollection_exists(name)collectionExists(name)bool / Promise<boolean>
Read oneget_collection(name)getCollection(name)Collection
Deletedelete_collection(name)deleteCollection(name)bool / Promise<boolean>

Note the signature difference: the Aetherfy Python create_collection accepts a standalone distance argument in third position, while the JavaScript createCollection takes the description third and expects the distance inside the vectors config.

Managing Aetherfy collections in Python

Install with pip install aetherfy-vectors (Python >= 3.9). VectorConfig and DistanceMetric live in aetherfy_vectors.models and are not re-exported from the package root; Schema, FieldDefinition and AnalysisResult are.

from aetherfy_vectors import AetherfyVectorsClient from aetherfy_vectors.models import VectorConfig, DistanceMetric, Point client = AetherfyVectorsClient() # Create. created = client.create_collection( "articles", VectorConfig(size=4, distance=DistanceMetric.COSINE), description="Published articles", ) print(created.name, created.config.size, created.config.distance) # articles 4 DistanceMetric.COSINE # Exists. print(client.collection_exists("articles")) # True print(client.collection_exists("nope")) # False # Read one. info = client.get_collection("articles") print(info.name) # articles print(info.config.size) # 4 print(info.description) # Published articles # List all. for c in client.get_collections(): print(c.name, c.config.size, c.points_count) # articles 4 0 # Delete. print(client.delete_collection("articles")) # True print(client.collection_exists("articles")) # False client.close()

Creating a collection whose name is already taken, or reading one that does not exist, raises an AetherfyVectorsException subclass rather than returning None. Guard with collection_exists when the collection may or may not be there:

if not client.collection_exists("articles"): client.create_collection("articles", VectorConfig(size=4, distance=DistanceMetric.COSINE))

Managing Aetherfy collections in JavaScript

Install with npm install aetherfy-vectors (Node >= 20). Import everything from the package root.

import { AetherfyVectorsClient, DistanceMetric } from 'aetherfy-vectors'; const client = new AetherfyVectorsClient(); async function main() { // Create. const created = await client.createCollection( 'articles', { size: 4, distance: DistanceMetric.COSINE }, 'Published articles', ); console.log(created.name, created.config.size, created.config.distance); // articles 4 Cosine // Exists. console.log(await client.collectionExists('articles')); // true console.log(await client.collectionExists('nope')); // false // Read one. const info = await client.getCollection('articles'); console.log(info.name, info.config.size, info.description); // articles 4 Published articles // List all. Note pointsCount, not points_count. for (const c of await client.getCollections()) { console.log(c.name, c.config.size, c.pointsCount); } // articles 4 0 // Delete. console.log(await client.deleteCollection('articles')); // true console.log(await client.collectionExists('articles')); // false client.dispose(); } main();

The Aetherfy Collection shape

Python fieldJavaScript fieldTypeNotes
namenamestring
configconfigVectorConfigsize (int) and distance
descriptiondescriptionstring, optional
points_countpointsCountnumber, optionalSnake case in Python, camel case in JavaScript
statusstatusoptionalReported by the server
regionsregionsoptionalPopulated only on a plan with more than one region

Region placement is plan-scoped in Aetherfy: Free and Starter collections live in a single region, and replication across more than one region begins at the plan named Performance. The regions argument on create and the regions field here are only meaningful above that line. See Regions & replication.

Mutating Aetherfy payloads without rewriting vectors

Three calls change a point’s payload while leaving its vector alone. They differ in whether they merge, replace, or remove.

CallPythonJavaScriptSemantics
Mergeset_payload(collection_name, payload, points, key=None)setPayload(collectionName, payload, points, { key? })Additive — existing keys not mentioned are kept
Replaceoverwrite_payload(collection_name, payload, points)overwritePayload(collectionName, payload, points)Full replace — keys not mentioned are dropped
Remove keysdelete_payload(collection_name, keys, points)deletePayload(collectionName, keys, points)Deletes the named keys only

Every payload mutation call is capped at 512 points per call in both SDKs. Chunk a larger update.

Payload mutation in Aetherfy with Python

from aetherfy_vectors import AetherfyVectorsClient from aetherfy_vectors.models import VectorConfig, DistanceMetric, Point client = AetherfyVectorsClient() client.create_collection("articles", VectorConfig(size=4, distance=DistanceMetric.COSINE)) client.upsert("articles", [ Point(id=1, vector=[0.1, 0.2, 0.3, 0.4], payload={"title": "Hello", "status": "draft", "author": "ada"}), ]) # Merge: adds published_at, keeps title/status/author, updates status. client.set_payload("articles", {"status": "published", "published_at": "2026-01-01"}, [1]) print(client.retrieve("articles", [1])[0]["payload"]) # {'title': 'Hello', 'status': 'published', 'author': 'ada', 'published_at': '2026-01-01'} # Remove specific keys. client.delete_payload("articles", ["published_at"], [1]) print(client.retrieve("articles", [1])[0]["payload"]) # {'title': 'Hello', 'status': 'published', 'author': 'ada'} # Replace: everything not listed is gone. client.overwrite_payload("articles", {"title": "Hello"}, [1]) print(client.retrieve("articles", [1])[0]["payload"]) # {'title': 'Hello'} # Chunk anything larger than 512 points. ids = list(range(2000)) for start in range(0, len(ids), 512): client.set_payload("articles", {"batch": "import-7"}, ids[start:start + 512]) client.close()

Payload mutation in Aetherfy with JavaScript

import { AetherfyVectorsClient, DistanceMetric } from 'aetherfy-vectors'; const client = new AetherfyVectorsClient(); async function main() { 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: 'Hello', status: 'draft', author: 'ada' } }, ]); // Merge. await client.setPayload('articles', { status: 'published', published_at: '2026-01-01' }, [1]); console.log((await client.retrieve('articles', [1]))[0].payload); // { title: 'Hello', status: 'published', author: 'ada', published_at: '2026-01-01' } // Remove keys. await client.deletePayload('articles', ['published_at'], [1]); console.log((await client.retrieve('articles', [1]))[0].payload); // { title: 'Hello', status: 'published', author: 'ada' } // Replace. await client.overwritePayload('articles', { title: 'Hello' }, [1]); console.log((await client.retrieve('articles', [1]))[0].payload); // { title: 'Hello' } // Chunk anything larger than 512 points. const ids = Array.from({ length: 2000 }, (_, i) => i); for (let start = 0; start < ids.length; start += 512) { await client.setPayload('articles', { batch: 'import-7' }, ids.slice(start, start + 512)); } client.dispose(); } main();

The Aetherfy payload schema

A collection can carry an optional schema describing the shape of its payloads. The schema is a set of named field definitions, and an enforcement mode decides what happens when a write does not match.

Enforcement modeBehaviour
offThe schema is stored but not applied. This is the default.
warnMismatches are surfaced but the write proceeds.
strictMismatches reject the write.

Field definition fields:

Python (FieldDefinition)JavaScript (FieldDefinition)Meaning
typetypeOne of null, boolean, string, integer, float, array, object
requiredrequiredWhether the key must be present
element_typeelementTypeElement type, for array fields
fieldsfieldsNested field definitions, for object fields

Note the casing split again: Python uses element_type, JavaScript uses elementType.

Setting and reading an Aetherfy schema in Python

Schema, FieldDefinition and AnalysisResult are exported from the aetherfy_vectors package root.

from aetherfy_vectors import AetherfyVectorsClient, Schema, FieldDefinition from aetherfy_vectors.models import VectorConfig, DistanceMetric, Point client = AetherfyVectorsClient() client.create_collection("articles", VectorConfig(size=4, distance=DistanceMetric.COSINE)) schema = Schema( fields={ "title": FieldDefinition(type="string", required=True), "status": FieldDefinition(type="string", required=True), "views": FieldDefinition(type="integer", required=False), "tags": FieldDefinition(type="array", required=False, element_type="string"), }, description="Article payload contract", ) etag = client.set_schema("articles", schema, enforcement="strict", description="v1") print(etag) # the ETag string of the new schema version # Read it back. Returns None when no schema is set. loaded = client.get_schema("articles") print(sorted(loaded.fields)) # ['status', 'tags', 'title', 'views'] print(loaded.fields["title"].type) # string print(loaded.fields["title"].required) # True print(loaded.fields["tags"].element_type) # string # Remove the schema. print(client.delete_schema("articles")) # True print(client.get_schema("articles")) # None client.close()

set_schema returns the new schema’s ETag as a string, not a schema object. get_schema returns Optional[Schema] — None means the collection exists but has no schema defined, which is a normal state and not an error.

The enforcement argument accepts only "off", "warn" or "strict"; anything else raises before a request is made.

Setting and reading an Aetherfy schema in JavaScript

import { AetherfyVectorsClient, DistanceMetric, Schema, } from 'aetherfy-vectors'; const client = new AetherfyVectorsClient(); async function main() { await client.createCollection('articles', { size: 4, distance: DistanceMetric.COSINE }); const schema: Schema = { fields: { title: { type: 'string', required: true }, status: { type: 'string', required: true }, views: { type: 'integer', required: false }, tags: { type: 'array', required: false, elementType: 'string' }, }, description: 'Article payload contract', }; const etag = await client.setSchema('articles', schema, 'strict', 'v1'); console.log(etag); // the ETag string of the new schema version const loaded = await client.getSchema('articles'); if (loaded) { console.log(Object.keys(loaded.fields).sort()); // [ 'status', 'tags', 'title', 'views' ] console.log(loaded.fields.title.type); // string console.log(loaded.fields.title.required); // true console.log(loaded.fields.tags.elementType); // string } console.log(await client.deleteSchema('articles')); // true console.log(await client.getSchema('articles')); // null client.dispose(); } main();

getSchema resolves to Schema | null; null means no schema is defined. The enforcement mode is the third positional argument and defaults to 'off'.

Inferring an Aetherfy schema from existing points

analyze_schema / analyzeSchema samples the points already in a collection and proposes a schema. It writes nothing — you decide whether to install the suggestion.

sample_size must be between 100 and 10000 inclusive; the default is 1000.

Analyzing in Python

from aetherfy_vectors import AetherfyVectorsClient client = AetherfyVectorsClient() result = client.analyze_schema("articles", sample_size=1000) print(result.collection) # articles print(result.sample_size) # number of points actually sampled print(result.total_points) # points in the collection print(result.processing_time_ms) # server-side processing time, integer ms print(sorted(result.suggested_schema.fields)) # ['status', 'tags', 'title', 'views'] # Install the suggestion, still without enforcing it. etag = client.set_schema("articles", result.suggested_schema, enforcement="off") client.close()

Analyzing in JavaScript

import { AetherfyVectorsClient } from 'aetherfy-vectors'; const client = new AetherfyVectorsClient(); async function main() { const result = await client.analyzeSchema('articles', 1000); console.log(result.collection); // articles console.log(result.sampleSize); // number of points actually sampled console.log(result.totalPoints); // points in the collection console.log(result.processingTimeMs); // server-side processing time, integer ms console.log(Object.keys(result.suggestedSchema.fields).sort()); // [ 'status', 'tags', 'title', 'views' ] await client.setSchema('articles', result.suggestedSchema, 'off'); client.dispose(); } main();

The Aetherfy AnalysisResult shape

Python fieldJavaScript fieldType
collectioncollectionstring
sample_sizesampleSizeinteger
total_pointstotalPointsinteger
fieldsfieldsmap of field name to per-field analysis
suggested_schemasuggestedSchemaSchema
processing_time_msprocessingTimeMsinteger milliseconds

A safe rollout is: analyze_schema to get a suggestion, set_schema with off to record it, switch to warn while you watch for mismatches, then strict once writes are clean.

Related: First collection for creating and filling a collection, Retrieve, delete, count for removing points rather than the whole collection, and the SDK reference for the complete method list.

Last updated on