Skip to content

Infrastructure API

Node-wide infrastructure that no team owns. Unless a row says otherwise, every route here needs a superuser. See Databases and services for the model.

Toolchains apps deploy against. Responses are rows (snake_case), each with a versions list. The detail route adds _def, the catalog definition.

Method Path Permission Body Returns
GET /applications/catalog Authenticated {results}: built-in runtime definitions (key, deploy modes, defaults)
GET /applications/ Authenticated {results}: installed runtimes with their versions
POST /applications/ Superuser {key, version?} The runtime. Installs in the background. Versioned runtimes need a version.
GET /applications/{id} Authenticated The runtime with versions and _def
PATCH /applications/{id} Superuser {defaultVersion?, defaultDeployMode?, defaultBuildCommand?, defaultStartCommand?} The runtime
DELETE /applications/{id} Superuser {detail: "Removal queued."}
GET /applications/{id}/versions Authenticated {results}: installed versions
POST /applications/{id}/versions Superuser {version} The new version row. Installs next to the others.
DELETE /applications/{id}/versions/{versionId} Superuser {detail}. Refused while an app pins it. Removing the default promotes another.
POST /applications/{id}/versions/{versionId}/default Superuser The version. New apps get it by default.
GET /applications/{id}/versions/{versionId}/health Authenticated Cached health {healthy, checkedAt, detail, …}, or {healthy: null, checkedAt: null} before the first probe
POST /applications/{id}/versions/{versionId}/reinstall Superuser The version. Reinstalls an unhealthy toolchain.

Versions look like 3.5.4, 22.12.0, 3.12 or stable (letters, digits, ., +, -, up to 64 characters).

Method Path Permission Body Returns
GET /services/catalog Authenticated {results}: service types with their config schema
GET /services/ Superuser {results}: installed services
POST /services/ Superuser {serviceType, displayName, config?} The service. Installs in the background.
GET /services/{id} Superuser The service, with _def
PUT /services/{id}/config Superuser {config} The service
POST /services/{id}/start Superuser The service
POST /services/{id}/stop Superuser The service
POST /services/{id}/retry Superuser The service. Retries a failed install.
GET /services/{id}/health Superuser Cached health, with the last repair’s lastRepairAt, lastRepairStatus, lastRepairDetail, lastRepairSteps
POST /services/{id}/repair Superuser {detail: "Repair queued."}
DELETE /services/{id} Superuser {detail: "Uninstall queued."}

serviceType is one of redis, memcached, smtp, mailpit, pgbouncer, pgadmin, mongo-express. config is an object of string values whose keys come from the catalog schema. For example, redis takes port (default 6380), bind (default 127.0.0.1), maxmemory (default 256mb), maxmemory_policy (default allkeys-lru), password (empty disables auth) and appendonly (default true). Install logs stream on /ws/services/{id}/logs.

Method Path Permission Returns
GET /db-engines/ Authenticated {results}: engines (postgres: 18, 17, 16, 15, 14. mongodb: 8.0, 7.0, 6.0) with versions, capabilities and labels

Responses are camelCase.

Method Path Body Returns
GET /databases/ {results}: instances
POST /databases/ {version, displayName, port?}. version is an integer major version. The instance (status: "pending"). The first becomes the default.
GET /databases/{id} The instance
POST /databases/{id}/start The instance
POST /databases/{id}/stop The instance
POST /databases/{id}/set-default The instance
POST /databases/{id}/retry The instance. Retries a failed install.
POST /databases/{id}/expose {isPublic, domain?}. domain is required when isPublic is true. The instance. Enables TLS, an SSL-only hostssl rule and a ufw rule, or removes them.
DELETE /databases/{id} {detail: "Uninstall queued."}
GET /databases/{id}/metrics Live metrics (connections, throughput, cache hit ratio, database sizes, host CPU and RAM), or {status: "initializing"} while the monitor role is provisioned
GET /databases/{id}/config Tunable settings
PUT /databases/{id}/config {settings: {name: "value", …}} The instance

Instance fields: id, version, displayName, port, status, isDefault, isPublic, publicDomain, isSystem (the panel’s own cluster), host, isManaged (false for a system cluster on another host), canRestore, dataDirectory, errorMessage, installedAt, createdAt, updatedAt.

The system instance can’t be stopped, uninstalled or exposed. When it’s on another host, every operation that needs the agent returns 422.

Method Path Body Returns
GET /databases/{id}/dbs {results} without connection info
POST /databases/{id}/dbs {dbName, roleName, password?, extensions?, roleAttributes?} The database with connection
GET /databases/{id}/dbs/{dbId} The database with connection
PUT /databases/{id}/dbs/{dbId}/role {roleAttributes: [...]}, the full desired set. [] leaves only LOGIN. The database
DELETE /databases/{id}/dbs/{dbId} {detail: "Drop queued."}

dbName and roleName are at most 63 characters. Leave out password to have one generated. extensions is a list such as ["uuid-ossp", "pg_trgm"]. roleAttributes (for example ["CREATEDB"]) is checked against an allowlist.

connection is {host, port, database, username, password, url}, plus publicHost and publicUrl (sslmode=verify-full) when the instance is exposed. Databases discovered on the cluster (isExternal: true) have no password or URL, and can be backed up but not dropped, restored into or re-permissioned.

Method Path Body Returns
GET /databases/{id}/dbs/{dbId}/backups {results}
POST /databases/{id}/dbs/{dbId}/backups {scope?}: full (default), schema or data The backup
GET /databases/{id}/dbs/{dbId}/backups/{backupId}/download The .sql.gz file (application/gzip), when completed
DELETE /databases/{id}/dbs/{dbId}/backups/{backupId} {detail}
POST /databases/{id}/dbs/{dbId}/restore {backupId} {detail: "Restore queued."}
POST /databases/{id}/dbs/{dbId}/restore-upload Raw dump as the body. Optional X-Filename header. {detail: "Restore queued."}
GET /databases/{id}/dbs/{dbId}/backup-schedule The schedule
PUT /databases/{id}/dbs/{dbId}/backup-schedule {enabled?, frequency?, hour?, minute?, weekday?, scope?, keepCount?} The schedule

Backup fields: id, databaseId, fileName, sizeBytes, scope, status, trigger, errorMessage, startedAt, completedAt, createdAt. Schedule defaults: disabled, daily at 02:00, full, keep 7. frequency is hourly, daily or weekly. A backup is only served under the database and instance it belongs to.

The same model as PostgreSQL, under /mongo. Every route needs a superuser. Responses are camelCase, and instances carry engine: "mongodb".

Method Path Body Returns
GET /mongo/ {results}: instances
POST /mongo/ {version, displayName, port?}. version is a string: "8.0", "7.0" or "6.0". The instance
GET /mongo/{id} The instance
POST /mongo/{id}/start The instance
POST /mongo/{id}/stop The instance
POST /mongo/{id}/set-default The instance
POST /mongo/{id}/retry The instance. Retries a failed install.
POST /mongo/{id}/expose {isPublic, domain?} The instance
DELETE /mongo/{id} {detail}
GET /mongo/{id}/metrics Live metrics
GET /mongo/{id}/config Tunable mongod settings
PUT /mongo/{id}/config {settings: {name: "value", …}} The instance
GET /mongo/{id}/dbs {results} without connection info
POST /mongo/{id}/dbs {dbName, userName, password?, roles?}. roles is a list of built-in roles such as ["readWrite", "dbAdmin"]. The database with connection
GET /mongo/{id}/dbs/{dbId} The database with connection
PUT /mongo/{id}/dbs/{dbId}/roles {roles: [...]}. [] strips every role. The database
DELETE /mongo/{id}/dbs/{dbId} {detail}. Drops the database and its user.
GET /mongo/{id}/dbs/{dbId}/backups {results}
POST /mongo/{id}/dbs/{dbId}/backups {scope?} The backup
GET /mongo/{id}/dbs/{dbId}/backups/{backupId}/download The backup file
DELETE /mongo/{id}/dbs/{dbId}/backups/{backupId} {detail}
POST /mongo/{id}/dbs/{dbId}/restore {backupId} {detail}
POST /mongo/{id}/dbs/{dbId}/restore-upload Raw dump as the body. Optional X-Filename header. {detail}
GET /mongo/{id}/dbs/{dbId}/backup-schedule The schedule
PUT /mongo/{id}/dbs/{dbId}/backup-schedule Same fields as PostgreSQL The schedule

connection is {host, port, database, username, password, authSource, url}, with a mongodb://…?authSource=<db> URL, plus publicHost and publicUrl when the instance is exposed.

Responses are camelCase.

Method Path Body Returns
GET /storage/providers {results}
POST /storage/providers/garage {displayName, port?, publicUrl?}. port is the S3 API port (default 3900). Garage also uses port+1 and port+2. The provider. Only one local server can be installed.
POST /storage/providers/external {displayName, endpoint, accessKey, secretKey, region?, publicUrl?, forcePathStyle?}. region defaults to us-east-1, forcePathStyle to true. The provider
GET /storage/providers/{id} The provider
POST /storage/providers/{id}/start The provider (local servers only)
POST /storage/providers/{id}/stop The provider (local servers only)
POST /storage/providers/{id}/expose {publicUrl?, consoleUrl?, issueCert?}. An empty publicUrl clears it. issueCert defaults to true. The provider. Writes an Nginx vhost and, for https URLs, a certificate.
DELETE /storage/providers/{id} {detail: "Provider removal queued."}
GET /storage/providers/{id}/buckets {results} without credentials
POST /storage/providers/{id}/buckets {bucketName, isPublic?} (≤ 63 characters) The bucket with connection
GET /storage/providers/{id}/buckets/{bid} The bucket with connection
DELETE /storage/providers/{id}/buckets/{bid} {detail: "Bucket deletion queued."}

Provider fields: id, kind (garage, external, or minio for older installs), displayName, endpoint, region, publicUrl, consoleUrl, forcePathStyle, consolePort, status, errorMessage, installedAt, createdAt, updatedAt. A bucket’s connection is {endpoint, region, bucket, accessKey, secretKey, publicUrl, forcePathStyle}.

Linking buckets to apps is on the App resources API.