Managed services API
These routes let you inspect the Valkey catalog and operate an existing managed project. Creation still uses the public project route with config.type_project: "valkey", config.profile, and the matching plan.
Authentication and permissions
Send a session token with the organization context:
Authorization: Bearer <token>
x-organization-id: <organization-id>For automation, use an organization API Key (x-api-key: znf_... or Authorization: Bearer znf_...); in that case x-organization-id is not needed, because the organization comes from the key itself. The public catalog does not require these headers.
With a session token, the organization header selects the billing and authorization context when a user belongs to more than one organization. Keep the API key in a secret manager, never in a versioned file. For reads, treat 404 as an inaccessible or missing project without guessing IDs. For rotation, show the response only to the authorized operator, update the application secret, and discard the password from memory as soon as clients restart.
Project operations require the matching permissions for the managed_service resource. To create Key-Value, Cache, or Queue through the project route, grant managed_service.create on organization:*; to operate a specific service, use its project ID:
| Operation | Permission |
|---|---|
| Create Key-Value, Cache, or Queue | managed_service.create on organization:* |
| Read status | managed_service.status.read on managed_service:<project-id> |
| Read masked connection | managed_service.connection.read on managed_service:<project-id> |
| Rotate credentials | managed_service.credentials.rotate on managed_service:<project-id> |
An owner has full access in a user session. assistant, member, and organization API Keys need the specific grant. The scopes managed_service.read, managed_service.version.update, managed_service.metrics.read, managed_service.lifecycle.update, and managed_service.delete are in the catalog but do not currently have an organization API Key route exposed.
Catalog
GET /v1/managed-services/catalogAuthentication is not required. The catalog reports the Valkey version, currency, profiles, plans, hourly/monthly/yearly prices, benefits, included storage, and public high-availability availability.
{
"status": "success",
"data": {
"engine": "valkey",
"version": "9.1.1",
"currency": "brl",
"profiles": [
{ "id": "key_value", "persistence": true },
{ "id": "cache", "persistence": false },
{ "id": "queue", "persistence": true }
],
"plans": [
{
"id": "queue-basic",
"profile": "queue",
"prices": { "hourly": 13, "monthly": 7490, "yearly": 74990 },
"features": ["1 vCPU", "1 GiB de RAM", "Alta disponibilidade com uma primária e duas réplicas"],
"included_storage_gb": 5,
"high_availability": { "key_value": true, "cache": false, "queue": true }
}
]
}
}Reduced example. high_availability shows, per profile, whether the plan has high availability. Values are BRL cents. Read the catalog at execution time; do not hardcode prices in automations.
Read status
GET /v1/managed-services/:id/statusReduced response:
{
"status": "success",
"data": {
"id": "<project-id>",
"status": "running",
"engine": "valkey",
"profile": "queue",
"version": "9.1.1",
"persistence": true,
"instances": 3
}
}Read the connection
GET /v1/managed-services/:id/connectionThe password cannot be recovered through this route:
{
"status": "success",
"data": {
"host": "valkey-<project-id>.managed.zenifra.com",
"port": "<port>",
"username": "default",
"tls": true,
"connection_string": "valkeys://default:********@valkey-<project-id>.managed.zenifra.com:<port>/0"
}
}Rotate the credential
Rotation is asynchronous and idempotent. First request the rotation; then follow the operation until it completes, when the new connection is returned.
1. Request the rotation
PATCH /v1/managed-services/:id/credentials
Idempotency-Key: <unique-key-of-16-to-200-characters>The Idempotency-Key header is required and accepts 16 to 200 characters (A-Z, a-z, 0-9, ., _, and -). The API responds 202:
{
"status": "accepted",
"data": {
"operation_id": "<operation-id>",
"state": "accepted"
}
}2. Follow the operation
GET /v1/managed-services/:id/credential-rotations/:operationIdPoll at bounded intervals until state reaches a final state. While the rotation has not finished, the response contains only operation_id, state, and credential_version. When the rotation completes (state: completed), the response includes the new connection, with the password, and you must update the application secret before discarding the previous value:
{
"status": "success",
"data": {
"operation_id": "<operation-id>",
"state": "completed",
"credential_version": 2,
"username": "default",
"host": "valkey-<project-id>.managed.zenifra.com",
"port": "<port>",
"tls": true,
"connection_string": "valkeys://default:<new-password>@valkey-<project-id>.managed.zenifra.com:<port>/0"
}
}Show the response only to the authorized operator. If the query does not yet include the connection, repeat the call.
Common errors
| Code | Situation |
|---|---|
400 | Invalid or missing ID, parameters, or Idempotency-Key |
401 | Missing or invalid session/API Key |
403 | Insufficient organization permission (managed service access denied) |
404 | Managed project or rotation operation not found |
409 | A rotation is already in progress, or the service is being deleted |
503 | Commercial catalog or managed service operations temporarily unavailable |
Rate limits (counted per source IP): catalog 60 per minute; status 60 per minute; connection 30 per minute; rotation request 5 every 5 minutes; rotation query 60 per minute.
Next steps
Last updated on
Databases through the API
Read the state and connection of PostgreSQL, MariaDB, and ClickHouse databases, renew the password, update the version, and list linked applications.
Metrics and Logs
Retrieve native and resource metrics, availability states, and project logs through Zenifra's stable API endpoints.