# Templates

> Cache de templates por conta, sincronização, criação e exclusão.

Fonte: https://metahub.matratecnologia.com/docs/templates

Cache dos templates da conta (WABA) da conexão, montado na ativação e mantido pelos webhooks da Meta.

| Método e rota | O que faz | Respostas |
|---|---|---|
| `GET …/templates` | Lista (paginada); filtros `status`, `category`, `language`, `name` | 200, 404 |
| `GET …/templates/:templateId` | Busca um (id do hub) | 200, 404 `TEMPLATE_NOT_FOUND` |
| `POST …/templates` | Cria na Meta | 201, 400, 403, 404, 409, 422, 429, 502 |
| `DELETE …/templates/:templateId` | Exclui na Meta (só aquele idioma) | 204, 404, 409, 422, 429, 502 |
| `POST …/templates/sync` | Pede a ressincronização com a Meta | 202 |

Template: `{ id, name, language, category, status, parameterFormat, components, qualityScore, rejectedReason, correctCategory, pendingCategoryAt, syncedAt }`. `components` vem no formato da Meta. `correctCategory`/`pendingCategoryAt` avisam que a Meta vai trocar a categoria naquela data.

**Sync.** `POST …/templates/sync` responde `202 { "status": "queued" | "recent", "syncedAt": ... }`: `queued` quando enfileira, `recent` quando já houve um pedido nos últimos 5 minutos (nada é enfileirado; o limite da Meta é de 200 chamadas por hora por conta). Pedido que chega com uma sincronização da conta já em andamento ganha outra rodada quando ela termina. O resultado aparece nas leituras e nos eventos de template.

**Criar.** Corpo estrito por `category` (`MARKETING`, `UTILITY` ou `AUTHENTICATION`), com `name` (`a-z 0-9 _`, até 512), `language` (código da Meta, por exemplo `pt_BR`) e `ttlSeconds?`. `MARKETING`/`UTILITY` aceitam `parameterFormat` (`POSITIONAL` ou `NAMED`), `header?` (texto ou localização; header de mídia responde `400 TEMPLATE_MEDIA_HEADER_UNSUPPORTED`), `body`, `footer?` e `buttons?`. `AUTHENTICATION` só no preset de código (`addSecurityRecommendation?`, `codeExpirationMinutes?`, `buttonText?`). A categoria gravada é a da resposta da Meta (um `UTILITY` pode ser aprovado como `MARKETING`); a aprovação chega por `whatsapp.template.status_updated`.

| Status | `code` | Quando |
|---|---|---|
Recusas da criação e da exclusão:

| Status | `code` | Rota | Quando |
|---|---|---|---|
| 400 | (validação) | criar | corpo fora do schema (campo extra, nome fora do formato, `ttlSeconds` fora da faixa da categoria, parâmetros do `body` sem exemplo ou fora de ordem) |
| 400 | `TEMPLATE_MEDIA_HEADER_UNSUPPORTED` | criar | header `IMAGE`, `VIDEO` ou `DOCUMENT` (o hub ainda não sobe a mídia de exemplo) |
| 404 | `CONNECTION_NOT_FOUND` / `TEMPLATE_NOT_FOUND` | as duas / excluir | conexão de outro app, conta que passou para outro workspace, template de outra conta ou já excluído |
| 409 | `TEMPLATE_NAME_TAKEN` | criar | já existe o nome nesse idioma |
| 409 | `TEMPLATE_NOT_DELETABLE` | excluir | template `DISABLED` (a Meta não permite excluir); nada é chamado |
| 409 | `CONNECTION_NOT_ACTIVE` / `CREDENTIAL_UNAVAILABLE` | as duas | conexão `disconnected`, ou a conta não tem conexão `active` com credencial |
| 403 | `META_PERMISSION_DENIED` | criar | a Meta negou a permissão |
| 422 | `META_REJECTED` | as duas | outra recusa da Meta, com `metaCode` |
| 429 | `META_RATE_LIMITED` | as duas | a Meta limitou as chamadas do app ou da conta (`metaCode` `4`, `80007` ou `80008`); `Retry-After: 60`. Nada foi criado nem excluído: repita depois |
| 429 | sem `code` | as duas | o rate limit por chave do hub (30/min nas escritas de template), com `Retry-After` |
| 502 | `META_UNAVAILABLE` | as duas | resposta incerta; na criação o hub pede uma sync. Confira a listagem antes de repetir |
