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

# Enviar mensagens com WABA

> Como enviar texto, mídia, botões e templates por uma instância oficial (WABA) usando a API da Zapster

Este guia mostra como enviar mensagens por uma instância oficial (WABA). O endpoint é o mesmo das instâncias não oficiais, `POST /v1/wa/messages`, com a mesma assinatura de requisição. A Zapster converte o seu payload para o formato da Cloud API da Meta automaticamente.

## Antes de começar

1. Você precisa de uma [instância WABA conectada](/pt-BR/v1/guides/connect-waba-instance).
2. Mensagens livres (texto, mídia, botões) só são entregues dentro da **janela de conversa de 24 horas**, que abre quando o cliente manda mensagem para o seu número. Fora da janela, use um **template** aprovado pela Meta.
3. Instâncias WABA não enviam para grupos. Se precisar de grupos, use uma instância não oficial. Veja o comparativo em [WABA vs não oficial](/pt-BR/v1/guides/waba-vs-unofficial).

Em todos os exemplos abaixo, troque `YOUR_API_TOKEN` pelo seu token de API e `YOUR_INSTANCE_ID` pelo ID da instância WABA.

<Note>
  As mensagens livres (texto, mídia e botões) enviadas por uma instância oficial são gratuitas até **30 de setembro de 2026**. A partir de **1 de outubro de 2026**, a Meta passa a cobrar por elas. Entenda o que muda na seção [Cobrança das mensagens em 2026](#cobrança-das-mensagens-em-2026), mais abaixo.
</Note>

## Texto simples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.zapsterapi.com/v1/wa/messages \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "X-Instance-ID: YOUR_INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient": "5511999999999",
      "text": "Olá! Seu pedido foi confirmado."
    }'
  ```

  ```javascript Node.js (axios) theme={null}
  const axios = require('axios')

  const response = await axios.post(
    'https://api.zapsterapi.com/v1/wa/messages',
    {
      recipient: '5511999999999',
      text: 'Olá! Seu pedido foi confirmado.',
    },
    {
      headers: {
        Authorization: 'Bearer YOUR_API_TOKEN',
        'X-Instance-ID': 'YOUR_INSTANCE_ID',
      },
    },
  )

  console.log(response.data.message_id)
  ```

  ```javascript Node.js (fetch) theme={null}
  const response = await fetch('https://api.zapsterapi.com/v1/wa/messages', {
    body: JSON.stringify({
      recipient: '5511999999999',
      text: 'Olá! Seu pedido foi confirmado.',
    }),
    headers: {
      Authorization: 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
      'X-Instance-ID': 'YOUR_INSTANCE_ID',
    },
    method: 'POST',
  })

  const data = await response.json()
  console.log(data.message_id)
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.zapsterapi.com/v1/wa/messages",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "X-Instance-ID": "YOUR_INSTANCE_ID",
      },
      json={
          "recipient": "5511999999999",
          "text": "Olá! Seu pedido foi confirmado.",
      },
  )

  print(response.json()["message_id"])
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"io"
  	"net/http"
  	"strings"
  )

  func main() {
  	body := strings.NewReader(`{
  		"recipient": "5511999999999",
  		"text": "Olá! Seu pedido foi confirmado."
  	}`)

  	req, _ := http.NewRequest("POST", "https://api.zapsterapi.com/v1/wa/messages", body)
  	req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  	req.Header.Set("X-Instance-ID", "YOUR_INSTANCE_ID")
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	defer res.Body.Close()

  	data, _ := io.ReadAll(res.Body)
  	fmt.Println(string(data))
  }
  ```
</CodeGroup>

## Mídia (imagem, vídeo ou documento)

Envie a mídia por URL pública ou base64 no campo `media`. O tipo (imagem, vídeo, documento) é detectado automaticamente a partir do arquivo. Para documentos, você pode informar `fileName` para controlar o nome exibido no WhatsApp.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.zapsterapi.com/v1/wa/messages \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "X-Instance-ID: YOUR_INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient": "5511999999999",
      "media": {
        "url": "https://exemplo.com/imagem.jpg",
        "caption": "Confira o catálogo de julho"
      }
    }'
  ```

  ```javascript Node.js (axios) theme={null}
  const axios = require('axios')

  await axios.post(
    'https://api.zapsterapi.com/v1/wa/messages',
    {
      media: {
        caption: 'Confira o catálogo de julho',
        url: 'https://exemplo.com/imagem.jpg',
      },
      recipient: '5511999999999',
    },
    {
      headers: {
        Authorization: 'Bearer YOUR_API_TOKEN',
        'X-Instance-ID': 'YOUR_INSTANCE_ID',
      },
    },
  )
  ```

  ```javascript Node.js (fetch) theme={null}
  await fetch('https://api.zapsterapi.com/v1/wa/messages', {
    body: JSON.stringify({
      media: {
        caption: 'Confira o catálogo de julho',
        url: 'https://exemplo.com/imagem.jpg',
      },
      recipient: '5511999999999',
    }),
    headers: {
      Authorization: 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
      'X-Instance-ID': 'YOUR_INSTANCE_ID',
    },
    method: 'POST',
  })
  ```

  ```python Python theme={null}
  import requests

  requests.post(
      "https://api.zapsterapi.com/v1/wa/messages",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "X-Instance-ID": "YOUR_INSTANCE_ID",
      },
      json={
          "recipient": "5511999999999",
          "media": {
              "url": "https://exemplo.com/imagem.jpg",
              "caption": "Confira o catálogo de julho",
          },
      },
  )
  ```

  ```go Go theme={null}
  package main

  import (
  	"net/http"
  	"strings"
  )

  func main() {
  	body := strings.NewReader(`{
  		"recipient": "5511999999999",
  		"media": {
  			"url": "https://exemplo.com/imagem.jpg",
  			"caption": "Confira o catálogo de julho"
  		}
  	}`)

  	req, _ := http.NewRequest("POST", "https://api.zapsterapi.com/v1/wa/messages", body)
  	req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  	req.Header.Set("X-Instance-ID", "YOUR_INSTANCE_ID")
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	res.Body.Close()
  }
  ```
</CodeGroup>

Para enviar vídeo ou documento, basta trocar a URL. Exemplo de documento com nome de arquivo:

```json theme={null}
{
  "recipient": "5511999999999",
  "media": {
    "url": "https://exemplo.com/contrato.pdf",
    "fileName": "contrato.pdf",
    "caption": "Segue o contrato para assinatura"
  }
}
```

## Botões interativos

Em WABA, botões viram mensagens interativas da Cloud API e seguem as regras da Meta: até 3 botões `reply`, ou exatamente 1 botão `url`, sem misturar os dois tipos. Botões `call` e `copyable` não existem em mensagem de sessão (veja [Erros comuns](#erros-comuns)). A matriz completa está em [Mensagem com botões](/pt-BR/v1/guides/messages-with-buttons).

Quando você envia `media` junto com botões, a mídia vira o cabeçalho da mensagem interativa (imagem, vídeo ou documento; áudio não é suportado). Se enviar `media.caption` e `text` juntos, o `caption` tem prioridade e vira o corpo da mensagem.

### Botões de resposta rápida (reply) com imagem

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.zapsterapi.com/v1/wa/messages \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "X-Instance-ID: YOUR_INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient": "5511999999999",
      "text": "Deseja confirmar o agendamento de amanhã?",
      "media": {
        "url": "https://exemplo.com/clinica.jpg"
      },
      "buttons": [
        { "id": "confirm", "label": "Confirmar", "type": "reply" },
        { "id": "reschedule", "label": "Remarcar", "type": "reply" },
        { "id": "cancel", "label": "Cancelar", "type": "reply" }
      ]
    }'
  ```

  ```javascript Node.js (axios) theme={null}
  const axios = require('axios')

  await axios.post(
    'https://api.zapsterapi.com/v1/wa/messages',
    {
      buttons: [
        { id: 'confirm', label: 'Confirmar', type: 'reply' },
        { id: 'reschedule', label: 'Remarcar', type: 'reply' },
        { id: 'cancel', label: 'Cancelar', type: 'reply' },
      ],
      media: { url: 'https://exemplo.com/clinica.jpg' },
      recipient: '5511999999999',
      text: 'Deseja confirmar o agendamento de amanhã?',
    },
    {
      headers: {
        Authorization: 'Bearer YOUR_API_TOKEN',
        'X-Instance-ID': 'YOUR_INSTANCE_ID',
      },
    },
  )
  ```

  ```javascript Node.js (fetch) theme={null}
  await fetch('https://api.zapsterapi.com/v1/wa/messages', {
    body: JSON.stringify({
      buttons: [
        { id: 'confirm', label: 'Confirmar', type: 'reply' },
        { id: 'reschedule', label: 'Remarcar', type: 'reply' },
        { id: 'cancel', label: 'Cancelar', type: 'reply' },
      ],
      media: { url: 'https://exemplo.com/clinica.jpg' },
      recipient: '5511999999999',
      text: 'Deseja confirmar o agendamento de amanhã?',
    }),
    headers: {
      Authorization: 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
      'X-Instance-ID': 'YOUR_INSTANCE_ID',
    },
    method: 'POST',
  })
  ```

  ```python Python theme={null}
  import requests

  requests.post(
      "https://api.zapsterapi.com/v1/wa/messages",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "X-Instance-ID": "YOUR_INSTANCE_ID",
      },
      json={
          "recipient": "5511999999999",
          "text": "Deseja confirmar o agendamento de amanhã?",
          "media": {"url": "https://exemplo.com/clinica.jpg"},
          "buttons": [
              {"id": "confirm", "label": "Confirmar", "type": "reply"},
              {"id": "reschedule", "label": "Remarcar", "type": "reply"},
              {"id": "cancel", "label": "Cancelar", "type": "reply"},
          ],
      },
  )
  ```

  ```go Go theme={null}
  package main

  import (
  	"net/http"
  	"strings"
  )

  func main() {
  	body := strings.NewReader(`{
  		"recipient": "5511999999999",
  		"text": "Deseja confirmar o agendamento de amanhã?",
  		"media": { "url": "https://exemplo.com/clinica.jpg" },
  		"buttons": [
  			{ "id": "confirm", "label": "Confirmar", "type": "reply" },
  			{ "id": "reschedule", "label": "Remarcar", "type": "reply" },
  			{ "id": "cancel", "label": "Cancelar", "type": "reply" }
  		]
  	}`)

  	req, _ := http.NewRequest("POST", "https://api.zapsterapi.com/v1/wa/messages", body)
  	req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  	req.Header.Set("X-Instance-ID", "YOUR_INSTANCE_ID")
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	res.Body.Close()
  }
  ```
</CodeGroup>

### Botão de link (url) com imagem

Lembre: em WABA só pode existir 1 botão `url` na mensagem, e ele não pode ser combinado com botões `reply`.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.zapsterapi.com/v1/wa/messages \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "X-Instance-ID: YOUR_INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient": "5511999999999",
      "text": "Seu boleto de julho está disponível.",
      "media": {
        "url": "https://exemplo.com/fatura.jpg"
      },
      "buttons": [
        {
          "label": "Ver boleto",
          "type": "url",
          "url": "https://exemplo.com/boleto/123"
        }
      ]
    }'
  ```

  ```javascript Node.js (axios) theme={null}
  const axios = require('axios')

  await axios.post(
    'https://api.zapsterapi.com/v1/wa/messages',
    {
      buttons: [
        {
          label: 'Ver boleto',
          type: 'url',
          url: 'https://exemplo.com/boleto/123',
        },
      ],
      media: { url: 'https://exemplo.com/fatura.jpg' },
      recipient: '5511999999999',
      text: 'Seu boleto de julho está disponível.',
    },
    {
      headers: {
        Authorization: 'Bearer YOUR_API_TOKEN',
        'X-Instance-ID': 'YOUR_INSTANCE_ID',
      },
    },
  )
  ```

  ```javascript Node.js (fetch) theme={null}
  await fetch('https://api.zapsterapi.com/v1/wa/messages', {
    body: JSON.stringify({
      buttons: [
        {
          label: 'Ver boleto',
          type: 'url',
          url: 'https://exemplo.com/boleto/123',
        },
      ],
      media: { url: 'https://exemplo.com/fatura.jpg' },
      recipient: '5511999999999',
      text: 'Seu boleto de julho está disponível.',
    }),
    headers: {
      Authorization: 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
      'X-Instance-ID': 'YOUR_INSTANCE_ID',
    },
    method: 'POST',
  })
  ```

  ```python Python theme={null}
  import requests

  requests.post(
      "https://api.zapsterapi.com/v1/wa/messages",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "X-Instance-ID": "YOUR_INSTANCE_ID",
      },
      json={
          "recipient": "5511999999999",
          "text": "Seu boleto de julho está disponível.",
          "media": {"url": "https://exemplo.com/fatura.jpg"},
          "buttons": [
              {
                  "label": "Ver boleto",
                  "type": "url",
                  "url": "https://exemplo.com/boleto/123",
              }
          ],
      },
  )
  ```

  ```go Go theme={null}
  package main

  import (
  	"net/http"
  	"strings"
  )

  func main() {
  	body := strings.NewReader(`{
  		"recipient": "5511999999999",
  		"text": "Seu boleto de julho está disponível.",
  		"media": { "url": "https://exemplo.com/fatura.jpg" },
  		"buttons": [
  			{ "label": "Ver boleto", "type": "url", "url": "https://exemplo.com/boleto/123" }
  		]
  	}`)

  	req, _ := http.NewRequest("POST", "https://api.zapsterapi.com/v1/wa/messages", body)
  	req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  	req.Header.Set("X-Instance-ID", "YOUR_INSTANCE_ID")
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	res.Body.Close()
  }
  ```
</CodeGroup>

## Template (fora da janela de 24h)

Templates precisam ser criados e aprovados na Meta antes do envio. O campo `template` é mutuamente exclusivo com `text` e `media`.

<Info>
  O objeto `template` é um **espelho do formato da Meta**. A Zapster embrulha apenas `name` e `language` (que vira `{ "code": ... }`) e repassa o array `components` exatamente como você o envia para a Cloud API, sem reinterpretar. Por isso, use o mesmo formato da documentação de templates da Cloud API da Meta.
</Info>

O `components` descreve as partes do template que recebem valores no envio:

* **`header`**: cabeçalho com mídia (imagem, vídeo ou documento) ou com uma variável de texto.
* **`body`**: o corpo, onde entram as variáveis do texto aprovado.
* **`button`**: os botões que têm valor dinâmico, como o `payload` de uma resposta rápida ou o sufixo de uma URL.

As variáveis do template podem ser **posicionais** (`{{1}}`, `{{2}}`, preenchidas pela ordem do array `parameters`) ou **nomeadas** (`{{customer_name}}`, preenchidas por `parameter_name`). Cada template usa um estilo ou o outro, nunca os dois juntos. Os valores enviados precisam corresponder ao que o template aprovado espera.

### Exemplo simples (variável posicional)

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.zapsterapi.com/v1/wa/messages \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "X-Instance-ID: YOUR_INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient": "5511999999999",
      "template": {
        "name": "confirmacao_pedido",
        "language": "pt_BR",
        "components": [
          {
            "type": "body",
            "parameters": [
              { "type": "text", "text": "João" }
            ]
          }
        ]
      }
    }'
  ```

  ```javascript Node.js (axios) theme={null}
  const axios = require('axios')

  await axios.post(
    'https://api.zapsterapi.com/v1/wa/messages',
    {
      recipient: '5511999999999',
      template: {
        components: [
          {
            parameters: [{ text: 'João', type: 'text' }],
            type: 'body',
          },
        ],
        language: 'pt_BR',
        name: 'confirmacao_pedido',
      },
    },
    {
      headers: {
        Authorization: 'Bearer YOUR_API_TOKEN',
        'X-Instance-ID': 'YOUR_INSTANCE_ID',
      },
    },
  )
  ```

  ```javascript Node.js (fetch) theme={null}
  await fetch('https://api.zapsterapi.com/v1/wa/messages', {
    body: JSON.stringify({
      recipient: '5511999999999',
      template: {
        components: [
          {
            parameters: [{ text: 'João', type: 'text' }],
            type: 'body',
          },
        ],
        language: 'pt_BR',
        name: 'confirmacao_pedido',
      },
    }),
    headers: {
      Authorization: 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
      'X-Instance-ID': 'YOUR_INSTANCE_ID',
    },
    method: 'POST',
  })
  ```

  ```python Python theme={null}
  import requests

  requests.post(
      "https://api.zapsterapi.com/v1/wa/messages",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "X-Instance-ID": "YOUR_INSTANCE_ID",
      },
      json={
          "recipient": "5511999999999",
          "template": {
              "name": "confirmacao_pedido",
              "language": "pt_BR",
              "components": [
                  {
                      "type": "body",
                      "parameters": [{"type": "text", "text": "João"}],
                  }
              ],
          },
      },
  )
  ```

  ```go Go theme={null}
  package main

  import (
  	"net/http"
  	"strings"
  )

  func main() {
  	body := strings.NewReader(`{
  		"recipient": "5511999999999",
  		"template": {
  			"name": "confirmacao_pedido",
  			"language": "pt_BR",
  			"components": [
  				{
  					"type": "body",
  					"parameters": [{ "type": "text", "text": "João" }]
  				}
  			]
  		}
  	}`)

  	req, _ := http.NewRequest("POST", "https://api.zapsterapi.com/v1/wa/messages", body)
  	req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  	req.Header.Set("X-Instance-ID", "YOUR_INSTANCE_ID")
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	res.Body.Close()
  }
  ```
</CodeGroup>

### Com header, variáveis posicionais e botões

Este template tem cabeçalho de imagem, duas variáveis posicionais no corpo (`{{1}}` e `{{2}}`) e dois botões: um de resposta rápida (com `payload`) e um de URL dinâmica (o texto vira o sufixo anexado à URL base do template). O `index` do botão segue a ordem em que ele aparece no template aprovado.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.zapsterapi.com/v1/wa/messages \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "X-Instance-ID: YOUR_INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient": "5511999999999",
      "template": {
        "name": "pedido_enviado",
        "language": "pt_BR",
        "components": [
          {
            "type": "header",
            "parameters": [
              { "type": "image", "image": { "link": "https://exemplo.com/banner.jpg" } }
            ]
          },
          {
            "type": "body",
            "parameters": [
              { "type": "text", "text": "João" },
              { "type": "text", "text": "#1234" }
            ]
          },
          {
            "type": "button",
            "sub_type": "quick_reply",
            "index": 0,
            "parameters": [
              { "type": "payload", "payload": "RASTREAR_PEDIDO" }
            ]
          },
          {
            "type": "button",
            "sub_type": "url",
            "index": 1,
            "parameters": [
              { "type": "text", "text": "pedido/1234" }
            ]
          }
        ]
      }
    }'
  ```

  ```javascript Node.js (axios) theme={null}
  const axios = require('axios')

  await axios.post(
    'https://api.zapsterapi.com/v1/wa/messages',
    {
      recipient: '5511999999999',
      template: {
        components: [
          {
            parameters: [
              { image: { link: 'https://exemplo.com/banner.jpg' }, type: 'image' },
            ],
            type: 'header',
          },
          {
            parameters: [
              { text: 'João', type: 'text' },
              { text: '#1234', type: 'text' },
            ],
            type: 'body',
          },
          {
            index: 0,
            parameters: [{ payload: 'RASTREAR_PEDIDO', type: 'payload' }],
            sub_type: 'quick_reply',
            type: 'button',
          },
          {
            index: 1,
            parameters: [{ text: 'pedido/1234', type: 'text' }],
            sub_type: 'url',
            type: 'button',
          },
        ],
        language: 'pt_BR',
        name: 'pedido_enviado',
      },
    },
    {
      headers: {
        Authorization: 'Bearer YOUR_API_TOKEN',
        'X-Instance-ID': 'YOUR_INSTANCE_ID',
      },
    },
  )
  ```

  ```javascript Node.js (fetch) theme={null}
  await fetch('https://api.zapsterapi.com/v1/wa/messages', {
    body: JSON.stringify({
      recipient: '5511999999999',
      template: {
        components: [
          {
            parameters: [
              { image: { link: 'https://exemplo.com/banner.jpg' }, type: 'image' },
            ],
            type: 'header',
          },
          {
            parameters: [
              { text: 'João', type: 'text' },
              { text: '#1234', type: 'text' },
            ],
            type: 'body',
          },
          {
            index: 0,
            parameters: [{ payload: 'RASTREAR_PEDIDO', type: 'payload' }],
            sub_type: 'quick_reply',
            type: 'button',
          },
          {
            index: 1,
            parameters: [{ text: 'pedido/1234', type: 'text' }],
            sub_type: 'url',
            type: 'button',
          },
        ],
        language: 'pt_BR',
        name: 'pedido_enviado',
      },
    }),
    headers: {
      Authorization: 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
      'X-Instance-ID': 'YOUR_INSTANCE_ID',
    },
    method: 'POST',
  })
  ```

  ```python Python theme={null}
  import requests

  requests.post(
      "https://api.zapsterapi.com/v1/wa/messages",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "X-Instance-ID": "YOUR_INSTANCE_ID",
      },
      json={
          "recipient": "5511999999999",
          "template": {
              "name": "pedido_enviado",
              "language": "pt_BR",
              "components": [
                  {
                      "type": "header",
                      "parameters": [
                          {"type": "image", "image": {"link": "https://exemplo.com/banner.jpg"}}
                      ],
                  },
                  {
                      "type": "body",
                      "parameters": [
                          {"type": "text", "text": "João"},
                          {"type": "text", "text": "#1234"},
                      ],
                  },
                  {
                      "type": "button",
                      "sub_type": "quick_reply",
                      "index": 0,
                      "parameters": [{"type": "payload", "payload": "RASTREAR_PEDIDO"}],
                  },
                  {
                      "type": "button",
                      "sub_type": "url",
                      "index": 1,
                      "parameters": [{"type": "text", "text": "pedido/1234"}],
                  },
              ],
          },
      },
  )
  ```

  ```go Go theme={null}
  package main

  import (
  	"net/http"
  	"strings"
  )

  func main() {
  	body := strings.NewReader(`{
  		"recipient": "5511999999999",
  		"template": {
  			"name": "pedido_enviado",
  			"language": "pt_BR",
  			"components": [
  				{
  					"type": "header",
  					"parameters": [
  						{ "type": "image", "image": { "link": "https://exemplo.com/banner.jpg" } }
  					]
  				},
  				{
  					"type": "body",
  					"parameters": [
  						{ "type": "text", "text": "João" },
  						{ "type": "text", "text": "#1234" }
  					]
  				},
  				{
  					"type": "button",
  					"sub_type": "quick_reply",
  					"index": 0,
  					"parameters": [{ "type": "payload", "payload": "RASTREAR_PEDIDO" }]
  				},
  				{
  					"type": "button",
  					"sub_type": "url",
  					"index": 1,
  					"parameters": [{ "type": "text", "text": "pedido/1234" }]
  				}
  			]
  		}
  	}`)

  	req, _ := http.NewRequest("POST", "https://api.zapsterapi.com/v1/wa/messages", body)
  	req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  	req.Header.Set("X-Instance-ID", "YOUR_INSTANCE_ID")
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	res.Body.Close()
  }
  ```
</CodeGroup>

### Variáveis nomeadas

Quando o template foi aprovado com variáveis nomeadas, cada parâmetro leva um `parameter_name` além de `type` e `text`. O restante da requisição (o `recipient`, os headers, o `name` e o `language`) é igual aos exemplos acima. Muda apenas o conteúdo de `components`:

```json components (variáveis nomeadas) theme={null}
[
  {
    "type": "header",
    "parameters": [
      { "type": "text", "parameter_name": "company_name", "text": "Zapster" }
    ]
  },
  {
    "type": "body",
    "parameters": [
      { "type": "text", "parameter_name": "customer_name", "text": "João" },
      { "type": "text", "parameter_name": "order_id", "text": "#1234" }
    ]
  }
]
```

<Note>
  Não misture variáveis posicionais e nomeadas no mesmo template. Use `parameter_name` apenas quando o template foi aprovado com variáveis nomeadas; caso contrário, use a forma posicional (só `type` e `text`, na ordem em que aparecem).
</Note>

## Cobrança das mensagens em 2026

O canal oficial do WhatsApp (WABA) é pago, e quem cobra pelas mensagens é a **Meta**, não a Zapster. São duas coisas separadas: a assinatura da sua instância na Zapster, de um lado, e o que a Meta cobra pelo envio das mensagens, do outro. A cobrança da Meta é feita através da conta de WhatsApp Business ligada ao seu número.

Em 2026 a Meta muda a forma de cobrar as mensagens livres, que são justamente as que você aprende a enviar neste guia. Esta seção resume, em português claro, o que a [documentação oficial da Meta](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing/non-template-messages) descreve de um jeito nem sempre fácil de entender.

### O que é uma "mensagem de serviço"

É toda mensagem livre (texto, mídia ou botões) que você envia em resposta a um cliente, dentro da janela de 24 horas. Pela definição da Meta, é qualquer mensagem que não seja um template. São exatamente as mensagens deste guia. Até hoje elas são **gratuitas**, assim desde novembro de 2024.

### O que muda e quando

| Data                     | O que passa a ser cobrado                                                                                                                                                                                                                                                                          |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1 de agosto de 2026**  | Mensagens do **Meta Business Agent** (respostas geradas pela inteligência artificial da Meta) passam a ser cobradas por token: US\$ 2,00 a cada 1 milhão de tokens, o que dá por volta de 4 a 5 centavos de dólar por mensagem. Isso só vale se você usar o agente de IA da Meta.                  |
| **1 de outubro de 2026** | As **mensagens de serviço** (as mensagens livres deste guia) passam a ser cobradas por mensagem enviada. Elas eram gratuitas desde novembro de 2024. No mesmo dia, mensagens de utilidade enviadas dentro da janela de 24 horas, gratuitas desde 1 de julho de 2025, também passam a ser cobradas. |

### Quanto vai custar

A Meta ainda não publicou os valores. Segundo a documentação, os preços que entram em vigor em 1 de outubro de 2026 serão anunciados **até 1 de setembro de 2026**. O preço de uma mensagem de serviço vai acompanhar o preço já usado para mensagens de utilidade e autenticação, que **varia conforme o país** do cliente. A Meta informou que não haverá desconto por volume para mensagens de serviço.

### O que continua igual

* A regra da janela de 24 horas não muda: mensagens livres só saem com a janela aberta. O que muda é que elas deixam de ser gratuitas.
* Os templates já eram pagos e seguem com a cobrança própria deles.
* Essa cobrança é só do canal **oficial** (WABA). Instâncias não oficiais (QR code) não passam por essa cobrança da Meta.

### Em resumo

Hoje, responder um cliente dentro da janela de 24 horas não custa nada. A partir de **1 de outubro de 2026**, cada uma dessas respostas passa a ter um custo cobrado pela Meta. Se você envia muitas mensagens de atendimento, vale acompanhar o anúncio de preços de setembro de 2026 e já incluir esse custo no seu planejamento.

<Info>
  Fonte: [WhatsApp Business Platform: Non-Template Messages Pricing](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing/non-template-messages), documentação oficial da Meta. As datas e os valores são definidos pela Meta e podem mudar.
</Info>

## Erros comuns

Quando o payload usa um recurso que a Cloud API não suporta, a Zapster rejeita a requisição na hora com um erro `400` explicando o motivo. Nada é descartado ou adaptado silenciosamente.

| Código                            | Quando acontece                                                             | Como resolver                                                                                                                                                          |
| --------------------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `waba_feature_not_supported`      | Botão `call` ou `copyable` em mensagem de sessão, ou áudio junto com botões | Para ligação, use um template com botão `PHONE_NUMBER`. Para copiar código, use um template de Marketing ou Authentication. Para áudio, envie em uma mensagem separada |
| `waba_invalid_button_combination` | Mistura de botão `url` com `reply`, ou mais de 1 botão `url`                | Envie 1 botão `url` sozinho, ou até 3 botões `reply`                                                                                                                   |
| `waba_conversation_window_closed` | Mensagem livre fora da janela de 24 horas                                   | Envie um template aprovado para reabrir a conversa                                                                                                                     |
| `waba_group_not_supported`        | `recipient` de grupo em instância WABA                                      | Grupos só funcionam em instâncias não oficiais                                                                                                                         |
| `waba_template_required`          | Campo `template` enviado para instância não oficial                         | Templates só existem em instâncias WABA                                                                                                                                |

## Próximos passos

* [Mensagem com botões](/pt-BR/v1/guides/messages-with-buttons) para a matriz completa de suporte por tipo de conexão
* [WABA vs não oficial](/pt-BR/v1/guides/waba-vs-unofficial) para escolher o tipo de instância
* [Conectando uma instância WABA](/pt-BR/v1/guides/connect-waba-instance)
