HeatherDB

Search documentation

Loading the documentation index…

Download
HeatherDB documentation
DocumentationHTTP API

Database endpoints

Create, list, inspect and drop databases. A database owns one LMDB environment, its own vector dimension, and its own collections.

/db (the collection of databases) is root only. /db/{db} is reachable by root or by a user scoped to that database. See Overview and Run several databases.

GET /db

List every database.

Auth: Basic or Bearer, root scope.

Request body: no body.

curl -u admin:pw http://localhost:6380/db
{ "databases": [
  { "name": "default", "created_at": 1767225600, "dimension": 128,
    "map_size_mb": 4096, "collections": 3 }
] }

Half-initialised directories (no readable db.toml) are skipped rather than failing the call.

StatusCause
403 Forbiddenthe caller is scoped to a database
500 Internal Server Errorthe database directory could not be listed

POST /db

Create a database.

Auth: Basic or Bearer, root scope.

FieldTypeDefaultNotes
namestringrequired1–63 chars, [a-z][a-z0-9_-]*. Must not start with _
dimensionintegerrequiredImmutable for the life of the database
map_size_mbinteger4096LMDB ceiling for this database's env
mdl_gatebooleanfalseAllocate by description length instead of tau_split/tau_overload
eamobject—Partial EAMConfig override: k, t_max, beta, neighbor_cap, num_landmarks, l_0, competitive, precision. Unset fields keep the engine default; the merged config is validated. "competitive": false makes every collection a plain store: writes append each vector as its own location with no activation, merge or migration, use it to retain individual observations, including similarity-based associative recall through attention. Competitive mode learns shared patterns and can adapt through graceful forgetting. See Choose a memory mode. "precision": "f32" stores vectors in half the space (rounded to f32 when written; all math stays f64). Both are fixed for the database's lifetime, and GET /db / GET /db/{db} report them
curl -u admin:pw -X POST http://localhost:6380/db \
  -H 'Content-Type: application/json' \
  -d '{"name":"movies","dimension":384,"map_size_mb":32768,
       "eam":{"k":64,"t_max":8}}'

Responds with the same shape as GET /db/{db}:

{ "name": "movies", "created_at": 1767225600, "dimension": 384,
  "map_size_mb": 32768, "collections": 0, "competitive": true, "precision": "f64",
  "format_version": 1, "skipped_records": 0 }
StatusCause
400 Bad Requestinvalid name, or the merged EAM config failed validation
403 Forbiddenthe caller is scoped to a database
409 Conflicta database of that name already exists
500 Internal Server Errorthe database was created but its config could not be read back

GET /db/{db}

One database's metadata.

Auth: Basic or Bearer, root or Database(db).

Request body: no body.

curl -u admin:pw http://localhost:6380/db/movies
{ "name": "movies", "created_at": 1767225600, "dimension": 384,
  "map_size_mb": 32768, "collections": 0, "competitive": true, "precision": "f64",
  "format_version": 1, "skipped_records": 0 }

collections is 0 when the collection list cannot be read, not an error.

StatusCause
403 Forbiddenthe caller is scoped to a different database
404 Not Foundno db.toml for that name
409 Conflict(any /db/{db}/... route) the database is on disk in a format newer than this server reads; the message says which. See Storage format

format_version is the database's on-disk format; skipped_records counts records reads have skipped since it was opened because they did not decode (non-zero means damage).

DELETE /db/{db}

Drop a database. Moves $DATA/db/{db}/ to $DATA/_trash/{db}-<unix-seconds>/ rather than deleting it — recover by moving the directory back and restarting.

Auth: Basic or Bearer, root or Database(db). The scope classifier is method-blind on /db/{name}/..., so a user scoped to movies can drop movies. Give a database-scoped user a database you are willing to let them delete.

Request body: no body.

curl -u admin:pw -X DELETE http://localhost:6380/db/movies
{ "dropped": true, "purged": false }

{"dropped": false} when the database was not mounted.

With ?purge=true the database is deleted for good instead of kept in _trash/ (it is still moved there first, so it is unmounted atomically): {"dropped": true, "purged": true}. Use it for data you will never recover, such as scratch databases or ones rebuilt from a log; trash is never emptied automatically, so repeated drops of large databases fill the disk. Without it, purged is false.

StatusCause
400 Bad Requestthe move to _trash/ failed
403 Forbiddenthe caller is scoped to a different database, or the target is default, which cannot be dropped (the legacy routes target it)

See also Backup and restore.

GET /db/{db}/durability

Whether the database syncs every commit to disk.

Auth: Basic or Bearer, root or Database(db).

Request body: no body.

curl -u admin:pw http://localhost:6380/db/movies/durability
{ "database": "movies", "sync": true }
StatusCause
403 Forbiddenthe caller is scoped to a different database
404 Not Foundno such database

PUT /db/{db}/durability

Stops or restarts syncing every commit to disk. By default each commit is synced (LMDB's default), which is what makes a write durable, and on macOS it is a full device flush (F_FULLFSYNC) that can dominate write time. {"sync": false} lets commits reach the operating system without waiting for the disk (LMDB NO_SYNC): much faster bulk loads, at the cost that a system crash (not a server crash) can lose recent commits, or corrupt the database on file systems that reorder writes. Use it for data you can rebuild, such as a memory replayed from a log, and turn it back on when the load is done: {"sync": true} flushes everything written meanwhile before it answers.

The setting is not persisted: a restarted server syncs every commit again.

Auth: Basic or Bearer, root or Database(db).

FieldTypeNotes
syncbooleanrequired
curl -u admin:pw -X PUT http://localhost:6380/db/movies/durability \
  -H 'content-type: application/json' -d '{"sync": false}'
{ "database": "movies", "sync": false }
StatusCause
403 Forbiddenthe caller is scoped to a different database
404 Not Foundno such database
500 Internal Server Errorthe flag could not be changed or the flush failed