Skip to content

Create a database

Provision a managed PostgreSQL or MySQL database from the dashboard, CLI, or API. This page documents every field on the create request and how PandaStack turns it into a running cluster.

Creating a database writes the database row (status: queued) plus a transactional outbox row (database.provision) in a single transaction. A relay publishes it to Google Pub/Sub and worker-v3 applies the KubeBlocks Cluster CR. The worker fills in publicUrl, privateUrl, and the proxy version only once the pod reaches Running.

POST /v1/databases

The request body is CreateDatabaseInput:

FieldTypeRequiredDefaultNotes
namestringYesRFC-1123 label: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$, 1–63 chars. Lowercase alphanumeric and hyphens, must start/end alphanumeric.
typeenumYespostgresql or mysql.
versionstringYesMust be on the version allow-list for the engine (see below).
instanceTypestringYesA tier slug, e.g. free-tier, standard-tier. See Tiers & scaling.
visibilityenumNopublicpublic or private.
usernamestringNoengine default1–63 chars. Defaults to root (MySQL) or postgres (PostgreSQL).
dbNamestringNoengine default1–63 chars. Defaults to mysql (MySQL) or postgres (PostgreSQL).
passwordstringNoauto-generatedMin 8 chars. Omit to have PandaStack generate a 24-character alphanumeric password.
regionstringNousOnly us exists today.
backupenumNodisabledenabled or disabled. See Backups & restore.
architectureenumNostandalonestandalone (Single Zone, 1 replica) or replicaset (Multiple Zone / HA, paid-only).
projectIdnumberNoPositive integer. Links the database to a project.

Choose an engine (type) and a version from the allow-list. A version outside the list is rejected — the worker builds a cluster version reference from engine + version with no other fallback, so only these resolve to a working cluster.

Engine (type)Versions acceptedNotes
postgresql16.4.0, 14.8.0Use 16.4.0 for new databases. 14.8.0 is deprecated for new databases. PostgreSQL 17/18 need KubeBlocks ≥ 1.0 (fleet runs 0.9.1) — not offerable yet.
mysql8.4.2, 5.7.448.0.33 is excluded (broken / CrashLoopBackOff).

mongodb appears in the engine picker but is deprecated and unprovisionable — you cannot create a new MongoDB database.

The instanceType is a tier slug from the database tier catalog. Tiers range from the free free-tier (0.25 vCPU / 0.5 GB RAM / 1 GiB disk) up to c2-2xcompute-tier (8 vCPU / 16 GB / 80 GiB). A non-free tier requires an active paid plan — a free organization cannot provision a paid-tier database, and the shared paid gating (isOrgPaid) is enforced on the server so a raw API caller cannot bypass it.

See the full catalog and per-tier disk / price on Tiers & scaling.

visibilityReachable fromUse when
public (default)The open internet via the *.db.pandastack.app proxy over TLSYour client runs outside PandaStack (laptop, CI, external host)
privateOnly inside the platform networkOnly your PandaStack apps connect

The exact connection rules — especially the MySQL username routing — are on Connecting.

architectureTopologyAvailabilityPlan
standalone (default)Single Zone, 1 replicaNo HAAny tier
replicasetMultiple Zone, 3 replicasHigh availabilityPaid only

The free tier is single-zone only; selecting a free tier snaps architecture back to standalone.

You may pass a username, dbName, and password, or omit any of them:

  • Password — omit it and PandaStack auto-generates a 24-character alphanumeric password. Passwords are AES-encrypted at rest (iv:cipher) and never returned in a normal response.
  • Username / database defaults follow engine conventions:
EngineDefault usernameDefault database
MySQLrootmysql
PostgreSQLpostgrespostgres

Set backup: enabled at create time to turn on scheduled backups; the retention count (backupsToKeep) applies from there. See Backups & restore.

  • One free database per organization. Attempting a second while one exists is rejected.
  • A free database is created with a 30-day expiry and follows the suspend → purge lifecycle. See Free-tier lifecycle.
  • Free databases are single-zone (standalone) only.
Terminal window
curl -X POST https://api.pandastack.io/v1/databases \
-H "Authorization: Bearer $PANDASTACK_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "app-db",
"type": "postgresql",
"version": "16.4.0",
"instanceType": "standard-tier",
"visibility": "public",
"architecture": "standalone",
"backup": "enabled",
"projectId": 1421
}'

Response (DatabaseDetail, connection URLs masked until the cluster is running):

{
"success": true,
"data": {
"id": 903,
"name": "app-db",
"type": "postgresql",
"version": "16.4.0",
"status": "queued",
"visibility": "public",
"instanceType": "standard-tier",
"organizationId": "48210033",
"region": "us",
"backup": "enabled",
"backupsToKeep": 7,
"architecture": "standalone",
"serverDetails": { "cpu": 1, "memory": 2, "disk": 10 },
"publicUrl": null,
"privateUrl": null,
"connectionDetails": {
"host": null, "port": null, "username": "postgres",
"database": "postgres", "passwordAvailable": true
},
"createdAt": "2026-07-14T10:30:00.000Z",
"updatedAt": "2026-07-14T10:30:00.000Z"
}
}

The response follows the standard envelope: { "success": true, "data": <T> }. Once the worker finishes, status becomes running and publicUrl / privateUrl are populated (masked). A free-org quota violation returns 402 quota_exceeded; a paid-only tier or replicaset on a free org returns 402.