Ambientes de Preview — API
Use estes endpoints para configurar e operar Ambientes de Preview aninhados em um projeto HTTP principal. Um preview tem identidade, URL, capacidade, storage e ciclo de cobrança próprios, mas só pode ser acessado pelo projeto principal ao qual pertence.
A operação é idempotente por organização, projeto principal e previewKey. PUT e DELETE podem retornar uma operação assíncrona; consulte o endpoint de operação até alcançar um estado terminal.
Autenticação e segurança
Inclua uma credencial com a permissão do projeto correspondente e o contexto da organização:
| Header | Obrigatório | Descrição |
|---|---|---|
x-api-key | Nas operações da Action | API Key do projeto principal, mantida em um secret. |
x-organization-id | Requests com token da organização | Organização ativa do projeto. A Action identifica a organização pelo projeto autenticado. |
Content-Type: application/json | Em requests com body | Indica um body JSON. |
O owner precisa habilitar Ambientes de Preview no console antes que uma API Key do projeto possa operar previews. A chave fica limitada ao projeto principal e aos guardrails configurados: ela não altera settings, entitlement, limites ou planos não permitidos.
As respostas públicas nunca incluem variáveis de ambiente, credenciais, URLs privadas de imagem, nomes de recursos ou detalhes operacionais internos. Trate a API Key como segredo e não a registre.
URL base e identificadores
https://api.zenifra.com/v1Nos exemplos, PROJECT_ID representa o ID do projeto HTTP principal e API_KEY representa uma API Key mantida em um secret. Substitua apenas esses placeholders pelos valores da sua organização.
export PROJECT_ID="seu-project-id"
export API_KEY="sua-api-key"
export USER_TOKEN="seu-token-de-usuario"
export ORGANIZATION_ID="sua-organization-id"
export BASE_URL="https://api.zenifra.com/v1"A previewKey deve usar somente letras, números, ponto, sublinhado e hífen, dentro do limite de tamanho da API. Não altere silenciosamente uma chave rejeitada.
Endpoints
| Objetivo | Método e rota |
|---|---|
| Consultar settings | GET /project/:projectId/preview-environments/settings |
| Atualizar settings | PATCH /project/:projectId/preview-environments/settings |
| Listar plano herdado | GET /project/:projectId/preview-environments/plans |
| Consultar custos dos previews | GET /project/:projectId/preview-environments/billing |
| Listar previews | GET /project/:projectId/preview-environments |
| Criar ou atualizar um preview | PUT /project/:projectId/preview-environments/:previewKey |
| Consultar um preview | GET /project/:projectId/preview-environments/:previewKey |
| Remover um preview | DELETE /project/:projectId/preview-environments/:previewKey |
| Consultar uma operação | GET /project/:projectId/preview-environments/:previewKey/operations/:operationId |
Settings do projeto
Consultar settings
GET /project/:projectId/preview-environments/settingsRetorna o opt-in e os guardrails efetivos do projeto principal. A resposta pública inclui enabled, o plano herdado do projeto em default_plan/allowed_plans, default_ttl_hours, max_ttl_hours e max_active_environments. O Preview nunca pode escolher um plano diferente do projeto principal.
curl -sS "$BASE_URL/project/$PROJECT_ID/preview-environments/settings" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID"Exemplo de resposta:
{
"data": {
"enabled": true,
"default_plan": "basic",
"allowed_plans": ["basic"],
"default_ttl_hours": 24,
"max_ttl_hours": 168,
"max_active_environments": 5
}
}Atualizar settings
PATCH /project/:projectId/preview-environments/settingsRequer permissão de configuração no projeto. A API não permite alterar o entitlement da organização nem ultrapassar o limite efetivo.
{
"enabled": true,
"default_ttl_hours": 24,
"max_ttl_hours": 168,
"max_active_environments": 5
}default_ttl_hours e max_ttl_hours devem estar entre 1 e 168, e o default não pode ser maior que o máximo. O preço horário sempre vem do plano do projeto principal.
Custos dos previews
GET /project/:projectId/preview-environments/billingRequer project.billing.read. Retorna o custo acumulado dos Previews ativos, a taxa horária atual e uma estimativa até a expiração de cada ambiente e do conjunto.
Os valores monetários são retornados em centavos de BRL, seguindo o contrato de billing existente. Por exemplo, 5.4 representa R$ 0,054. accrued_amount considera snapshots horários calculados até as_of; pending_amount identifica o valor ainda aguardando settlement. estimated_until_expiration é uma estimativa, não uma cobrança final, e não inclui a hora corrente enquanto ela não tiver sido fechada pelo job de uso horário.
{
"data": {
"currency": "brl",
"as_of": "2026-08-25T22:00:00.000Z",
"previews": [
{
"preview_id": "preview-id",
"key": "pr-42",
"status": "running",
"plan": "basic",
"hourly_rate": 5.4,
"accrued_amount": 10.8,
"settled_amount": 5.4,
"pending_amount": 5.4,
"estimated_until_expiration": 21.6,
"expires_at": "2026-08-26T02:00:00.000Z",
"billing_status": "pending"
}
],
"summary": {
"active_previews": 1,
"accrued_amount": 10.8,
"settled_amount": 5.4,
"pending_amount": 5.4,
"hourly_rate": 5.4,
"estimated_until_expiration": 21.6
}
}
}Planos
Listar planos de preview
GET /project/:projectId/preview-environments/plansRetorna o plano do projeto principal e seus preços publicados em BRL. O endpoint existe para que o Console mostre o custo correto; não há um catálogo de planos exclusivo para Preview.
curl -sS "$BASE_URL/project/$PROJECT_ID/preview-environments/plans" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID"O preço retornado pelo catálogo é a fonte de verdade. Não copie valores comerciais para a Action ou para a aplicação cliente.
Listar previews
GET /project/:projectId/preview-environmentsLista os previews aninhados no projeto principal. Use os parâmetros page e limit para paginação.
curl -sS "$BASE_URL/project/$PROJECT_ID/preview-environments?page=1&limit=20" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID"Cada item pode conter os seguintes campos públicos:
| Campo | Descrição |
|---|---|
id | Identificador público do preview. |
key | Chave estável que identifica o ambiente no projeto. |
status | Estado de produto, como accepted, provisioning, available, deleting, deleted ou failed. |
url | URL pública quando disponível. |
plan | Plano selecionado. |
payment_mode | O preview usa cobrança hourly. |
exposure | Exposição configurada para o ambiente. |
inherit_envs | Sempre true: os ENVs do projeto principal são herdados. Nunca contém os valores. |
updated_at e expires_at | Atualização mais recente e expiração atual. |
A lista não retorna ENVs, dados, credenciais, hashes, leases, contadores ou nomes de recursos.
Criar ou atualizar um preview
PUT /project/:projectId/preview-environments/:previewKeyCria ou atualiza o preview identificado por previewKey. O corpo de um upsert aceita:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
image | string | Sim no upsert | Referência da imagem pronta a publicar. |
inherit_envs | boolean | Não | Campo de compatibilidade legada; o Preview sempre herda os ENVs do usuário dentro da Zenifra. |
ttl_hours | integer | Não | Duração em horas; default 24, mínimo 1, máximo 168. |
O preview usa sempre o plano do projeto principal e sincroniza sua porta, exposição e regras de acesso. O storage é novo, vazio e isolado. Dados, domínios personalizados e comandos customizados de imagem não são herdados.
curl -sS -X PUT \
"$BASE_URL/project/$PROJECT_ID/preview-environments/pr-42" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID" \
-H "Content-Type: application/json" \
-d '{
"image": "docker.io/library/nginx@sha256:6784fb0834aa7dbbe12e3d7471e69c290df3e6ba810dc38b34ae33d3c1c05f7d",
"ttl_hours": 24
}'A primeira aceitação normalmente retorna 202 Accepted com id, key, operation_id e o estado atual. Um replay idempotente que já terminou pode retornar 200. Se houver uma operação ativa com payload incompatível, a API retorna 409 e a operação existente deve ser consultada.
Consultar um preview
GET /project/:projectId/preview-environments/:previewKeyRetorna o estado atual, URL, plano, preço horário em BRL quando disponível, herança de ENVs, timestamps e a operação corrente. Não retorna valores de variáveis de ambiente.
curl -sS \
"$BASE_URL/project/$PROJECT_ID/preview-environments/pr-42" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID"Remover um preview
DELETE /project/:projectId/preview-environments/:previewKeySolicita a remoção imediata do preview e encerra sua cobrança quando a remoção for confirmada. A operação é idempotente: repetir o delete não cria outro ambiente nem outra cobrança.
curl -sS -X DELETE \
"$BASE_URL/project/$PROJECT_ID/preview-environments/pr-42" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID"A primeira solicitação pode retornar 202 Accepted com operation_id. Quando o preview já estiver removido, a repetição retorna o estado terminal ou uma resposta de sucesso equivalente. A Action não exige IMAGE para este caminho.
Polling de operações
Consultar uma operação
GET /project/:projectId/preview-environments/:previewKey/operations/:operationIdUse o operation_id retornado por PUT ou DELETE para acompanhar a operação. Consulte em intervalos limitados e pare em um estado terminal.
Estados possíveis:
acceptedreservingprovisioningupdatingavailabledeletingdeletedfailed
Upsert termina com sucesso em available; delete termina com sucesso em deleted. Em failed, leia o código público e corrija a entrada antes de tentar novamente.
curl -sS \
"$BASE_URL/project/$PROJECT_ID/preview-environments/pr-42/operations/operation-id" \
-H "Authorization: Bearer $USER_TOKEN" \
-H "x-organization-id: $ORGANIZATION_ID"A resposta de operação contém somente estado, identificadores públicos, timestamps, URL quando disponível, expires_at e erro público sanitizado. Não contém segredos ou detalhes internos.
Erros públicos
Os códigos de domínio permanecem estáveis e a mensagem é acionável:
| Código | Significado |
|---|---|
preview_not_enabled | O opt-in ainda não foi habilitado no projeto principal. |
invalid_preview_key | A chave não atende ao formato ou tamanho permitido. |
preview_plan_not_allowed | O plano não está na lista permitida. |
preview_ttl_invalid ou preview_ttl_exceeds_limit | Use um TTL entre 1h e 168h e dentro do limite do projeto. |
preview_organization_limit_reached ou preview_project_limit_reached | O limite efetivo do projeto ou da organização foi atingido. |
parent_configuration_unavailable | Não há configuração pública suficiente no projeto principal para aplicar o preview. |
preview_operation_in_progress | Já existe uma operação ativa para a mesma identidade. |
preview_unavailable | O preview não pôde ficar disponível com a entrada fornecida. |
preview_wait_timeout | A Action atingiu o tempo máximo de espera. |
Além do código, a API pode retornar uma mensagem e um identificador de requisição para suporte. Nunca exponha a resposta completa em logs públicos quando ela fizer parte de uma automação.
Status HTTP
200: leitura bem-sucedida ou replay de uma operação já concluída.202: upsert ou delete aceito para processamento.400: body, chave, ação ou duração inválidos.401: credencial ausente ou inválida.403: organização, projeto ou permissão insuficiente; o opt-in também precisa estar ativo para mutações com API Key.404: projeto principal, preview ou operação não encontrada.409: conflito com uma operação ativa ou payload incompatível.