API reference · Management plane
Projects
Create, read, rename, export and delete projects, and read their usage.
Host: https://api.manybases.com · Key: ak_. Two gestures also require a signed-in human (X-Account-Session).
/v1/projectslist_projects{ id, name, plan, region, app_url, seats: { used, cap, as_of }, created_at, status, urls: { api } }. seats.used and seats.as_of can be null — see "A dated reading". Paginated: limit defaults to 50, maximum 200, and cursor reads the next page, newest project first./v1/projects { name, plan? }create_project201 with the project card. Provisions a real database and a file bucket (about 6 s). Requires a key with the "every project" scope; 402 quota_exceeded when the account's app limit is reached (Free: 2, Builder: 20, Studio: 100). plan is ignored: the plan is the account's/v1/projects/:pidget_projecttables (a count), urls.api — the host of the project's data plane — and urls.site, the site's address. Its figures are the last reading, with its date: reading the card measures nothing — see "A dated reading"/v1/projects/:pid { name?, app_url? }set_app_urlapp_url is https:// only, in canonical form with its trailing slash (https://my-app.example/), or null to clear it. Changing app_url requires a signed-in human and confirms in two steps; name alone requires nothing/v1/projects/:pid/usageget_usage/v1/projects/:pid/export/v1/projects/:piddelete_projectThe project card#
plan is the account's plan — free, personal (the Builder plan) or studio — and sets the seat cap (3 on Free, 1 000 on Builder and Studio). region is where the data lives — weur, Cloudflare's Western Europe region — fixed at creation. status has three values on the wire:
provisioning— resources are being created. Export and delete answer409meanwhile.active— nominal.suspended— the account is above a volume quota (file storage, database size, or requests of the UTC month). Reads keep serving; every write on the data plane answers402 quota_exceeded. The status is set and lifted by an hourly job, never by a request. Management keeps working: card, rename, keys, export and delete — deleting an app is the way out of an overage, and it is never locked. See Limits.
A project being deleted no longer appears in the list, and its card answers the neutral 404.
The app URL#
app_url is the public address of the app. Invitation links are built from it, and the first deployment of a site fills it in when it is empty. Because changing it redirects every user of the app, a chosen value only enters through a signed-in human and a confirmation: the first PATCH answers 428 with a confirmation_token; the second, same body plus token, applies. Deploying a site never replaces an existing value; taking a site down clears the app URL only if it still pointed at that site. See Sites.
A dated reading#
No route measures anything: list_projects, get_project and get_usage return the platform's last reading of the project, with its as_of. The platform refreshes that reading on its own, every five minutes, a few projects at a time, whether or not anyone asks; creating a project records zeros, which are true. A project never observed returns null for these figures, with a hint — never a 0, which would read "this project is empty". No call refreshes them.
Usage#
GET /v1/projects/:pid/usage returns:
{ "data": {
"storage_bytes": 12345, "db_bytes": 67890, "rows": null,
"requests_month": 1200,
"seats": { "used": 2, "cap": 3, "as_of": "2026-09-04T10:00:00Z" },
"quotas": { "storage_bytes": …, "db_bytes": …, "requests_month": … },
"as_of": "2026-09-04T10:00:00Z"
} }storage_bytes,db_bytes,rowsandseatscome from the last observation, withas_of.db_bytesis the size of the database file as the platform reports it, which can lag behind the latest writes.rowsis not measured: it is0right after creation, thennull.requests_monthis the account's total for the current UTC month, served on a project route on purpose: the quota is counted account-wide. It counts data-plane requests carrying a valid key; replays and authentication refusals are excluded. The window reopens on the 1st of the month; deleting projects never resets it.quotasare the plan's limits, not a reading.- Anything the API cannot derive is
null, with a hint saying so.
The app limit#
The Free plan allows 2 apps, Builder 20 and Studio 100. The limit counts existing projects, never the historical total: deleting one frees its slot immediately. POST /v1/projects beyond the limit answers 402 quota_exceeded with the figure and the two exits — delete an app, or upgrade. An account that comes back down to Free keeps its projects; the ones beyond the limit, in creation order, switch to read-only until the account is back under.
Export#
GET /v1/projects/:pid/export returns a zip with dump.sql (schema and data, restorable elsewhere), the project's files and a manifest.json that lists the tables, their presets, and the internal tables the archive deliberately leaves out. It requires a signed-in human, and the refusal comes before the ownership check — an agent alone gets the same 401 whether the project exists or not. Details and the current bound on the number of files: Export.
Deleting a project#
Two gates, in this order: X-Account-Session (without it 401, no token, definitive for an agent), then a confirmation_token from a first 428 call. Nothing is destroyed and the slot is not freed until the second call. A token that no longer counts — expired after 5 minutes, already used, issued for another project or another account — is treated as absent: 428 again with a fresh token, and the response never says which of the four conditions applied. Replaying the DELETE on a project already being deleted answers 200; once it is gone, the neutral 404.
