PostgreSQL¶
Server-level PostgreSQL management when the plugin is enabled.
All endpoints below are mounted under /api. Authentication: Authorization: Bearer <token> unless noted as public.
Endpoint count: 16
Endpoints¶
| Method | Path | Handler | Guards |
|---|---|---|---|
POST |
/api/postgresql/backup |
postgreSQLBackup |
RequirePermission(db, "administrative_operations") |
GET |
/api/postgresql/backups |
postgreSQLListBackups |
RequirePermission(db, "administrative_operations") |
DELETE |
/api/postgresql/backups/:name |
postgreSQLDeleteBackup |
RequirePermission(db, "administrative_operations") |
GET |
/api/postgresql/pgadmin |
getPgAdminStatus |
RequirePermission(db, "administrative_operations") |
GET |
/api/postgresql/pgadmin/credentials |
getPgAdminCredentials |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/pgadmin/install |
installPgAdmin |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/pgadmin/uninstall |
uninstallPgAdmin |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/pgadmin/update |
updatePgAdmin |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/restart |
postgreSQLRestart |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/restore |
postgreSQLRestore |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/start |
postgreSQLStart |
RequirePermission(db, "administrative_operations") |
GET |
/api/postgresql/status |
getPostgreSQLStatus |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/stop |
postgreSQLStop |
RequirePermission(db, "administrative_operations") |
GET |
/api/postgresql/users |
postgreSQLListUsers |
RequirePermission(db, "administrative_operations") |
POST |
/api/postgresql/users |
postgreSQLCreateUser |
RequirePermission(db, "administrative_operations") |
DELETE |
/api/postgresql/users/:username |
postgreSQLDeleteUser |
RequirePermission(db, "administrative_operations") |
Source¶
Handlers for this section live in api/routes/handlers_*.go in the StarkOne source. Each handler binds its request body with gin.ShouldBindJSON(&req) and responds with the standard envelope:
On error:
Reference¶
POST /api/postgresql/backup¶
Creates a full SQL dump of all PostgreSQL roles and databases via pg_dumpall and writes it to /var/backups/postgresql.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
backup_error |
pg_dumpall failed; message includes the command error and output. |
Side effects
- Creates the directory
/var/backups/postgresql(mode 0755) if missing andchowns it topostgres:postgres. - Runs
sudo -u postgres pg_dumpall -f <path>, writing a timestamped filepg-backup-YYYY-MM-DD-HHMMSS.sql.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/backup \
-H "Authorization: Bearer $TOKEN"
GET /api/postgresql/backups¶
Lists the most recent PostgreSQL backup files (up to 10) found in /var/backups/postgresql.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
Returns the envelope. Only files whose name begins with pg-backup- are included, sorted newest-first by name, capped at 10. If the backup directory cannot be read, an empty list is returned with 200.
{
"data": {
"backups": [
{ "name": "pg-backup-2026-06-17-153000.sql", "date": "2026-06-17 15:30", "size": "2.4 MB" }
]
}
}
Example
DELETE /api/postgresql/backups/:name¶
Deletes a single backup file by name from /var/backups/postgresql.
Guards: RequirePermission(db, "administrative_operations")
Path parameters
| Name | Type | Description |
|---|---|---|
name |
string | Backup file name. Rejected if it contains /, \, or ... |
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Name contains a path separator or ... |
404 |
not_found |
Backup file does not exist. |
500 |
delete_error |
Removing the file failed. |
Side effects
- Removes the file at
/var/backups/postgresql/<name>viaos.RemoveAll.
Example
curl -X DELETE https://panel.example.com:2087/api/postgresql/backups/pg-backup-2026-06-17-153000.sql \
-H "Authorization: Bearer $TOKEN"
GET /api/postgresql/pgadmin¶
Reports whether pgAdmin 4 is installed and running, its version, and the panel-relative URL to reach it through the panel's reverse proxy.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
Returns the envelope. installed is true when the venv pip exists; version comes from pip show pgadmin4; running reflects systemctl is-active pgadmin4; url is built from the request scheme/host plus the proxy prefix.
{
"data": {
"installed": true,
"running": true,
"version": "8.5",
"url": "https://panel.example.com:2087/api/postgresql/pgadmin/proxy/"
}
}
Example
GET /api/postgresql/pgadmin/credentials¶
Returns the stored pgAdmin login email and password read from /etc/starkone/.pgadmin.conf.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
Returns the envelope wrapping the persisted credentials struct.
{ "data": { "email": "[email protected]", "password": "..." } }
Errors
| Status | Code | Meaning |
|---|---|---|
404 |
not_installed |
Credentials file not found (pgAdmin not installed). |
500 |
corrupt_config |
Credentials file could not be parsed as JSON. |
Example
curl https://panel.example.com:2087/api/postgresql/pgadmin/credentials \
-H "Authorization: Bearer $TOKEN"
POST /api/postgresql/pgadmin/install¶
Installs pgAdmin 4 into a Python venv at /opt/pgadmin4/venv, generates credentials, writes its config and a systemd unit, and starts the service.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
{ "success": true, "message": "pgAdmin installed", "email": "[email protected]" }
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
prereq_error |
Installing OS prerequisites failed. |
500 |
mkdir_error |
Creating install/data/log/config directories failed. |
500 |
venv_error |
Creating the Python venv failed. |
500 |
pip_upgrade_error |
Upgrading pip/wheel/setuptools failed. |
500 |
pip_install_error |
pip install pgadmin4 failed. |
500 |
creds_error |
Loading or generating credentials failed. |
500 |
config_error |
Writing the pgAdmin config failed. |
500 |
setup_error |
Running pgAdmin's setup (user creation) failed. |
500 |
systemd_error |
Writing the systemd unit failed. |
500 |
service_start_error |
systemctl enable --now pgadmin4 failed. |
Side effects
- Installs OS prerequisites.
- Creates
/opt/pgadmin4,/var/lib/pgadmin,/var/log/pgadmin,/etc/starkone. - Builds a venv and
pip installs pgadmin4. - Writes credentials, config, and
/etc/starkone/pgadmin-servers.json. - Writes
/etc/systemd/system/pgadmin4.service, runssystemctl daemon-reload, thensystemctl enable --now pgadmin4.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/pgadmin/install \
-H "Authorization: Bearer $TOKEN"
POST /api/postgresql/pgadmin/uninstall¶
Stops and removes the pgAdmin service and deletes all pgAdmin install, data, log, and config artifacts (including leftover nginx/apache configs from older versions).
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Side effects
systemctl disable --now pgadmin4and removes/etc/systemd/system/pgadmin4.service, thensystemctl daemon-reload.- Removes stale web-server fragments:
/etc/nginx/conf.d/00-pgadmin.conf,/etc/starkone/.pgadmin_alias,/etc/apache2/conf-available/pgadmin.conf(witha2disconf pgadmin),/etc/httpd/conf.d/pgadmin.conf, thensystemctl reload nginx. - Deletes
/opt/pgadmin4,/var/lib/pgadmin,/var/log/pgadmin, the credentials file, and the servers JSON.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/pgadmin/uninstall \
-H "Authorization: Bearer $TOKEN"
POST /api/postgresql/pgadmin/update¶
Upgrades the installed pgAdmin 4 package via pip and restarts the service, reporting the old and new versions.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
not_installed |
The venv pip does not exist (pgAdmin not installed). |
500 |
pip_update_error |
pip install --upgrade pgadmin4 failed. |
Side effects
- Runs
pip install --upgrade pgadmin4in the venv. - Runs
systemctl restart pgadmin4.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/pgadmin/update \
-H "Authorization: Bearer $TOKEN"
POST /api/postgresql/restart¶
Restarts the PostgreSQL system service.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
restart_error |
systemctl restart of the PostgreSQL service failed. |
Side effects
- Runs
systemctl restart <pg-service>(service name resolved at runtime).
Example
curl -X POST https://panel.example.com:2087/api/postgresql/restart \
-H "Authorization: Bearer $TOKEN"
POST /api/postgresql/restore¶
Restores a previously created backup by feeding its SQL dump into psql, recreating roles and databases.
Guards: RequirePermission(db, "administrative_operations")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
backup |
string | yes | Backup file name in /var/backups/postgresql. Rejected if it contains /, \, or ... |
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Body failed to bind, or the backup name contains a path separator or ... |
404 |
not_found |
The named backup file does not exist. |
500 |
restore_error |
psql -f <path> failed; message includes the error and output. |
Side effects
- Runs
sudo -u postgres psql -f <backupPath> postgres, which recreates roles and databases from the dump.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/restore \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"backup": "pg-backup-2026-06-17-153000.sql"}'
POST /api/postgresql/start¶
Starts the PostgreSQL system service.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
start_error |
systemctl start of the PostgreSQL service failed. |
Side effects
- Runs
systemctl start <pg-service>.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/start \
-H "Authorization: Bearer $TOKEN"
GET /api/postgresql/status¶
Returns PostgreSQL runtime status: running state, version, uptime, connection count, memory usage, and total data size.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
Returns the envelope. version comes from psql --version (available even when stopped). When running, connections, uptime, and data_size are queried live; memory_mb is read from systemctl show ... MemoryCurrent. If the SQL data-size query fails, data_size falls back to du -sh of the data directory.
{
"data": {
"running": true,
"version": "15.4",
"uptime": "12h 5m",
"connections": 7,
"memory_mb": 128,
"data_size": "2.4 GB"
}
}
Example
POST /api/postgresql/stop¶
Stops the PostgreSQL system service.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
stop_error |
systemctl stop of the PostgreSQL service failed. |
Side effects
- Runs
systemctl stop <pg-service>.
Example
GET /api/postgresql/users¶
Lists PostgreSQL roles (excluding internal pg_* roles) with their role attributes.
Guards: RequirePermission(db, "administrative_operations")
Response - 200 OK
Returns the envelope. Each entry's roles is built from the role flags (SUPERUSER, CREATEDB, CREATEROLE, LOGIN). The db field is always an empty string. If the query fails, an empty list is returned with 200.
Example
POST /api/postgresql/users¶
Creates a PostgreSQL role with the requested privilege level and, optionally, creates a database owned by it or grants it privileges on an existing database.
Guards: RequirePermission(db, "administrative_operations")
Request body
{
"username": "string (required)",
"password": "string (required)",
"database": "string (optional)",
"role": "string (optional)"
}
| Field | Type | Required | Description |
|---|---|---|---|
username |
string | yes | Role name. Must be letters, digits, or underscore, max 63 chars. |
password |
string | yes | Role login password. |
database |
string | no | If set, a database to create (owned by the user) or grant privileges on. Must pass the same name validation. |
role |
string | no | Privilege level. One of superuser, createdb, readonly, login, readwrite. Defaults to login. |
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Body failed to bind, or the username/database failed name validation. |
500 |
create_error |
Creating the role failed, or the user was created but the database create/grant failed. |
Side effects
- Runs
CREATE ROLE <username> WITH <attrs> PASSWORD <pw>. Role attributes depend onrole:superuser->LOGIN SUPERUSER CREATEDB CREATEROLE;createdb->LOGIN CREATEDB; others ->LOGIN. - If
databaseis set and does not exist:CREATE DATABASE <db> OWNER <username>. - If
databaseexists: grantsCONNECT(whenroleisreadonly) orALL PRIVILEGESto the user.
Example
curl -X POST https://panel.example.com:2087/api/postgresql/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "user1", "password": "s3cret", "database": "appdb", "role": "createdb"}'
DELETE /api/postgresql/users/:username¶
Drops a PostgreSQL role after reassigning and dropping the objects it owns.
Guards: RequirePermission(db, "administrative_operations")
Path parameters
| Name | Type | Description |
|---|---|---|
username |
string | Role name to drop. Must be letters, digits, or underscore, max 63 chars. |
Response - 200 OK
This handler returns a flat (non-enveloped) body:
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Username failed name validation. |
500 |
delete_error |
The DROP ROLE statement failed. |
Side effects
- Runs
REASSIGN OWNED BY <username> TO postgres, thenDROP OWNED BY <username>, thenDROP ROLE IF EXISTS <username>.
Example