> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vertracloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar um template privado

> Cria um template privado e a primeira versão dele a partir de um manifesto e do código de cada serviço, enviados como multipart form data.

Esta chamada cria um template privado com a primeira versão e responde `201` com o template. A requisição é `multipart/form-data`: o manifesto vai em um campo de texto, e cada serviço que executa o seu código vai em uma parte ZIP. Para começar a partir de um app ou de uma stack que você já tem, use [Criar template a partir de app](https://docs.vertracloud.app/pt-br/api-reference/endpoint/templates/create-from-app.md) ou [Criar template a partir de stack](https://docs.vertracloud.app/pt-br/api-reference/endpoint/templates/create-from-stack.md).

Precisa do escopo `templates:write` quando chamado com uma chave de API. Só planos que podem criar imagens Docker personalizadas podem criar templates, e cada conta tem no máximo 5 templates privados, pessoais e de workspace somados. Em um workspace, só o dono do workspace cria templates. Um template privado não é revisado pela Vertra Cloud: quem o recebe vê o aviso "Não verificado pela Vertra". Confira o manifesto antes com [Validar manifesto](https://docs.vertracloud.app/pt-br/api-reference/endpoint/templates/validate.md). O formato está na [referência do manifesto](https://docs.vertracloud.app/pt-br/templates/create/manifest-reference.md).

O ZIP de um serviço é verificado antes de ser armazenado. O envio inteiro é recusado com `TEMPLATE_SECRET_IN_SOURCE` quando tem um arquivo `.env` que não é um exemplo, uma chave privada ou um token conhecido; `details.files` lista apenas os caminhos. Pastas `.vertra/` são descartadas, e arquivos `.env*` nunca entram em um template.

**manifest** `string` *required*

O manifesto como string JSON serializada, seguindo o [schema do manifesto](https://docs.vertracloud.app/pt-br/templates/reference/manifest-schema.md). Um serviço cujo `source.type` é `image` se refere a uma imagem da sua conta pelo ID em `source.image`.

**sources\[service\_id]** `file`

Uma parte ZIP por serviço do manifesto cuja origem é `code`, nomeada pelo id do serviço, por exemplo `sources[bot]`. Obrigatória para cada um desses serviços.

**changelog** `string`

A mensagem da primeira versão, como objeto JSON serializado com `pt-br` (obrigatório), `en` e `es`.

**workspace\_id** `string`

O workspace que será dono do template. Sem ele, o template é seu.

```bash cURL theme={null}
curl -X POST https://api.vertracloud.app/v1/templates \
  -H "Authorization: Bearer $VERTRA_API_KEY" \
  -F 'manifest=<manifest.json' \
  -F 'sources[bot]=@bot.zip'
```

### Resposta

**response** `object`

O template, com a primeira versão.

**Mostrar objeto**

**id** `string`

O ID do template.

**slug** `string`

O slug do template, tirado do `id` do manifesto.

**origin** `string`

`private` para os templates que você cria. Os templates do catálogo são `vertra` ou `community`.

**visibility** `string`

`public`, `beta`, `hidden` ou `deprecated`.

**name** `object`

O nome por idioma: `pt-br`, `en` e `es`. Um `en` ou `es` ausente cai para `pt-br`.

**description** `object`

A descrição por idioma, no mesmo formato de `name`.

**category** `string`

`automation`, `ai-agents`, `bots`, `apis`, `cms`, `monitoring`, `starters`, `databases` ou `other`.

**tags** `string[]`

As tags.

**icon\_url** `string | null`

URL do ícone, ou `null` quando o template não tem um.

**author\_display** `string | null`

O nome exibido como autor. `null` para os templates feitos pela plataforma.

**links** `object`

Links do software que o template empacota: `website`, `docs`, `source` e `license`, todos opcionais.

**landing** `string | null`

Slug de uma página pública dedicada, ou `null`.

**featured** `boolean`

Destacado na galeria.

**current\_version** `object`

A versão mais recente: `id`, `version` (versão semântica), `security` (`true` para uma versão de segurança) e `created_at`.

**services** `object[]`

O que o template cria. Cada serviço tem `id`, `kind` (`app`, `database` ou `blob`), `source_type` (`code`, `image` ou `null`), `database` (o engine, ou `null`), `blob_visibility`, `ram` (`min`, `recommended` e `max` opcional, em MB), `web` (`required`, `optional`, `none` ou `null`) e `conditional` (`true` quando o serviço só é criado para algumas respostas).

**creates\_stack** `boolean`

`true` quando usar o template cria uma stack (dois ou mais serviços).

**ram\_min\_total** `integer`

A soma da memória mínima de todos os serviços, em MB.

**byok** `boolean`

`true` quando quem usa o template traz a própria chave para um modelo de IA.

**required\_plan** `string`

O plano mais baixo que pode usar o template.

**code\_view** `boolean`

`false` para um [template fechado](https://docs.vertracloud.app/pt-br/templates/use/closed-templates.md): quem o usa não pode ver o código dele.

**uses\_count** `integer | null`

Sempre `null` para um template privado.

**owner** `object | null`

`user_id` e `workspace_id` (`null` quando o template pertence ao usuário).

**github** `object | null`

O repositório vinculado (`repository` no formato `owner/name`, e `branch`), ou `null` quando o template não está vinculado.

**inputs** `object[]`

As perguntas que o usuário responde ao usar o template. Veja [Placeholders e inputs](https://docs.vertracloud.app/pt-br/templates/create/placeholders-and-inputs.md).

**permissions** `object`

As permissões efetivas dos apps criados a partir do template, depois dos padrões e das restrições de um template fechado: `code_view`, `code_edit`, `ram_change`, `ram_below_min`, `ram_above_max`, `env_add`, `commands_edit`, `terminal`, `save_as_template` e `detach`, todos booleanos.

**outputs** `object[]`

O que o assistente mostra no fim de um deploy: `label`, `value` e as flags opcionais `secret` e `once`.

**readme** `object | null`

A documentação do template (Markdown) por idioma, ou `null`.

**changelog** `object | null`

O changelog da versão mais recente por idioma, ou `null`.

**account** `object`

O que usar o template faria na sua conta (`fits`, `reasons`, `required_ram`, `free_ram`, `needs_image_slot`, `image_slots_free`, `in_use` e `in_use_count`). Presente apenas nas chamadas autenticadas que leem o template.

**created\_at** `string`

Quando o template foi criado.

**updated\_at** `string`

Quando o template foi atualizado pela última vez.

```json Response theme={null}
{
  "response": {
    "id": "tpl-abc123def456",
    "slug": "support-bot",
    "origin": "private",
    "visibility": "public",
    "name": { "pt-br": "Bot de suporte", "en": "Support bot" },
    "description": { "pt-br": "Bot que responde o suporte.", "en": "A bot that answers support." },
    "category": "bots",
    "tags": ["discord", "support"],
    "icon_url": null,
    "author_display": "Ana",
    "links": {},
    "landing": null,
    "featured": false,
    "current_version": {
      "id": "tplv-111222333444",
      "version": "1.0.0",
      "security": false,
      "created_at": "2026-10-27T14:02:00Z"
    },
    "services": [
      {
        "id": "bot",
        "kind": "app",
        "source_type": "code",
        "database": null,
        "blob_visibility": null,
        "ram": { "min": 256, "recommended": 512 },
        "web": "none",
        "conditional": false
      }
    ],
    "creates_stack": false,
    "ram_min_total": 256,
    "byok": false,
    "required_plan": "economy",
    "code_view": true,
    "uses_count": null,
    "owner": { "user_id": "1234567890123456789", "workspace_id": null },
    "github": null,
    "inputs": [],
    "permissions": {
      "code_view": true,
      "code_edit": true,
      "ram_change": true,
      "ram_below_min": false,
      "ram_above_max": true,
      "env_add": true,
      "commands_edit": true,
      "terminal": false,
      "save_as_template": true,
      "detach": true
    },
    "outputs": [],
    "readme": null,
    "changelog": null,
    "created_at": "2026-10-27T14:02:00Z",
    "updated_at": "2026-10-27T14:02:00Z"
  }
}
```

### Respostas de erro

**code** `string`

O código de erro que indica o motivo da falha. Valores possíveis:

* `API_KEY_SCOPE_DENIED`: A chave de API não tem o escopo `templates:write` (`403`).
* `TEMPLATE_MANIFEST_INVALID`: O manifesto não é válido; `details.issues` lista cada achado com o `path` e o `code`. Nada é criado.
* `TEMPLATE_SOURCE_REQUIRED`: Um serviço `code` não tem uma parte ZIP.
* `TEMPLATE_SECRET_IN_SOURCE`: Um ZIP tem um segredo (um arquivo `.env`, uma chave privada ou um token); `details.files` lista os caminhos (`400`).
* `TEMPLATE_SLUG_TAKEN`: O `id` do manifesto já está em uso entre os seus templates ou é uma palavra reservada.
* `TEMPLATE_PRIVATE_LIMIT_REACHED`: A conta já tem 5 templates privados.
* `PLAN_DOES_NOT_SUPPORT_CUSTOM_IMAGES`: O plano não pode criar imagens Docker personalizadas, então não pode criar templates.
* `IMAGE_NOT_FOUND`: Um serviço `image` se refere a uma imagem que não é sua ou não tem um build bem-sucedido.
* `WORKSPACE_OWNER_ONLY`: `workspace_id` foi enviado e quem chama não é o dono desse workspace.

```json Error Response theme={null}
{
  "code": "TEMPLATE_MANIFEST_INVALID",
  "details": {
    "issues": [{ "path": "services.bot.ram.min", "code": "invalid_ram", "message": "ram.min must be a positive number of MB" }]
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.