API Zenifra
A API da Zenifra permite automatizar tudo o que você faz no console: criar e remover projetos, publicar novas versões, configurar variáveis, domínio, instâncias e auto-scaling, acompanhar builds, logs e métricas, operar bancos de dados, serviços gerenciados, Jobs agendados e ambientes de preview.
Esta página reúne o que vale para todas as rotas: autenticação, permissões, formato das respostas, operações assíncronas, limites de requisições e códigos de status. Cada página da referência descreve os campos, as permissões e os erros específicos dos seus endpoints.
URL base
Todas as rotas usam o prefixo /v1:
https://api.zenifra.com/v1Envie corpos em JSON com Content-Type: application/json.
Autenticação
API Key da organização (recomendada para automações)
Crie a chave em Organização → API Keys no console. Ela pertence à organização, concede apenas os scopes escolhidos e pode ter data de expiração e lista de IPs permitidos. O segredo começa com znf_ e é exibido uma única vez, no momento da criação. Veja API Keys da Organização.
Envie a chave em um destes headers:
-H "x-api-key: znf_..."
# ou
-H "Authorization: Bearer znf_..."A organização é identificada pela própria chave, então o header x-organization-id não é necessário nessas chamadas.
Token de sessão de usuário
Integrações que agem em nome de uma pessoa usam Authorization: Bearer <token> e precisam informar a organização ativa em x-organization-id. Sem esse header, a API responde 400 ou 403, conforme a rota.
Algumas rotas só aceitam token de usuário, como a criação e a revogação de conexões Git (exigem sessão de owner), as configurações de ambientes de preview e a gestão de membros. As páginas dessas rotas indicam essa restrição.
Chaves legadas de projeto
Chaves antigas, vinculadas a um único projeto, continuam aceitas apenas para atualizar a imagem publicada (Atualizar imagem) e para operar ambientes de preview com o opt-in ativo. Para qualquer outra rota, use uma API Key da organização.
Headers
| Header | Quando usar | Descrição |
|---|---|---|
x-api-key ou Authorization: Bearer znf_... | Automações | API Key da organização |
Authorization: Bearer <token> | Sessão de usuário | Token de login |
x-organization-id | Obrigatório com token de usuário | Organização ativa. Ignorado quando a credencial é uma API Key da organização |
Content-Type: application/json | Requisições com corpo | Formato do payload |
Idempotency-Key | Rotas que o aceitam | Evita duplicar operações ao repetir uma requisição; veja abaixo |
Permissões
Para uma sessão owner, o acesso é completo. Membros assistant, member e API Keys precisam do scope da ação no recurso correto, por ID específico ou com * para todos os recursos daquele tipo:
| Tarefa | Scope mínimo |
|---|---|
| Criar projeto HTTP ou Job agendado | project.create em organization:* |
| Criar banco de dados (PostgreSQL, MariaDB ou Analytics) | database.create em organization:* |
| Criar Key-Value, Cache ou Queue (Valkey) | managed_service.create em organization:* |
| Visualizar projeto | project.read em project:<project-id> |
| Métricas e uso de armazenamento | project.metrics.read em project:<project-id> |
| Logs e builds | project.logs.read em project:<project-id> |
| Publicar nova imagem | project.image.update em project:<project-id> |
| Remover projeto | project.delete em project:<project-id> |
O catálogo completo de scopes está em API Keys da Organização. Uma API Key com IP fora da lista permitida recebe 403 com o código API_KEY_IP_NOT_ALLOWED; uma chave expirada ou revogada recebe 401.
Formato das respostas
As respostas usam um envelope JSON com status:
{
"status": "success",
"data": { }
}Erros retornam status: "failed" com uma message legível e, quando existe, um code estável para tratar no seu código:
{
"status": "failed",
"code": "PROJECT_MUST_BE_RUNNING",
"message": "project must be running to update autoscaling"
}Use o code (quando presente) e o status HTTP para decidir o que fazer; não dependa do texto exato de message.
O corpo é validado antes da autenticação na maioria das rotas. Por isso, um payload inválido retorna 400 mesmo quando a credencial também está ausente.
Operações assíncronas e idempotência
Operações que levam tempo, como builds, previews e rotação de credenciais de serviços gerenciados, respondem 202 Accepted com um identificador de operação. A implantação de templates responde 201 com o estado da implantação. Consulte o estado na rota indicada pela página do recurso até a operação terminar.
Rotas que aceitam o header Idempotency-Key usam a chave para devolver a mesma operação quando a requisição é repetida, sem criar um segundo recurso. Gere um valor único por operação (por exemplo, um UUID) e reutilize-o apenas ao repetir exatamente a mesma requisição.
Limites de requisições
Cada rota tem o seu próprio limite, contado por endereço IP de origem, método e rota. Consultas costumam aceitar mais chamadas por minuto do que operações de escrita, e operações sensíveis, como troca de plano ou de exposição, têm limites menores. As páginas de cada recurso informam os limites relevantes.
Ao exceder o limite, a API responde 429 Too Many Requests com uma mensagem que informa quantos segundos aguardar. Implemente espera e nova tentativa com intervalo crescente.
Códigos de status HTTP
| Código | Significado |
|---|---|
200 | Requisição bem-sucedida |
201 | Recurso criado |
202 | Operação aceita e processada em segundo plano |
400 | Dados inválidos, header obrigatório ausente ou operação não suportada para o tipo de projeto |
401 | Credencial ausente, inválida, expirada ou revogada; em algumas rotas antigas, plano sem o recurso |
402 | Plano sem métricas, ou organização com pagamento pendente |
403 | Permissão insuficiente, recurso fora do escopo da credencial, IP não permitido ou plano sem o recurso (ex.: HEALTHCHECK_NOT_AVAILABLE_FOR_PLAN) |
404 | Recurso não encontrado (projeto, organização, build, preview, execução) |
409 | Conflito com o estado atual, como operação em andamento, projeto parado ou capacidade indisponível no plano |
429 | Limite de requisições excedido ou alteração em período de espera |
500 | Erro interno |
502 | Falha ao concluir uma etapa dependente da operação |
503 | Recurso temporariamente indisponível; tente novamente mais tarde |
Endpoints por área
Projetos
| Tarefa | Página | Endpoints principais |
|---|---|---|
| Criar, listar e remover projetos; consultar planos | Projetos | POST /project, GET /project, DELETE /project/:id, GET /project/plans |
| Consultar projeto, nome, descrição e exposição | Informações do Projeto | GET /project/:id, PATCH /project/:id/name, PATCH /project/:id/exposure |
| Parar ou retomar | Ciclo de Vida | PATCH /project/:id/stop, PATCH /project/:id/resume |
| Alterar plano e renovação | Plano | PATCH /project/:id/plan |
| Escalar instâncias | Instâncias | GET /project/:id/instances, PATCH /project/:id/instances |
| Configurar auto-scaling | Auto-scaling | PATCH /project/:id/autoscaling |
| Configurar health check | Health check | GET /project/:id/healthcheck, PATCH /project/:id/healthcheck |
| Avisos por e-mail | Alertas | GET /project/:id/alerts, PATCH /project/:id/alerts |
| Variáveis de ambiente | Variáveis de Ambiente | GET /project/:id/envs, PATCH /project/:id/envs |
| Armazenamento | Armazenamento | PATCH /project/:id/storage/size, GET /project/:id/storage/usage |
| Subdomínio e domínios personalizados | Domínio | PATCH /project/:id/domain, PATCH /project/:id/custom-domains |
| Restringir acesso por IP | Acesso de rede | PATCH /project/:id/network-access |
| Custos do projeto | Cobrança do projeto | GET /project/:id/billing/hourly-usage, GET /project/:id/billing/ledger |
| Jobs agendados | Jobs agendados | PATCH /project/:id/schedule, GET /project/:id/job-runs |
Deploy
| Tarefa | Página | Endpoints principais |
|---|---|---|
| Publicar uma imagem | Atualizar Imagem de Deploy | PATCH /project/:id/image |
| Histórico de publicações | Deployments | GET /project/:id/historic/deployments |
| Conectar repositórios e configurar a origem | Conexões e origens Git | /git/providers, /git/connections, /project/:id/source |
| Disparar e acompanhar builds | Builds de repositórios Git | POST /project/:id/deploy, GET /project/:id/builds, GET /project/:id/builds/:buildId/logs |
| Ambientes de preview | Ambientes de Preview | PUT /project/:id/preview-environments/:previewKey |
| Templates | Templates | GET /templates, POST /templates/:id/deployments |
As rotas /project/:id/github/* continuam disponíveis para projetos GitHub antigos. Para novas integrações, use as rotas /project/:id/deploy e /project/:id/builds, que funcionam com qualquer provedor Git.
Dados e serviços
| Tarefa | Página | Endpoints principais |
|---|---|---|
| Status, conexão, senha e versão de bancos | Bancos de dados | GET /project/:id/database/status, GET /project/:id/database/connection |
| Key-Value, Cache e Queue (Valkey) | Serviços gerenciados | GET /managed-services/:id/connection, PATCH /managed-services/:id/credentials |
Observabilidade
| Tarefa | Página | Endpoints principais |
|---|---|---|
| Métricas e logs | Métricas e Logs | GET /project/:id/metrics, GET /project/:id/logs |
| Tráfego HTTP | Métricas de Rede | GET /project/:id/metrics/network/* |
Exemplos
cURL
curl "https://api.zenifra.com/v1/project/507f1f77bcf86cd799439011" \
-H "x-api-key: $ZENIFRA_API_KEY"Python
import os
import requests
BASE_URL = "https://api.zenifra.com/v1"
headers = {"x-api-key": os.environ["ZENIFRA_API_KEY"]}
response = requests.get(
f"{BASE_URL}/project/507f1f77bcf86cd799439011/metrics",
headers=headers,
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Node.js
const BASE_URL = 'https://api.zenifra.com/v1'
async function getMetrics(projectId) {
const response = await fetch(`${BASE_URL}/project/${projectId}/metrics`, {
headers: { 'x-api-key': process.env.ZENIFRA_API_KEY },
})
if (!response.ok) {
throw new Error(`Zenifra API ${response.status}: ${await response.text()}`)
}
return (await response.json()).data
}
getMetrics('507f1f77bcf86cd799439011').then(console.log)Guarde a API Key em uma variável de ambiente ou cofre de segredos; nunca a coloque no código-fonte nem em aplicações frontend.
FAQ
Onde encontro a API Key e o ID do projeto?
A API Key é criada em Organização → API Keys; o segredo aparece uma única vez, então guarde-o com segurança no momento da criação. Se perder o segredo, revogue a chave e crie outra. O ID do projeto aparece no console, na URL da página do projeto e na resposta de GET /v1/project.
Uma API Key vale para todos os projetos?
Vale para os recursos e ações que você escolher na criação. Use o ID específico do projeto para limitar a chave a um projeto, ou * para todos os projetos atuais e futuros da organização. Prefira chaves com o mínimo de scopes, separadas por ambiente ou integração.
O x-organization-id é sempre necessário?
Não. Com API Key da organização, a organização vem da própria chave. Com token de usuário, o header é obrigatório.
Existe limite de requisições?
Sim. Os limites variam por rota e são contados por IP de origem. Ao receber 429, aguarde o tempo indicado na resposta antes de tentar novamente. Para automações com volume alto, fale com o suporte.
Posso usar a CLI ou o MCP em vez da API?
Sim. A CLI e o servidor MCP usam a mesma API e as mesmas permissões, e são o caminho mais rápido para scripts e assistentes.
Última atualização em