Each collection is its own vector index. The default is 768 dimensions — what Harakumo's default embedding model (bge-base) produces, so text you send fits as-is. Choose 384 (bge-small) or 1,024 (bge-large) to match those models, or 1,536 for vectors you make elsewhere; larger is refused.
Embed, upsert, query
SDK
const { collection } = await hk.vectors.create(project.id, {
name: 'docs', dimensions: 768, metric: 'cosine',
metadataIndexes: [{ propertyName: 'lang', indexType: 'string' }],
});
// Send text and let Harakumo embed it (metered on AI credits), or send your own "values".
await hk.vectors.upsert(collection.id, [
{ id: 'doc-1', text: 'Peaches are in season in July.', metadata: { lang: 'en' } },
{ id: 'doc-2', text: 'Mangoes ripen best at room temperature.', metadata: { lang: 'en' } },
]);
const { matches } = await hk.vectors.query(collection.id, {
text: 'when can I buy peaches?', topK: 3, filter: { lang: 'en' }, returnMetadata: 'all',
});Namespaces and filters
- Give each vector a
namespace(one per end user, say); a query that names the namespace sees only its vectors. - Filters work on metadata fields made filterable with
metadataIndexesat create time, or later withPOST /api/vectors/:id { action: "index-metadata", propertyName, indexType }. Only vectors written after a field is indexed are filterable. Filtering on a field that is not indexed is a 400 that says so. - Delete vectors with
POST /api/vectors/:id { action: "delete", ids: [...] }.
Limits
- Upsert up to 1,000 vectors per request (100 when sending text); metadata up to 10 KB per vector.
- topK up to 100, or 50 when returning full metadata or values.
- Upserts are applied in the background: allow a few seconds (up to about 30) before new vectors show in queries.
GET /api/vectors/:idreports the index's own count. - Collections per plan: 1 hobby, 10 pro, 200 enterprise.
- Keys: a key limited to the project works for everything here; a read-only key can query but not upsert or delete.
Reference
SDK
const { embeddings } = await hk.ai.embed(['fresh mango', 'ripe banana'], 'bge-base'); // 768 dims
await hk.vectors.upsert(collectionId, [{ id: 'a', values: embeddings[0], metadata: { title: 'Mango' } }]);
const { matches } = await hk.vectors.query(collectionId, { vector: embeddings[1], topK: 5 });REST
POST /api/projects/:id/vectors { "name": "docs", "dimensions"?: 768, "metric"?: "cosine", "metadataIndexes"? }
POST /api/vectors/:id/upsert { "vectors": [{ "id": "doc-1", "values"?: [...], "text"?: "…", "metadata"?: {}, "namespace"? }] }
POST /api/vectors/:id/query { "vector"?: [...], "text"?: "…", "topK"?: 5, "filter"?, "namespace"?, "returnMetadata"?: "all"|"indexed"|"none" }
GET /api/vectors/:id # the collection and its vector count
POST /api/vectors/:id { "action": "delete", "ids": [...] } | { "action": "index-metadata", "propertyName", "indexType" }
DELETE /api/vectors/:id