/data, SDK data() and custom-tool ctx.data interfaces use the generic
Data namespace; agent tools use database_*.
Data is opt-in. Your project must have Data enabled before its API and dashboard
are available. Disabling Data preserves its contents.
Create a database
Open Databases in the project dashboard, select Live or Test, then choose Create database. Define the tables with a schema such as:text, integer, number, boolean, timestamp,
uuid and json. Every row also has _id, _version, _created_at and
_updated_at. Tables can have indexes and foreign keys within the same database.
Databases have immutable UUIDs. Renaming a database preserves its records and
grants. Edit schema supports adding tables, nullable columns and indexes.
Use Migrations for supported SQL schema changes and backfills. The additive
Edit schema API preserves existing columns; destructive SQL changes require
explicit intent.
Connect an application
Use your normal Polpo API key from API Keys. It provides full Data access within its existing organization/project scope, including schema administration. Keep the key in your application backend. The application authenticates its users and enforces their permissions before calling Polpo. Data does not provide built-in application users or per-user row security.Grant an agent access
In the database’s Access tab, grant an agent read-only or read/write access, optionally restricted to tables. Select agents from the project catalog, or manage an agent’s access from its Databases tab. These grants are independent of the application’s Polpo API key. Enabledatabase_* in its tool policy. Available
tools include database_list, database_describe, database_read, database_insert,
database_update, database_delete, database_upsert, database_transaction
and database_query.
database_read queries one table with typed filters, ordering and pagination.
database_transaction executes a batch of record operations in one database:
all commit or all roll back. database_query runs scoped SQL, including joins and
aggregates, with a default of 20 returned rows and maximum of 50. Mutations require
explicit write mode and write grants.
database_delete deletes a record, not the database.
For example, read the latest 20 paid orders with database_read:
ctx.data:
Concurrency and limits
Updates and deletes require the expected row version. Refresh and resolve a conflict if another caller changed the row. Atomic batches execute throughpolpo.data(id).transaction(operations, { idempotencyKey }). Reusing a key with
an identical request returns the original result; changing its body is rejected.
The key is scoped to the caller and resource.
Requests are limited to 256 KiB, batches to 100 operations, and transaction
results to 1 MiB. Oversized results roll back the batch. Reads return at most 200
rows per page; bounded offset pagination does not provide a snapshot across
concurrent writes. Use the returned nextOffset to continue, up to offset 10,000.
SQL queries and mutations
data.query() executes one parameterized statement within one logical database.
The PostgreSQL provider supports SELECT with joins, aggregates, subqueries,
UNION and VALUES; INSERT, UPDATE, DELETE and ON CONFLICT require
explicit mode: "write". Every referenced table must be granted for its operation.
Use unqualified logical table names and $1, $2, … parameters for values.
_version and _updated_at automatically.
Unlike typed updates, SQL requires the caller to include a version predicate when
optimistic concurrency is needed; zero affected rows means the predicate did not
match. The result contains rows, rowCount and truncated. Read rowCount is
the returned row count, not a full-table count. Write rowCount includes all
affected rows even when the returned page is truncated. maxRows defaults to 200
and cannot exceed 200. Result-size failures roll back mutations. Text columns
hold at most 64 KiB of UTF-8 text; numbers and timestamps must be finite.
This is a bounded PostgreSQL subset, not an unrestricted PostgreSQL connection.
Cross-database/schema access, catalogs, role/session changes, procedural SQL,
CTEs, table functions, arbitrary functions and server extensions are rejected.
Only supported column types and an explicit function allowlist are accepted.
Provider capabilities declare the SQL dialect and migration support; a provider
without SQL returns data_invalid. Use typed operations for portable record access.
SQL migrations
Administrators can apply ordered DDL and data backfills atomically:CREATE TABLE,
ALTER TABLE (add/drop/rename column, rename table, set/drop not-null, supported
type changes) and ordinary CREATE/DROP INDEX and DROP TABLE. Column constraints
support NOT NULL, UNIQUE and same-database REFERENCES; Polpo adds system columns.
Defaults, triggers, custom types and arbitrary ORM migration SQL are not supported.
Drops and type changes require allowDestructive: true; cascading drops are rejected.
A failure rolls back schema, backfills, catalog version and migration history.
A migration ID is immutable: retrying an identical request returns its original
result, while changing a recorded request is a conflict. History includes ID,
checksum, applied schema version and timestamp. Keep the original expectedVersion
when retrying the same migration. Each new migration uses the current version.
Migrations require manage; agent tools and ctx.data do not expose administration.
CLI and HTTP
resource.json contains { "name": "crm", "schema": { ... } }.
operations.json contains { "operations": [ ... ], "idempotencyKey": "..." }.
query.json contains {sql,params?,mode?,maxRows?,idempotencyKey?};
migration.json contains the migration object shown above. The CLI also supports
additive migrate, rename and version-checked delete with explicit
confirmation.
The CLI uses your authenticated Polpo session and selected project. To use a normal
Polpo API key directly, set POLPO_API_KEY and pass --url with the API origin
and --project with the project UUID. The key selects Live or Test; there is no
separate CLI environment override. For the standard self-hosted server use
--url http://localhost:3890/api.
Cloud also provides project administration routes:
These routes require project administrator access. Agent grants reference immutable
resource UUIDs and may restrict tables. Live and Test grants are separate; the
dashboard selects its environment while API keys use their bound environment.
Schema and database administration requires administrator access. Record tools
cannot create, migrate or delete databases. API errors have stable
data_*
codes and never expose SQL or provider credentials.
To create a database through the normal API, send a body containing name and
schema to POST /v1/data using administrator credentials. The schema uses the
same tables definition shown above.
The SDK equivalent is polpo.createData({ name, schema }). This administration
capability is available through HTTP, SDK, CLI and the dashboard. Agent tools and
custom-tool ctx.data expose record access according to their agent grants.
Normal project API keys also support schema administration. Dashboard members
can read/write records and run record SQL; owner/admin accounts manage schemas,
migrations and agent grants.
MCP and builder
The remote MCP and the in-product builder exposepolpo_databases_* tools for
list/get/create/rename/delete, schema evolution, transactions, SQL query/mutate,
SQL migrations/history, backend status and agent grants. They use the authenticated
Polpo account with an explicit projectId and optional environment (live by
default). polpo_databases_query is read-only; SQL writes use
polpo_databases_mutate. Existing MCP OAuth read/write scopes still apply.
These account-management tools are distinct from the agents’ database_* tools.
See the MCP tool catalog for all 14 tool
names and their inputs. The selected project must have Data enabled; account
membership and administrative roles are checked for each operation.
Agent directories
An agent enablesdatabase_* in .polpo/agents/<name>/agent.json. Databases are
project resources, not files inside an agent directory. There is no data field
or data/ subdirectory. Grants stay in Cloud administration. polpo deploy and
polpo pull do not apply migrations or copy records and grants; use explicit
API/SDK/CLI migration steps. Application user management remains your application’s
responsibility.
Hosting
The interface is provider-independent. OSS self-hosting currently uses a separate PostgreSQL application database; managed Polpo provisions it on Neon. Logical databases have separate schemas and transaction roles. Managed resources sharing a Neon branch also share compute and the branch’s backup/restore lifecycle; independent per-resource restore is not provided. The OSS dashboard includes Databases at/data: a Schema selector, table
navigation, record editing, SQL queries/mutations and migrations/history. It uses
the configured runtime backend. Live/Test selection, Neon provisioning controls
and the agent grant editor belong to the managed host; self-hosted grants remain
runtime configuration.