API de serviços gerenciados

Estas rotas permitem consultar o catálogo Valkey e operar um projeto gerenciado existente. A criação continua sendo feita pela rota pública de projetos com config.type_project: "valkey", config.profile e o plano correspondente.

Autenticação e permissões

Envie um token de sessão com o contexto da organização:

Authorization: Bearer <token>
x-organization-id: <organization-id>

Para automações, use uma API Key da organização (x-api-key: znf_... ou Authorization: Bearer znf_...); nesse caso, x-organization-id é dispensável, porque a organização vem da própria chave. O catálogo público não exige esses cabeçalhos.

Com token de sessão, o cabeçalho de organização seleciona o contexto de cobrança e autorização quando o usuário participa de mais de uma organização. A API Key deve permanecer em um secret manager, nunca em um arquivo versionado. Para leituras, trate 404 como projeto inacessível ou inexistente sem tentar adivinhar IDs. Para rotação, mostre a resposta somente ao operador autorizado, atualize o secret da aplicação e descarte a senha da memória assim que os clientes forem reiniciados.

As operações do projeto exigem as permissões correspondentes ao recurso managed_service. Para criar Key-Value, Cache ou Queue pela rota de projetos, conceda managed_service.create em organization:*; para operar um serviço específico, use o ID do projeto:

OperaçãoPermissão
Criar Key-Value, Cache ou Queuemanaged_service.create em organization:*
Consultar estadomanaged_service.status.read em managed_service:<project-id>
Consultar conexão mascaradamanaged_service.connection.read em managed_service:<project-id>
Rotacionar credencial e listar aplicações vinculadasmanaged_service.credentials.rotate em managed_service:<project-id>
Ligar ou desligar o acesso públicomanaged_service.exposure.update em managed_service:<project-id>

owner tem acesso completo na sessão de usuário. assistant, member e API Keys da organização precisam do grant específico. Os scopes managed_service.read, managed_service.version.update, managed_service.metrics.read, managed_service.lifecycle.update e managed_service.delete estão no catálogo, mas não possuem rota de API Key exposta atualmente.

GET /v1/managed-services/catalog

Não exige autenticação. O catálogo informa a versão do Valkey, moeda, modos de acesso público (exposure_modes), perfis, planos, preços por hora/mês/ano, benefícios, armazenamento incluído e disponibilidade pública de alta disponibilidade.

{
  "status": "success",
  "data": {
    "engine": "valkey",
    "version": "9.1.1",
    "currency": "brl",
    "exposure_modes": ["public", "private"],
    "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 }
      }
    ]
  }
}

Exemplo reduzido. high_availability indica, por perfil, se o plano tem alta disponibilidade. Os valores são centavos de BRL. Consulte o catálogo no momento da execução; não fixe preços em automações.

Consultar o estado

GET /v1/managed-services/:id/status

Resposta reduzida:

{
  "status": "success",
  "data": {
    "id": "<project-id>",
    "status": "running",
    "engine": "valkey",
    "profile": "queue",
    "version": "9.1.1",
    "persistence": true,
    "instances": 3,
    "exposure": "public"
  }
}

Consultar a conexão

GET /v1/managed-services/:id/connection

A senha nunca é recuperada por esta rota:

{
  "status": "success",
  "data": {
    "host": "valkey-<project-id>.managed.zenifra.com",
    "port": "<porta>",
    "username": "default",
    "tls": true,
    "connection_string": "valkeys://default:********@valkey-<project-id>.managed.zenifra.com:<porta>/0",
    "exposure": "public"
  }
}

exposure indica se o host e a porta públicos aceitam conexões (public) ou se o serviço só é alcançado pelas conexões privadas (private). O mesmo campo aparece em GET /v1/managed-services/:id/status. Host, porta e usuário continuam os mesmos nos dois estados.

Listar aplicações vinculadas

GET /v1/managed-services/:id/linked-applications

Lista as aplicações que usam o serviço e os nomes das variáveis de ambiente que receberam a conexão. Consulte antes de rotacionar a credencial para saber quais aplicações precisarão do novo segredo. O campo via indica a origem do vínculo: template (criada junto em um template) ou connection (conexão interna). Só aparecem aplicações que a credencial pode ler; aplicações excluídas não aparecem. Exige managed_service.credentials.rotate no serviço.

{
  "status": "success",
  "data": {
    "linked_applications": [
      { "project_id": "6650f1a2b3c4d5e6f7a8b9c0", "variable_names": ["VALKEY_URL"], "via": ["connection"] }
    ]
  }
}

Rotacionar a credencial

A rotação é assíncrona e idempotente. Primeiro solicite a rotação; depois acompanhe a operação até a conclusão, quando a nova conexão é devolvida.

1. Solicitar a rotação

PATCH /v1/managed-services/:id/credentials
Idempotency-Key: <chave-unica-de-16-a-200-caracteres>

O cabeçalho Idempotency-Key é obrigatório e aceita de 16 a 200 caracteres (A-Z, a-z, 0-9, ., _ e -). O serviço precisa estar em running, sem outra operação em andamento. A API responde 202:

{
  "status": "accepted",
  "data": {
    "operation_id": "<operation-id>",
    "state": "accepted"
  }
}

Repetir a solicitação com a mesma Idempotency-Key não inicia outra rotação: a API responde 202 com a mesma operação, no estado em que ela estiver.

2. Acompanhar a operação

GET /v1/managed-services/:id/credential-rotations/:operationId

Consulte em intervalos limitados até state chegar a um estado final. Enquanto a rotação não termina, a resposta traz apenas operation_id, state e credential_version. Quando a rotação é concluída (state: completed), a resposta inclui a nova conexão, com a senha, e você deve atualizar o secret da aplicação antes de descartar o valor anterior:

{
  "status": "success",
  "data": {
    "operation_id": "<operation-id>",
    "state": "completed",
    "credential_version": 2,
    "username": "default",
    "host": "valkey-<project-id>.managed.zenifra.com",
    "port": "<porta>",
    "tls": true,
    "connection_string": "valkeys://default:<nova-senha>@valkey-<project-id>.managed.zenifra.com:<porta>/0"
  }
}

Os estados são accepted, running, completed e failed. A operação é tentada no máximo 5 vezes, dentro de um prazo de 1 hora, e sempre termina em completed ou failed. Um failed pode ser seguido de nova tentativa automática dentro desse prazo; enquanto isso, uma nova solicitação recebe 409. Depois do prazo, solicite uma nova rotação com outra Idempotency-Key.

Mostre a resposta somente ao operador autorizado; ela é enviada com Cache-Control: no-store. Se a consulta ainda não trouxer a conexão, repita a chamada.

Ligar ou desligar o acesso público

PATCH /v1/managed-services/:id/exposure

Liga ou desliga o acesso público de um serviço Valkey (Key-Value, Cache ou Queue). Exige managed_service.exposure.update no serviço.

CampoTipoObrigatórioDescrição
exposurestringSimpublic para aceitar conexões no host e na porta públicos, com TLS; private para que o endereço público deixe de aceitar conexões
{
  "exposure": "private"
}
{
  "status": "success",
  "message": "public access updated with success",
  "exposure": "private"
}

Com private, o serviço só é alcançado pelas conexões privadas entre aplicações ou de dentro da plataforma. Com public, ele volta a aceitar conexões no mesmo host e na mesma porta, e a connection_string externa continua igual. As conexões privadas e a rotação de credencial funcionam nos dois estados. O serviço precisa estar em running; se a alteração não puder ser concluída, a Zenifra mantém o estado anterior.

CódigoSituação
400exposure ausente ou diferente de public e private, ou :id inválido
403Sem a permissão managed_service.exposure.update no serviço (insufficient organization permission)
404Serviço inexistente, de outra organização ou em exclusão (project not found)
409PROJECT_STATE_CONFLICT: o serviço não está em running
409PROJECT_OPERATION_IN_PROGRESS: outra operação está em andamento no serviço
422PROJECT_OPERATION_NOT_SUPPORTED: o serviço não aceita esta operação
429Limite de requisições excedido
503DATABASE_EXPOSURE_UPDATE_FAILED: o acesso público não pôde ser atualizado e o estado anterior foi mantido; tente novamente

Erros comuns

CódigoSituação
400ID, parâmetros ou Idempotency-Key inválidos ou ausentes
401Sessão ou API Key ausente/inválida
403Permissão da organização insuficiente (insufficient organization permission)
404Serviço gerenciado inexistente ou de outra organização (managed service not found), ou operação de rotação não encontrada (credential rotation not found)
409PROJECT_OPERATION_IN_PROGRESS: já existe uma rotação ou outra operação em andamento
409PROJECT_STATE_CONFLICT: o serviço não está em running (por exemplo, parado)
409O serviço está sendo excluído (managed service is being deleted)
503Catálogo comercial ou operações de serviços gerenciados temporariamente indisponíveis

Limites de requisições (contados por IP de origem): catálogo 60 por minuto; estado 60 por minuto; conexão 30 por minuto; aplicações vinculadas 50 por minuto; solicitação de rotação 5 a cada 5 minutos; consulta da rotação 60 por minuto; alteração do acesso público 5 a cada 5 minutos.

Próximos passos

Última atualização em

Nessa página