Templates (HTTP)
Endpoints /v1/templates — criar, listar, editar, sincronizar e apagar.
Templates são só para números oficiais (WABA). O broker é dono ponta a ponta: valida, submete à plataforma oficial, guarda o estado e reconcilia por sync. Os endpoints estão sob /v1/templates.
| método | path | o que faz |
|---|---|---|
POST | /v1/templates | cria e submete um template à plataforma oficial |
GET | /v1/templates | lista os templates (paginado, filtro por status) |
GET | /v1/templates/:id | lê um template |
PATCH | /v1/templates/:id | edita (só APPROVED/REJECTED) |
DELETE | /v1/templates/:id | apaga (soft-delete + delete na plataforma oficial) |
POST | /v1/templates/sync | reconcilia o estado com a plataforma oficial |
Criar um template
Corpo: name, language, category (marketing / utility / authentication) e components (ao menos um). channelId é opcional — só necessário se o tenant tem mais de um número oficial. A resposta 201 traz o template em status: "pending" (em revisão na plataforma oficial).
curl -X POST https://api.grwthy.com/v1/templates \
-H "Authorization: Bearer $WABROKER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "confirmacao_pedido",
"language": "pt_BR",
"category": "utility",
"components": [
{ "type": "body", "text": "Olá {{1}}, seu pedido {{2}} foi confirmado.",
"example": ["Ana", "1234"] },
{ "type": "footer", "text": "Equipe Loja" }
]
}'Resposta 201
{
"category": "utility",
"channelId": "ch_9f2c8a1b0d3e4f50",
"components": [
{
"example": {
"body_text": [
[
"John"
]
]
},
"text": "Hi {{1}}",
"type": "BODY"
}
],
"createdAt": "2026-08-04T12:00:00.000Z",
"id": "tpl_5a1c3e7f9b2d4068",
"language": "en_US",
"metaTemplateId": "meta-777",
"name": "welcome",
"rejectedReason": null,
"status": "pending",
"updatedAt": "2026-08-04T12:00:00.000Z"
}Tipos de componente aceitos: header (formato text com text/example, ou image/video/document com mediaUrl/handle), body (text, example?), footer (text) e buttons (lista de QUICK_REPLY/URL/PHONE_NUMBER/COPY_CODE).
Aprovação é assíncrona
status: "pending". A aprovação ou rejeição chega depois pelo evento template.updated no webhook — ou puxando por sync.Listar
Paginado por cursor; filtre por ?status= (ex.: approved, pending, rejected). Siga nextCursor em ?cursor=.
curl "https://api.grwthy.com/v1/templates?status=approved&limit=50" \
-H "Authorization: Bearer $WABROKER_API_KEY"Resposta 200
{
"items": [
{
"category": "utility",
"channelId": "ch_9f2c8a1b0d3e4f50",
"components": [
{
"example": {
"body_text": [
[
"John"
]
]
},
"text": "Hi {{1}}",
"type": "BODY"
}
],
"createdAt": "2026-08-04T12:00:00.000Z",
"id": "tpl_5a1c3e7f9b2d4068",
"language": "en_US",
"metaTemplateId": "meta-777",
"name": "welcome",
"rejectedReason": null,
"status": "pending",
"updatedAt": "2026-08-04T12:00:00.000Z"
}
],
"nextCursor": null
}Ler um template (GET /v1/templates/:id) devolve a mesma view de um item da listagem.
Resposta 200
{
"category": "utility",
"channelId": "ch_9f2c8a1b0d3e4f50",
"components": [
{
"example": {
"body_text": [
[
"John"
]
]
},
"text": "Hi {{1}}",
"type": "BODY"
}
],
"createdAt": "2026-08-04T12:00:00.000Z",
"id": "tpl_5a1c3e7f9b2d4068",
"language": "en_US",
"metaTemplateId": "meta-777",
"name": "welcome",
"rejectedReason": null,
"status": "pending",
"updatedAt": "2026-08-04T12:00:00.000Z"
}Editar
A plataforma oficial só edita templates APPROVED ou REJECTED — um pending ou nunca submetido responde 409 template_not_editable. Só category (opcional) e components mudam; name/language são imutáveis (ignorados se enviados). A edição volta o template a pending.
curl -X PATCH https://api.grwthy.com/v1/templates/tpl_abc123 \
-H "Authorization: Bearer $WABROKER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"components": [
{ "type": "body", "text": "Olá {{1}}, seu pedido {{2}} está a caminho.",
"example": ["Ana", "1234"] }
]
}'Resposta 200
{
"category": "marketing",
"channelId": "ch_9f2c8a1b0d3e4f50",
"components": [
{
"example": {
"body_text": [
[
"Jane"
]
]
},
"text": "Hi again {{1}}",
"type": "BODY"
}
],
"createdAt": "2026-08-04T12:00:00.000Z",
"id": "tpl_5a1c3e7f9b2d4068",
"language": "en_US",
"metaTemplateId": "meta-777",
"name": "welcome",
"rejectedReason": null,
"status": "pending",
"updatedAt": "2026-08-04T12:00:00.000Z"
}Sincronizar e apagar
# Sync — relê os templates da plataforma oficial e reconcilia o estado local
curl -X POST https://api.grwthy.com/v1/templates/sync \
-H "Authorization: Bearer $WABROKER_API_KEY"
# Apagar — remove na plataforma oficial e faz soft-delete local
curl -X DELETE https://api.grwthy.com/v1/templates/tpl_abc123 \
-H "Authorization: Bearer $WABROKER_API_KEY"O sync devolve as contagens do que reconciliou; o delete devolve o template já em status: "deleted".
Resposta 200
{
"created": 0,
"synced": 1,
"updated": 1
}Resposta 200
{
"category": "utility",
"channelId": "ch_9f2c8a1b0d3e4f50",
"components": [
{
"example": {
"body_text": [
[
"John"
]
]
},
"text": "Hi {{1}}",
"type": "BODY"
}
],
"createdAt": "2026-08-04T12:00:00.000Z",
"id": "tpl_5a1c3e7f9b2d4068",
"language": "en_US",
"metaTemplateId": "meta-777",
"name": "welcome",
"rejectedReason": null,
"status": "deleted",
"updatedAt": "2026-08-04T12:00:00.000Z"
}- Template de outro tenant (ou inexistente):
404 template_not_found, nunca403. - Um tenant sem nenhum número oficial recebe
422 unsupported_capability— não há WABA onde submeter. - As escritas (create/edit/delete/sync) têm rate limit por tenant — o excedente é
429 rate_limitedcomretryAfter.