Technical docs
Storage Databases
Overview
Organization Storage databases are SQLite files managed in the `/databases` workspace. Use them for structured, changing data. See `storage.md` for general file and folder rules and `references/websites-forms-dashboards.md` for read-only website queries.
Workspace
- `/databases` lists databases and offers `Add` to create one; a database has a display name, permanent identifier (alias), and optional description. Rename changes the display name, not the identifier. `Delete permanently` removes the database and every table with no undo.
- Open a database to see its tables, row counts and size. Create, rename, and permanently delete tables. Creating a table adds `id` automatically; define at least one data column. A table also has an internal `_version` column for updates.
- A table has `Data` and `Schema` views. Data supports adding, editing, selecting and deleting rows, pagination, sorting, and `Typed filters`. Filters can match `All filters` or `Any filter`, are applied to the full table rather than only the visible page, and can be cleared. Schema allows adding and renaming columns; column types cannot be changed in place. Deleting a column permanently removes its values from all rows.
- Supported data column types: `TEXT`, `INTEGER`, `REAL`, `BOOLEAN`, `TIMESTAMP`. A row editor offers `Empty` for nullable values. Changes to databases and tables update open views through realtime events.
Names, limits, and SQL
- Database aliases are 1 to 63 lowercase letters, digits, `_`, or `-`, starting with a letter or digit. Table and column names are 1 to 63 letters, digits, or `_`, starting with a letter or `_`.
- Limits: 20 managed databases per organization, 256 MiB per managed database, 100 tables per database, 100 columns per table, and at most 1,000 inserted or returned rows per operation. List rows with `limit` (default and maximum 1,000) and `offset`; use a read-only query to aggregate, count, group, or join instead of downloading all rows.
- Raw queries accept one `SELECT` or `WITH ... SELECT` statement and positional `?` parameters. Writes, `PRAGMA`, `ATTACH`, and multiple statements are not available through the query surface. In raw SQL, `BOOLEAN` values are stored as 0/1; managed tables expose `id` and `_version`.
- Managed databases live under `.databases/{alias}` in organization Storage and use `.sqlite` files; `.db3` files are also recognized. Uploading a `.sqlite` or `.db3` file elsewhere in Storage does not create a managed alias. AI tools `database.schema` and `database.query` may read a permitted Storage file by `storage_path` instead of alias, but do not modify it.
Organization API
Authenticated organization routes use `/api/organizations/{organization_id}/storage/databases` as their base. `GET` lists and `POST` creates databases; `PATCH /{alias}` changes the display name and `DELETE /{alias}` permanently removes one. `POST /{alias}/query` takes `{ "sql": "SELECT ...", "params": [] }` for read-only SQL. `GET` and `POST /{alias}/tables` list and create tables. `GET`, `PATCH`, and `DELETE /{alias}/tables/{table}` read the schema, rename, and permanently delete a table. `POST /{alias}/tables/{table}/columns` adds a column; `PATCH` and `DELETE /{alias}/tables/{table}/columns/{column}` rename and permanently remove one. `GET`, `POST`, `PATCH`, and `DELETE /{alias}/tables/{table}/rows` list, insert, batch-update, and batch-delete rows; `GET` and `PATCH /{alias}/tables/{table}/rows/{row_id}` get and update one row. Row-list query parameters include `limit`, `offset`, `order_by`, `direction`, `match`, and a JSON-encoded `filters` array. Organization access is required; mutations require an active organization. These are organization routes, not the `/api/private/storage` file API.
AI teammate tools and access
`database.list`, `database.schema`, `database.create`, `database.create_table`, `database.alter_table`, `database.insert_rows`, `database.list_rows`, `database.update_rows`, `database.delete_rows`, and `database.query` are normally loaded on demand when lazy tools are enabled. Read database schema before changing rows. Batched row updates accept `expected_version` to detect concurrent changes; row deletion is permanent. Database, table, and column deletion are not exposed as AI tools.
A regular AI teammate needs readable or writable Storage sharing for `.databases/{alias}` (or an inherited grant on `.databases`); creating a database requires write access to `.databases`. An unshared database is not returned to that teammate. System AI teammates operate under organization-level Storage access. `database.schema` and `database.query` take exactly one of `alias` or `storage_path`; a storage path is limited to files that the teammate can read.
Website access
A Storage website can query a managed database read-only through `window.alloy.databases.query(alias, sql, params)` after declaring its alias in `.alloy.json` beside the site's entry page. `window.alloy.databases.subscribe(alias, callback)` supplies change notifications while the preview is open. Websites cannot write database rows. See `references/websites-forms-dashboards.md` for the manifest and example.