# Vector DB

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**

```js
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 `metadataIndexes` at create time, or later with `POST /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/:id` reports 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**

```js
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**

```http
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
```
