A cluster is one logical PostgreSQL database — a primary node plus zero or more async read replicas — managed as a single resource. Operations that affect every node go here; per-node operations live in Nodes.

Create

POST /database/cluster/create
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "app-prod",
  "image_id": 1,
  "instance_type": "m1a.xlarge",
  "subnet_id": 1,
  "zone_id": 1,
  "project_id": 1,
  "allocate_public_ipv4": false,
  "is_multi_az": false,
  "security_group_ids": [12]
}

Required: name, image_id, instance_type, subnet_id, zone_id, project_id, allocate_public_ipv4.

Optional: is_multi_az (provisions two standbys), security_group_ids, ssh_pubkey, network_interfaces.

The response returns:

FieldNotes
idCluster ID — pin this in your config
nameEchoed back
hostnameDNS name clients connect to
nodes[]One element today (the primary)
postgres_passwordShown once. Save it immediately

The default database user is postgres.

List

GET /database/list?zone_id=1
Authorization: Bearer <token>

Omit zone_id to list across every zone. The response returns clusters with their hostname, id, name, and nodes — never the postgres password.

Restart

POST /database/cluster/restart
Authorization: Bearer <token>
Content-Type: application/json

{ "cluster_id": <id> }

Rolls every node — replicas first, then the primary with a failover. Typical downtime for the primary is a few seconds during the failover.

Terminate

POST /database/cluster/terminate
Authorization: Bearer <token>
Content-Type: application/json

{ "cluster_id": <id> }

Irreversible. Take a backup first if you might need the data. Terminate removes every node, releases storage, and drops the DNS record for the hostname.

Rotate the admin password

POST /database/resetpassword
Authorization: Bearer <token>
Content-Type: application/json

{ "cluster_id": <id> }

Response includes db_password and invalidates the old one immediately. To roll without an outage:

  1. reveal the current password from Secrets and verify your app reads it that way.
  2. Call resetpassword.
  3. Update the secret to the new value (exc secret version add).
  4. Restart / signal your app so it re-fetches.

Apps that cache the password forever will start failing the moment step 2 lands — plan accordingly.

Hostname

The hostname returned at create time is stable for the life of the cluster — it doesn’t change across restarts, password rotations, or node-add operations. Failover redirects automatically. Apps should resolve the hostname and reconnect on failure, not cache the underlying IP.

Required permissions

ActionPermission
Createdatabase:cluster:create
Listdatabase:cluster:list
Restartdatabase:cluster:restart
Terminatedatabase:cluster:terminate
Reset passworddatabase:cluster:resetpassword

Resource scoping: exc:database:cluster/<id>. See the Policies guide.