# smartbotic-vectorapi

> General-purpose REST API over smartbotic-database. **Multi-project**: every
> collection and document lives under a named project supplied as a URL path
> segment (e.g. `/api/v1/projects/{project}/collections`). **Multi-key**: each
> API key carries a list of project grants (MySQL-style; `["*"]` for all); admin
> keys additionally manage projects and keys. Auth: `Authorization: Bearer <KEY>`.
> Machine-readable spec: `/openapi.json` (OpenAPI 3.1).

## Projects

Requires a valid key. Admin-only operations are noted.

- `GET  /api/v1/projects` — List projects the key may access (admin sees all).
- `POST /api/v1/projects` `{name}` — Create a project (admin).
- `GET  /api/v1/projects/{project}` — Get project info (collection/document counts).
- `DELETE /api/v1/projects/{project}` — Drop a project (admin; the `default` project cannot be dropped).

## Keys (admin)

All key-management endpoints require an admin key.

- `GET  /api/v1/keys` — List keys. Secret value is masked; returns `id`, `key_prefix`, `label`, `projects`, `admin`, and `created_at`. Use `id` to reference the key in PATCH/DELETE.
- `POST /api/v1/keys` `{label, projects:[], admin?}` — Generate a new key. Returns the secret key value **once** (store it immediately) plus the stable `id`.
- `PATCH /api/v1/keys/{id}` `{label?, projects?, admin?}` — Update grants for an existing key, identified by its `id` (not the secret).
- `DELETE /api/v1/keys/{id}` — Revoke a key by `id`. Active sessions using it are immediately invalidated.

## Collections

Project-scoped. A key must be granted the project.

- `POST   /api/v1/projects/{project}/collections` `{name, kind:"json"|"vector", vector_dimension?, embedding_model?}` — Create a collection. `vector_dimension` is required for `kind=vector`. `embedding_model` defaults to the server's `default_embedding_model` setting.
- `GET    /api/v1/projects/{project}/collections` — List collections with metadata (incl. `document_count`, `size_bytes`). Query params (all applied server-side): `q` (case-insensitive name substring filter), `sort` (`name`|`kind`|`documents`|`size`|`created_at`, default `name`), `desc` (bool).
- `GET    /api/v1/projects/{project}/collections/{name}` — Get collection metadata.
- `DELETE /api/v1/projects/{project}/collections/{name}` — Drop a collection and all its documents.

Collection names may not start with `_` or the reserved prefix `vectorapi_`.

## JSON documents

Arbitrary JSON CRUD under a `kind=json` collection.

- `POST  /api/v1/projects/{project}/collections/{name}/documents` `{data:{…}}` — Insert a document. Returns `{id}`.
- `GET   /api/v1/projects/{project}/collections/{name}/documents/{id}` — Fetch a document by ID.
- `PUT   /api/v1/projects/{project}/collections/{name}/documents/{id}` — Replace a document (full upsert).
- `PATCH /api/v1/projects/{project}/collections/{name}/documents/{id}` — Partially update a document (merge fields).
- `DELETE /api/v1/projects/{project}/collections/{name}/documents/{id}` — Delete a document.
- `GET   /api/v1/projects/{project}/collections/{name}/documents` — Find documents.

**Filter grammar**: `?filter=field:op:value` (repeatable; ANDed). Supported ops: `eq`, `ne`, `lt`, `lte`, `gt`, `gte`, `contains`. Example: `?filter=age:gte:30&filter=name:eq:Alice`.

Additional query params: `limit` (default 20), `offset` (default 0), `sort` (field name), `desc` (bool).

## RAG vectors

Requires a `kind=vector` collection. Vectors are stored with cosine-similarity indexing.

- `POST /api/v1/projects/{project}/collections/{name}/vectors` `{id?, text?, vector?, metadata?}` — Store a vector. Supply either `text` (the server embeds it using the collection's `embedding_model`) or a pre-computed `vector` array. `vector` dimension must match the collection's `vector_dimension`. `metadata` is an arbitrary JSON object stored alongside the vector.
- `POST /api/v1/projects/{project}/collections/{name}/search` `{query_text?, query_vector?, top_k, min_score?, filters?}` — Cosine-similarity search. Supply either `query_text` or `query_vector`. `top_k` (required) limits results. `min_score` (0–1) filters low-confidence matches. `filters` apply the same `field:op:value` grammar to vector metadata.

## Settings (admin)

All settings endpoints require an admin key.

- `GET  /api/v1/settings` — Return current settings as JSON. `openai_api_key` is masked: the field is absent and `openai_api_key_set` (bool) indicates whether a key is configured.
- `PUT  /api/v1/settings` `{openai_api_base?, openai_api_key?, default_embedding_model?, cors_origins?, session_ttl_minutes?, webui_enabled?, default_project?}` — Merge the supplied fields into the current settings and persist. Omit `openai_api_key` (or pass an empty string) to keep the existing secret. Changes are hot-reloaded immediately.

## Stats

- `GET /api/v1/projects/{project}/stats` — Per-project stats (collections, document counts). Accessible to any key granted the project.
- `GET /api/v1/stats` — Server-wide stats including `memory_pressure_level`. Admin only.

## Ops

Public (no auth required):

- `GET /healthz` — Liveness probe; always 200 while the process is running.
- `GET /readyz`  — Readiness probe; 200 when the database is reachable, 503 otherwise.
- `GET /openapi.json` — OpenAPI 3.1 machine-readable spec.
- `GET /llms.txt`     — This file.

Session login (used by the web UI):

- `POST /ui/login` `{key}` — Exchange an API key for an HttpOnly session cookie (`svapi_session`). The cookie may be used in place of the `Authorization: Bearer` header for all `/api/v1/*` endpoints.
