Templates API

A API de Templates permite consultar o catálogo público ou o catálogo da organização ativa, criar e revisar pontos de partida para aplicações HTTP e iniciar um projeto com uma revisão específica. As rotas de gerenciamento exigem autenticação de usuário ou API key da organização e o contexto x-organization-id. A listagem pública oficial possui uma rota separada sem autenticação.

Autenticação e contexto

Envie um token de usuário no header Authorization com o esquema Bearer ou uma API key de organização conforme o fluxo de autenticação usado pela sua integração. Inclua x-organization-id nas chamadas autenticadas. A organização ativa define os templates privados e o destino de um novo projeto.

Authorization: Bearer <token>
x-organization-id: <organization-id>
Content-Type: application/json

GET /v1/public/templates é a única rota desta referência que não exige Authorization nem x-organization-id. Ela serve somente para consultar o catálogo oficial público. Criar projetos ou alterar templates continua exigindo autenticação e as permissões correspondentes.

Permissões necessárias

Use somente o scope da ação e o ID do template quando a operação for sobre um template específico:

AçãoScope mínimo
Listar ou visualizar templatetemplate.read em template:<template-id>; templates públicos seguem o contrato público
Criar template privadotemplate.create em organization:*
Editar templatetemplate.update em template:<template-id>
Publicar ou tornar privadotemplate.publish em template:<template-id>
Remover templatetemplate.delete em template:<template-id>
Criar projeto a partir do templatetemplate.read em template:<template-id> e o scope de criação do projeto correspondente

owner tem acesso completo na sessão de usuário. assistant, member e API Keys da organização precisam dos grants específicos. Um template que cria banco também exige database.create em organization:*; um template que cria cache ou queue exige managed_service.create em organization:*.

Listar o catálogo público oficial

Use esta rota em sites, vitrines e outras integrações que precisam exibir Templates oficiais sem abrir uma sessão de usuário:

GET /v1/public/templates?sort=most_used&page=1&limit=12

Não envie Authorization nem x-organization-id nessa chamada.

ParâmetroObrigatórioValores e padrão
sortNãomost_used (padrão), newest ou updated
pageNãoPágina iniciando em 1; padrão 1
limitNãoDe 1 a 24 itens; padrão 12

A resposta inclui apenas Templates públicos e ativos de organizações oficiais ativas. most_used ordena por organizações consumidoras únicas, depois por implantações concluídas e data de criação. newest usa a data de criação; updated usa a última atualização. A ordenação possui desempate determinístico para manter a paginação estável.

Cada item público contém somente id, name, summary, description, tags, official, author.organization_name, requires_database e updated_at. Configuração da aplicação, variáveis, padrões de plano, dados de uso e identificadores da organização não fazem parte deste contrato.

Exemplo de estrutura da resposta:

{
  "status": "success",
  "data": {
    "items": [
      {
        "id": "507f1f77bcf86cd799439011",
        "name": "API de atendimento",
        "summary": "Ponto de partida para uma API HTTP.",
        "description": "Template oficial para iniciar uma API.",
        "tags": ["api"],
        "official": true,
        "author": {
          "organization_name": "Zenifra"
        },
        "requires_database": true,
        "updated_at": "2026-09-03T12:00:00.000Z"
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 12,
      "total": 1,
      "pages": 1
    }
  }
}

Listar templates com autenticação

GET /v1/templates?scope=organization&sort=updated&page=1&limit=20
ParâmetroObrigatórioValores
scopeSimorganization ou public
sortSimupdated, newest ou most_used
officialNãotrue ou false; disponível com scope=public
pageNãoPágina iniciando em 1
limitNãoAté 50 itens

organization retorna templates acessíveis na organização ativa, ordenados pela última atualização. public retorna templates publicados. most_used usa organizações consumidoras únicas como critério principal e deploys concluídos como desempate. Use official=true para retornar somente Templates publicados pela Zenifra ou por parceiros oficiais.

Cada Template retornado informa apenas o nome público da organização autora. O identificador da organização não é compartilhado. owned_by_current_organization indica se o Template pertence à organização ativa, enquanto official informa se a autora é uma publicadora oficial. Os dois campos são informativos e não concedem permissões.

{
  "author": {
    "organization_name": "Organização autora"
  },
  "owned_by_current_organization": false,
  "official": true
}

Obter, criar e editar

GET /v1/templates/:id
POST /v1/templates
PATCH /v1/templates/:id

O corpo de criação e edição contém name, summary, description, tags, application, variables e defaults. A aplicação informa reference, port e storage_path; os padrões informam plano, cobrança, exposição, instâncias, auto-scaling e storage. Um template que precisa de banco também pode incluir opcionalmente database_dependency.

Referências públicas são aceitas para Docker Hub, GHCR, Quay e GitLab Registry. A Zenifra valida a aplicação antes de aceitar a revisão. Não envie credenciais, tokens ou valores secretos no template.

Cada edição exige expected_revision e uma revisão antiga retorna 409 Conflict. Variáveis secretas não podem ter default_value.

Dependência de banco

Consulte o catálogo atual antes de criar ou editar uma dependência:

GET /v1/project/database/catalog

A resposta lista IDs de mecanismos, planos, formas de cobrança, campos de configuração e campos de conexão. Use esses IDs em vez de manter uma lista fixa na sua integração. database_dependency declara mecanismos compatíveis, uma recomendação para cada mecanismo e vínculos opcionais de variáveis:

{
  "database_dependency": {
    "compatible_engine_ids": ["postgresql", "mariadb"],
    "recommended_engine_id": "postgresql",
    "recommendations": [
      { "engine_id": "postgresql", "plan_id": "db-basic", "payment_mode": "monthly", "configuration": { "version": "18", "instances": 1, "storage_capacity_gb": 10 } },
      { "engine_id": "mariadb", "plan_id": "db-basic", "payment_mode": "monthly", "configuration": { "version": "11", "instances": 3, "storage_capacity_gb": 10 } }
    ],
    "environment_bindings": [
      { "variable_name": "DB_PASSWORD", "connection_field_id": "password" },
      { "variable_name": "DB_HOST", "connection_field_id": "host" }
    ]
  }
}

Cada vínculo deve apontar para uma variável declarada e para um campo de conexão suportado por todos os mecanismos compatíveis. Vínculos de campos sensíveis exigem variável secreta e não podem ter valor padrão. Vínculos não sensíveis podem fornecer um valor sugerido para banco externo; a criação conjunta o substitui pelos dados da nova conexão. Omitir database_dependency cria um template sem dependência de banco. Na edição, omita o campo para preservar a dependência atual ou envie null para removê-la.

Publicar e remover

PATCH /v1/templates/:id/visibility
DELETE /v1/templates/:id

O corpo de visibilidade é { "visibility": "public", "expected_revision": 2 }. A criação começa privada. Publicar ou tornar privado exige template.publish; remoção exige template.delete e expected_revision. A remoção é lógica e não altera projetos já criados.

Criar projeto por template

Use o payload alternativo de POST /v1/project:

{
  "template_id": "507f1f77bcf86cd799439011",
  "template_revision": 2,
  "name": "atendimento-api",
  "description": "Projeto criado a partir de um template",
  "plan": "basic",
  "payment_mode": "monthly",
  "config": {
    "exposure": "public",
    "instances": 1,
    "storage": { "persistent": true, "capacity": 10 },
    "envs": [
      { "name": "APP_ENV", "value": "production" },
      { "name": "APP_SECRET", "value": "valor-informado-no-deploy" }
    ],
    "network_access": {
      "ingress_white_list": [{ "cidr": "0.0.0.0/0", "description": "Acesso ao projeto" }],
      "ingress_black_list": []
    }
  }
}

A aplicação, porta, tipo HTTP e pasta persistente vêm da revisão do template. O request deve conter exatamente as variáveis declaradas. A implantação exige project.create e, para template privado, template.read. Falhas não contam uso nem alteram o ranking.

Criar aplicação e banco juntos

Para um template com dependência de banco, crie os dois recursos com:

POST /v1/templates/:id/deployments
Idempotency-Key: <chave-unica-com-ao-menos-16-caracteres>

O corpo inclui expected_revision, a configuração habitual da aplicação e o banco selecionado:

{
  "expected_revision": 2,
  "application": { "name": "atendimento-api", "plan": "basic", "payment_mode": "monthly", "config": { "exposure": "public", "instances": 1, "storage": { "persistent": true, "capacity": 10 }, "envs": [{ "name": "APP_ENV", "value": "production" }], "network_access": { "ingress_white_list": [], "ingress_black_list": [] } } },
  "database": { "name": "atendimento-db", "engine_id": "postgresql", "plan_id": "db-basic", "payment_mode": "monthly", "configuration": { "version": "18", "instances": 1, "storage_capacity_gb": 10 } }
}

A chamada exige project.create e database.create. A resposta contém apenas ID e estado da implantação, além dos IDs dos projetos; nunca contém credenciais de conexão. Reutilize a mesma chave de idempotência e corpo idêntico para tentar novamente com segurança. Um corpo diferente com a mesma chave retorna 409 Conflict.

GET /v1/template-deployments/:deploymentId

Use esse endpoint para acompanhar creating, ready, rolling_back ou failed. Banco e aplicação criados com sucesso continuam sendo projetos independentes.

Limites

O catálogo público oficial tem limite de 120 requisições por minuto por IP. Leituras autenticadas têm limite de 100 requisições por minuto. Criação e edição têm limite de 10 por minuto. Publicação e remoção têm limite de 5 por minuto. Respeite respostas 429 e aguarde antes de tentar novamente.

Próximos passos

Nessa página