Seções

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étodopatho que faz
POST/v1/templatescria e submete um template à plataforma oficial
GET/v1/templateslista os templates (paginado, filtro por status)
GET/v1/templates/:idlê um template
PATCH/v1/templates/:idedita (só APPROVED/REJECTED)
DELETE/v1/templates/:idapaga (soft-delete + delete na plataforma oficial)
POST/v1/templates/syncreconcilia 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).

bash
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

json
{
  "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

O template nasce em 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=.

bash
curl "https://api.grwthy.com/v1/templates?status=approved&limit=50" \
  -H "Authorization: Bearer $WABROKER_API_KEY"

Resposta 200

json
{
  "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

json
{
  "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.

bash
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

json
{
  "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

bash
# 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

json
{
  "created": 0,
  "synced": 1,
  "updated": 1
}

Resposta 200

json
{
  "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, nunca 403.
  • 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_limited com retryAfter.