Databases through the API

Use these routes to operate an existing database project (PostgreSQL, MariaDB, or ClickHouse). To create the database, see Create, list, and delete projects. Valkey services (Key-Value, Cache, and Queue) use the Managed services routes.

Authentication and permissions

All routes accept an organization API Key (x-api-key: znf_... or Authorization: Bearer znf_...) or a user token with x-organization-id. Permissions use the database:<project-id> resource:

RouteScope
GET /v1/project/:id/database/statusdatabase.status.read
GET /v1/project/:id/database/connectiondatabase.connection.read
GET /v1/project/:id/database/linked-applicationsdatabase.password.rotate
PATCH /v1/project/:id/database/passworddatabase.password.rotate
PATCH /v1/project/:id/database/versiondatabase.version.update

owner has full access. assistant, member, and API Keys need the scope on the database ID or on database:*. Without it, the response is 403 with insufficient organization permission.

Read the state

GET /v1/project/:id/database/status
{
  "status": "success",
  "message": "got database status successfully",
  "data": {
    "project_id": "6650f1a2b3c4d5e6f7a8b9c1",
    "name": "orders-db",
    "plan": "db-basic",
    "status": "<current-state>"
  }
}

status is informational text with the current database state; when the detailed state is unavailable, the API returns the project status. Use it for display and diagnosis, not as a fixed value in automations. The response can also include an object with engine-specific details; do not rely on those details. For the project lifecycle, use GET /v1/project/:id (Project information).

If the project does not exist in the organization or is not a database, the response is 404 with database project not found.

Limit: 50 requests per minute.

Read the connection

GET /v1/project/:id/database/connection
{
  "status": "success",
  "message": "got database connection successfully",
  "data": {
    "host": "<host>",
    "port": 5432,
    "database": "<database>",
    "username": "<username>",
    "connectionStringRO": "postgresql://<username>:********@<read-host>:5432/<database>",
    "connectionString": "postgresql://<username>:********@<host>:5432/<database>"
  }
}

This route never returns the password: connection strings come with the password masked as ********. connectionStringRO only appears when the database has a read-only endpoint (for example, PostgreSQL with 2 or more instances). ClickHouse databases also return httpsPort. If you lost the password, renew it with the route below. A project that does not exist or is not a database returns 404 with database project not found.

Limit: 50 requests per minute.

List linked applications

GET /v1/project/:id/database/linked-applications

Lists the applications created together with this database from a template and the names of the environment variables that received the connection. Check it before renewing the password to know which applications will need new credentials. Only applications the credential can read (project.read) are listed. A project that does not exist returns 404; a project that is not a database returns 400.

{
  "status": "success",
  "data": {
    "linked_applications": [
      { "project_id": "6650f1a2b3c4d5e6f7a8b9c0", "variable_names": ["DATABASE_URL"] }
    ]
  }
}

Avoid repeated calls: the password renewal response also includes this list.

Renew the password

PATCH /v1/project/:id/database/password

Generates a new random password for the database. Send an empty body ({}). The previous password stops working; update the applications that use the database.

{
  "status": "success",
  "message": "database credentials updated with success",
  "data": {
    "password": "<new-password>",
    "linked_applications": [
      { "project_id": "6650f1a2b3c4d5e6f7a8b9c0", "variable_names": ["DATABASE_URL"] }
    ]
  }
}

The new password only appears in this response. Store it securely before discarding the response.

CodeSituation
400The project is not a database (project is not a database)
404Project not found
409A renewal is already in progress (DATABASE_CREDENTIAL_ROTATION_IN_PROGRESS)
503The renewal could not be completed (DATABASE_CREDENTIAL_ROTATION_FAILED); try again

Limit: 5 requests per minute.

Update the version

PATCH /v1/project/:id/database/version
FieldTypeRequiredDescription
versionstringYesPostgreSQL: 15, 16, 17, or 18. MariaDB: 10 or 11. ClickHouse has a single available version (26.8.6.5)
{
  "version": "18"
}
{
  "status": "success",
  "message": "mariadb version updated with success"
}

The success message is the same for every engine. Back up and validate application compatibility before changing versions.

CodeSituation
400Missing version, version not supported by the engine, or project that is not a database
404Project not found
500Failure applying the new version

Limit: 5 requests per minute.

Examples

curl "https://api.zenifra.com/v1/project/6650f1a2b3c4d5e6f7a8b9c1/database/connection" \
  -H "x-api-key: znf_..."

curl -X PATCH "https://api.zenifra.com/v1/project/6650f1a2b3c4d5e6f7a8b9c1/database/password" \
  -H "x-api-key: znf_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Next steps

Last updated on

On this page