Skip to main content

Managed databases API endpoints

These endpoints manage Cloider managed databases: PostgreSQL, MySQL, MongoDB and Redis. You create a database, read its connection details and password, change who can connect, turn SSL on, resize it, list and restore backups, pause and resume it, run queries with exec, and delete it.

All paths are relative to https://cloider.com/api. See Authentication for the token header.

At a glance​

MethodPathAccess
GET/databasesRead
POST/databasesWrite
GET/databases/:hashed_idRead
GET/databases/:hashed_id/statusRead
GET/database/password?id=Read
GET/database/cert?id=Read
PUT/databases/:hashed_id/trusted-sourcesWrite
PUT/databases/:hashed_id/sslWrite
PUT/databases/:hashed_id/planWrite
PUT/databases/:hashed_id/labelWrite
GET/database/backups?id=Read
GET/databases/:hashed_id/pitr-windowRead
POST/databases/:hashed_id/restoreWrite
POST/databases/:hashed_id/pauseWrite
POST/databases/:hashed_id/resumeWrite
DELETE/databases/:hashed_idWrite
GET/databases/:hashed_id/insightsRead
POST/databases/:hashed_id/execWrite
GET/databases/:hashed_id/terminalWrite
POST/databases/:hashed_id/terminal/wakeWrite
POST/databases/:hashed_id/terminal/heartbeatWrite

Note the three endpoints under /database/ (singular): they take the database id in the id query parameter instead of the path.

The database object​

{
"hashed_id": "d7f2m",
"database_name": "orders-db",
"database_label": "orders-db",
"database_user": "orders",
"service": "PostgreSQL",
"database_version": "18",
"status": "Ready",
"ssl": true,
"database_plan": "Standard",
"trusted_sources": [
{"name": "api", "code": "a8q2w", "type": "App"},
{"name": "203.0.113.0/24", "code": "203.0.113.0/24", "type": "Custom"}
],
"created_at": "2026-10-03T12:44:09.210571Z"
}
FieldTypeDescription
hashed_idstringThe database's id
database_namestringThe name you gave it. It is also the name of the database inside the engine, and part of the host name
database_labelstringA name unique among the account's databases. Starts as the name, -1, -2 appended when taken, and can be changed
database_userstringThe user the application connects as
servicestringThe engine: PostgreSQL, MySQL, MongoDB or Redis
database_versionstringThe engine's major version
statusstringCreating, Starting, Ready, Pausing, Paused, Upgrading, Terminating, Terminated or Failed
sslbooleanWhether connections must use TLS
database_planstringThe plan, which sets CPU, memory and storage
trusted_sourcesobject listWho can connect. See Replace the trusted sources
created_atstringWhen the database was created

GET /databases/:hashed_id adds three connection fields: database_port, host and private_host.

List databases​

GET /databases

Returns the account's databases, newest first, without deleted ones. The list doesn't include the port or host names; get a single database for those.

Access: any token.

curl https://cloider.com/api/databases \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
[
{
"hashed_id": "d7f2m",
"database_name": "orders-db",
"database_label": "orders-db",
"database_user": "orders",
"service": "PostgreSQL",
"database_version": "18",
"status": "Ready",
"ssl": true,
"database_plan": "Standard",
"trusted_sources": [{"name": "Allow Everything", "code": "*", "type": "Anywhere"}],
"created_at": "2026-10-03T12:44:09.210571Z"
},
{
"hashed_id": "c4r8n",
"database_name": "cache",
"database_label": "cache",
"database_user": "app",
"service": "Redis",
"database_version": "8",
"status": "Paused",
"ssl": false,
"database_plan": "Hobby",
"trusted_sources": [{"name": "api", "code": "a8q2w", "type": "App"}],
"created_at": "2026-09-28T07:15:51.044902Z"
}
]

Create a database​

POST /databases

Creates a database and starts provisioning it. The request returns at once with the new id; the database then goes through Creating and Starting to Ready. Poll its status until it is Ready.

Access: Read & Write token.

Request body​

FieldTypeRequiredDescription
database_namestringYes2 to 64 characters: lower case letters, digits and -, starting with a letter and not ending with -. Reserved: mysql, information_schema, performance_schema, sys, postgres, template0, template1, admin, local, config
database_userstringYes2 to 64 characters: lower case letters, digits and _, starting with a letter and not ending with _. Reserved: root, mysql, postgres, admin
servicestringYesPostgreSQL, MySQL, MongoDB or Redis
database_versionstringYesA version of that engine from GET /options, today 18 for PostgreSQL, 9 for MySQL, 8 for MongoDB and Redis
database_planstringYesA plan name from GET /options database_plans, for example Hobby or Standard. See pricing
trusted_sourcesobject listNoWho can connect, in the format described below. Leave it empty and nobody can connect over the network until you add a source
sslbooleanNotrue to require TLS. Default false
curl -X POST https://cloider.com/api/databases \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"database_name": "orders-db",
"database_user": "orders",
"service": "PostgreSQL",
"database_version": "18",
"database_plan": "Standard",
"ssl": true,
"trusted_sources": [{"name": "Allow Everything", "code": "*", "type": "Anywhere"}]
}'
Response
{"hashed_id": "d7f2m"}

The password is generated by Cloider. Read it with GET /database/password once the database is Ready.

Errors​

StatusFieldMessage
400database_nameDatabase name must not be empty, Database name can not be upper case, Database name can not start with numbers, Database name must not have special characters except "-", Database name must be at least 2 characters, Database name must not exceed 64 characters, Database name is reserved
400database_userDatabase username must not be empty, Database username must not have special characters except "_", Database username is reserved, Database username must not exceed 64 characters
400database_versiondatabase engine must be selected!, Invalid database type!, Invalid database version!, This database engine isn't available at the moment!
400_Invalid database plan
400_Free plan users can not create more than one database. UPGRADE NOW!
400_Your account is suspended. Upgrade to a paid plan to continue using our services.
400_You have read-only access to this account, you can not create databases! (a Restricted member)
403_This API token is read only!

Get a database​

GET /databases/:hashed_id

Returns one database with everything you need to connect: the public host, the private host and the port.

Access: any token.

curl https://cloider.com/api/databases/d7f2m \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"hashed_id": "d7f2m",
"database_name": "orders-db",
"database_label": "orders-db",
"database_user": "orders",
"service": "PostgreSQL",
"database_version": "18",
"status": "Ready",
"database_plan": "Standard",
"trusted_sources": [{"name": "Allow Everything", "code": "*", "type": "Anywhere"}],
"created_at": "2026-10-03T12:44:09.210571Z",
"database_port": "20417",
"ssl": true,
"host": "orders-db-d7f2m.db.cloider.com",
"private_host": "orders-db-d7f2m.db.cloider.internal"
}
FieldDescription
hostThe public host name, <name>-<id>.db.cloider.com. Reachable from the internet, for sources in trusted_sources
private_hostThe private host name, <name>-<id>.db.cloider.internal, for apps and Kubernetes clusters in the same account
database_portThe port, as a string. Each database has its own port, so read it from here rather than assuming the engine's default

Put the parts together into a connection URL, for example for PostgreSQL:

DB=$(curl -s https://cloider.com/api/databases/d7f2m -H "Authorization: Bearer $CLOIDER_TOKEN")
PASSWORD=$(curl -s "https://cloider.com/api/database/password?id=d7f2m" -H "Authorization: Bearer $CLOIDER_TOKEN")

export DATABASE_URL="postgresql://$(jq -r .database_user <<<"$DB"):$PASSWORD@$(jq -r .host <<<"$DB"):$(jq -r .database_port <<<"$DB")/$(jq -r .database_name <<<"$DB")?sslmode=require"
psql "$DATABASE_URL" -c "select version()"

Connect to a database explains public and private endpoints for every engine.

Get a database's status​

GET /databases/:hashed_id/status

Returns the status as plain text, for example Ready. Poll it after creating, resuming, resizing, restoring or changing SSL.

Access: any token.

until [ "$(curl -s https://cloider.com/api/databases/d7f2m/status \
-H "Authorization: Bearer $CLOIDER_TOKEN")" = "Ready" ]; do sleep 5; done
AfterThe status goes throughUntil
Create or restoreCreating, StartingReady
ResumeStartingReady
Turn SSL on or offStarting (the database restarts)Ready
ResizeUpgradingReady
PausePausingPaused
DeleteTerminatingTerminated

Get the password​

GET /database/password?id=:hashed_id

Returns the password of the database's user as plain text.

Access: any token, including read only tokens. Treat any token that can call this as a secret.

Query parameterRequiredDescription
idYesThe database's hashed_id
curl "https://cloider.com/api/database/password?id=d7f2m" \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
Xk29fQ7pLm3vT8wZ
StatusBody
404Not Found, no database has that id
403Forbidden, the database belongs to another account
502Failed to fetch database password, the database isn't reachable, for example while it is paused or still being created

These errors are plain text, not JSON.

Get the CA certificate​

GET /database/cert?id=:hashed_id

Returns the certificate authority (CA) certificate, in PEM format, that the database's TLS certificate is signed with. Clients use it to verify the server, for example with PostgreSQL's sslmode=verify-full. Only available when SSL is on.

Access: any token.

curl -s "https://cloider.com/api/database/cert?id=d7f2m" \
-H "Authorization: Bearer $CLOIDER_TOKEN" -o orders-db-ca.pem

psql "postgresql://orders@orders-db-d7f2m.db.cloider.com:20417/orders-db?sslmode=verify-full&sslrootcert=orders-db-ca.pem"
Response
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIQ...
-----END CERTIFICATE-----

404 Not Found when the database doesn't exist or SSL is off, 403 Forbidden for another account's database, 502 Failed to fetch database CA certificate when it can't be read. See SSL/TLS.

Replace the trusted sources​

PUT /databases/:hashed_id/trusted-sources

Replaces the list of sources allowed to connect to the database. Connections from anywhere else are dropped. The new list is applied in the background within moments.

Access: Read & Write token.

FieldTypeRequiredDescription
trusted_sourcesobject listYesThe complete new list. Send every source you want to keep

Each source has three fields:

typecodename
Anywhere*Allow Everything
CustomAn IPv4 CIDR range, for example 203.0.113.0/24, or /32 for one addressThe same CIDR
MyIPYour public address as a /32A label of your choice
AppThe app's hashed_idThe app's name, exactly
ClusterThe cluster's hashed_idThe cluster's name, exactly
curl -X PUT https://cloider.com/api/databases/d7f2m/trusted-sources \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"trusted_sources": [
{"name": "production", "code": "p8w2d", "type": "Cluster"},
{"name": "api", "code": "a8q2w", "type": "App"},
{"name": "203.0.113.0/24", "code": "203.0.113.0/24", "type": "Custom"}
]
}'
Response
{"success": true}

The API stores the list as given and doesn't validate it: an invalid CIDR or a misspelled name is accepted but allows nothing, and an empty list allows nobody. See Trusted sources for how each type is matched.

Turn SSL on or off​

PUT /databases/:hashed_id/ssl

Requires TLS for every connection (true) or allows plain connections (false). Applying it restarts the database: its status goes to Starting and back to Ready, and open connections are dropped.

Access: Read & Write token.

FieldTypeRequiredDescription
sslbooleanYestrue to require TLS, false to turn it off
curl -X PUT https://cloider.com/api/databases/d7f2m/ssl \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"ssl": true}'
Response
{"success": true}

Resize to a larger plan​

PUT /databases/:hashed_id/plan

Moves the database to a larger plan with more CPU, memory and storage. The status goes to Upgrading while the resize is applied, then back to Ready. The database is billed on the new plan only once the resize is done.

Access: Read & Write token. The database must be Ready.

FieldTypeRequiredDescription
database_planstringYesA plan larger than the current one, in the order of GET /options database_plans
curl -X PUT https://cloider.com/api/databases/d7f2m/plan \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"database_plan": "Pro"}'
Response
{"success": true}

Storage can grow but never shrink, so there is no way to move to a smaller plan. To get a smaller database, create one and move the data.

StatusMessage
400The database must be running to be upgraded.
400Invalid database plan
400A database can only be upgraded to a larger plan.
400This plan isn't available at the moment!
400Your account is suspended. Upgrade to a paid plan to continue using our services.
403This API token is read only!

See Resize a database.

Rename a database​

PUT /databases/:hashed_id/label

Changes the database's label, the name shown in the dashboard and used by the CLI. The database_name, and so the host name and the database inside the engine, stays the same.

Access: Read & Write token.

FieldTypeRequiredDescription
database_labelstringYes2 to 64 characters, lower case letters, digits and -, starting with a letter. Unique among the account's databases
curl -X PUT https://cloider.com/api/databases/d7f2m/label \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"database_label": "orders-primary"}'
Response
{"success": true}

Errors are on database_label: the naming rules (Database label can not be upper case and the like) and Database label already exists.

List backups​

GET /database/backups?id=:hashed_id

Returns the backups you can restore by name, newest first, as a list of timestamps in the form YYYY-MM-DD_HH-MM (UTC). Databases are restored from their point-in-time window, so the list is empty, apart from Redis snapshots taken before point-in-time recovery, which are listed until they expire, around mid-November 2026.

Access: any token.

Query parameterRequiredDescription
idYesThe database's hashed_id
curl "https://cloider.com/api/database/backups?id=d7f2m" \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
[]

404 Not Found and 403 Forbidden (plain text) as for the password; 502 Failed to fetch database backups when the list can't be read. See Backups and restore.

Get the point-in-time window​

GET /databases/:hashed_id/pitr-window

Returns the moments a database can be restored to: from earliest, 14 days back or the first full backup if that is more recent, until latest, the time of the request. Before the database's first full backup, the response is {"available": false}.

Access: any token.

curl https://cloider.com/api/databases/d7f2m/pitr-window \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{"available": true, "earliest": "2026-10-13T01:31:07Z", "latest": "2026-10-27T09:12:03Z"}

502 Failed to fetch the point-in-time window when the window can't be read.

Restore a backup​

POST /databases/:hashed_id/restore

Restores a backup into a new database. The source database isn't touched: Cloider creates a copy with the same engine, version, plan, user, trusted sources and SSL setting, seeded from the backup, and labels it <source label>-<moment restored to>. Point your application at the new database when it is Ready.

Access: Read & Write token.

The body takes exactly one of these fields:

FieldTypeDescription
latestbooleantrue restores the newest: the newest full backup plus every change since
target_timestringThe moment to restore to, RFC 3339, inside the point-in-time window, for example 2026-10-25T14:29:00Z
backupstringA Redis snapshot taken before point-in-time recovery, from GET /database/backups, until it expires
curl -X POST https://cloider.com/api/databases/d7f2m/restore \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"latest": true}'
Response
{"hashed_id": "h3k9w", "database_label": "orders-db-2026-10-27-09-12-03"}

Poll GET /databases/h3k9w/status until it is Ready. The restored database is a separate database, billed like any other, so delete it when you don't need it any more. On the Free plan, which allows one database, a restore is refused. A database must be Ready to be restored with latest or target_time.

StatusMessage
400Choose one of the newest backup, a backup or a point in time! (more than one field)
400Invalid backup selected! (no field, or backup not in the YYYY-MM-DD_HH-MM form)
400Invalid point in time, use RFC 3339 like 2026-10-25T14:30:00Z!
400The database must be running to restore it to a point in time!
400Point-in-time recovery isn't available for this database yet. It starts after its first full backup!
400Pick a point in time between 2026-10-13 01:31:07 UTC and now!
400Free plan users can not create more than one database. UPGRADE NOW!
400Your account is suspended. Upgrade to a paid plan to continue using our services.
403This API token is read only!
404Not Found (plain text)
502Couldn't read the point-in-time window, try again later!

Pause a database​

POST /databases/:hashed_id/pause

Stops the database and keeps its data. The status goes to Pausing, then Paused. A paused database is still billed for its storage; see Pause, resume and delete.

Access: Read & Write token.

curl -X POST https://cloider.com/api/databases/d7f2m/pause \
-H "Authorization: Bearer $CLOIDER_TOKEN"

The response is the account's database list, with this database Pausing. The endpoint doesn't check the current status, so pause only a Ready database.

Resume a database​

POST /databases/:hashed_id/resume

Starts a paused database. The status goes to Starting, then Ready, with the same host, port, password and data.

Access: Read & Write token.

curl -X POST https://cloider.com/api/databases/d7f2m/resume \
-H "Authorization: Bearer $CLOIDER_TOKEN"

The response is the database list, with this database Starting.

Delete a database​

DELETE /databases/:hashed_id

Deletes the database and its data. This can't be undone. Restore a backup into a new database first if you might need the data. The status goes to Terminating, then Terminated, and the database disappears from GET /databases.

Access: Read & Write token.

curl -X DELETE https://cloider.com/api/databases/d7f2m \
-H "Authorization: Bearer $CLOIDER_TOKEN"

The response is the database list, with this database Terminating.

Get insights​

GET /databases/:hashed_id/insights

Returns the database's resource usage: today's averages, this month's statistics and one entry per day for the last 31 days at least. These are the charts of the dashboard's Insights tab.

Access: any token.

curl https://cloider.com/api/databases/d7f2m/insights \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response (trimmed)
{
"date": "2026-10-20",
"month": "October 2026",
"today": {
"cpu": 42.5, "memory": 318.2, "storage": 1.4,
"disk_read": 10240, "disk_write": 52310, "net_rx": 8120, "net_tx": 15403,
"connections": 6.2
},
"connections_max": 100,
"month_stats": {
"cpu": {"avg": 38.1, "max": 410, "max_date": "2026-10-14", "min": 3, "min_date": "2026-10-02"},
"connections": {"avg": 5.8, "max": 31, "max_date": "2026-10-14", "min": 0, "min_date": "2026-10-04"}
},
"daily": [
{
"date": "2026-10-19",
"stats": {
"cpu": {"avg": 40.2, "max": 210, "min": 4},
"memory": {"avg": 312.9, "max": 401.3, "min": 290.1}
}
}
]
}
MetricUnit
cpumillicores (1000 = one core)
memoryMiB
storageGiB used (not the volume size)
disk_read, disk_write, net_rx, net_txbytes per second
connectionsopen connections

today is null before today's first sample, a metric in month_stats is null when there is no data for it yet, and a day without samples has no stats. connections_max is the engine's connection limit. See Insights.

Run a query with exec​

POST /databases/:hashed_id/exec

Runs one query or command with the engine's own client inside the database's environment, connected as the database user, and streams back the output and exit code. The client is psql for PostgreSQL, mysql for MySQL, mongosh for MongoDB and redis-cli for Redis. cloider db exec uses this endpoint.

Access: Read & Write token. The database must be Ready.

FieldTypeRequiredDescription
commandstring listOne of the twoThe query. For PostgreSQL, MySQL and MongoDB the items are joined with spaces and run as one statement (psql -c, mysql -e, mongosh --eval). For Redis they are the command and its arguments, for example ["GET", "greeting"]
stdinstring (base64)One of the twoA script to run, base64 encoded, up to 2 MiB. With no command, the client reads its statements from it
timeoutintegerNoSeconds before the command is stopped. Default 600, at most 3600
curl -N -X POST https://cloider.com/api/databases/d7f2m/exec \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command": ["SELECT count(*) FROM orders"]}'
Response
: open

event: stdout
data: IGNvdW50IAotLS0tLS0tCiAgMTI4NAooMSByb3cpCgo=

event: exit
data: 0

event: end
data: 1

Run a migration file:

curl -N -X POST https://cloider.com/api/databases/d7f2m/exec \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg stdin "$(base64 < migration.sql)" '{stdin: $stdin}')"

The response is the same event stream as cluster exec: base64 stdout and stderr chunks, then exit, timeout or error, then end. PostgreSQL runs with ON_ERROR_STOP, so a failing statement ends the script with a non zero exit code.

StatusFieldMessage
400commandGive a query to run, or a script on stdin!, The command can't contain NUL bytes!, The command is longer than 64 KiB!
400stdinstdin is bigger than 2 MiB!
400timeoutThe timeout can be an hour at most!
403_This API token is read only!
404_Database not found!
409_This database is paused. Resume it to run a command!, This database is being deleted!, This database is not ready yet!, This database isn't running right now!
503_The command could not be started, try again in a moment!

Web terminal endpoints​

The dashboard's Terminal tab opens the engine's interactive client in the browser. Three endpoints drive it. For scripts, exec is simpler.

EndpointWhat it doesResponse
GET /databases/:hashed_id/terminalReturns the terminal's URL{"url": "https://cloider.com/terminal?kind=database&..."}
POST /databases/:hashed_id/terminal/wakeStarts the terminal, which sleeps when unused, and answers once it accepts connections200
POST /databases/:hashed_id/terminal/heartbeatTells Cloider the terminal is still in use so it isn't put to sleep204

All three need a Read & Write token (403 Terminals need a Read & Write API token! for the URL with a read only token) and a Ready database; otherwise they answer 409 with the same messages as exec. Wake answers 503 The terminal could not be started, try again in a moment! when it can't start the terminal. With an API token, the URL carries a terminal token that is valid for 2 minutes. See Terminal and exec.