Templates
Cache de templates por conta, sincronização, criação e exclusão.
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 |