Bandmaster docs

Enviar mensagens

O envio — host, autenticação, todos os tipos de mensagem e os erros.

O envio tem host próprio: message.2bebandmaster.com.br. Tudo o mais (login, número, templates) fica em admin.2bebandmaster.com.br.

A chamada

Uma rota só, para todos os tipos:

POST https://message.2bebandmaster.com.br/message/
authorization: Bearer <token>
identifier: <identifier-do-numero>
content-type: application/json

O token diz qual empresa envia; o identifier diz de qual número a mensagem sai. Os dois headers são obrigatórios.

O envio é assíncrono

A resposta 200 significa aceito e enfileirado, não entregue. Ela devolve um message_id; o que aconteceu de fato com a mensagem chega depois no seu webhook de status — e uma falha, no webhook de falha de envio.

enviar um texto

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
curl -X POST https://message.2bebandmaster.com.br/message/ \
-H "authorization: Bearer $TOKEN" \
-H "identifier: $IDENTIFIER" \
-H "content-type: application/json" \
-d '{
  "to": "558899442560",
  "type": "text",
  "text": "Olá! Como posso ajudá-lo?"
}'
Bandmaster200 OK✓✓
{
"index": 0,
"message": "To search your message later, use this ID",
"message_id": "6650f2a1b3c4d5e6f7a8b9c0"
}

Guarde o message_id: é por ele que os webhooks de status se referem a esta mensagem.

O envelope

Todo corpo tem a mesma base:

CampoObrigatórioObservação
typesimqual dos tipos abaixo
tosim¹número do destinatário, só dígitos, sem + — ou um BSUID (BR.17293847...)
phoneforma legada de informar o destinatário; prefira to

¹ exceto no tipo typing, que endereça pelo message_id da mensagem recebida.

identifier, chave do broker e URL de webhook são preenchidos pelo servidor — nunca os mande no corpo.

Enviar para um BSUID

Quando o cliente usa nome de usuário, você pode não ter o telefone dele — só o BSUID (o que é). Envie do mesmo jeito: o BSUID vai no campo to, no lugar do número.

texto para um BSUID

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "BR.1729384756102938",
"type": "text",
"text": "Olá! Recebemos seu pedido."
}
Bandmaster200 OK✓✓

aceito e enfileirado

Vale para todos os tipos desta página — texto, mídia, interativas, template — com uma exceção:

Template de autenticação não vai para BSUID

Um template de categoria AUTHENTICATION enviado a um BSUID é recusado: a Meta exige o telefone para esse tipo de template. Como a recusa acontece depois do enfileiramento, a chamada de envio ainda responde 200 — o erro chega no seu webhook de erro de template, com o título "Authentication template cannot be sent to a BSUID".

Precisa mandar um código de verificação a quem só tem BSUID? Peça antes o telefone com request_contact_info.

Tipos de mensagem

text

Texto puro. O campo text é uma string, não um objeto.

text

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "text",
"text": "Olá! Como posso ajudá-lo?"
}
Bandmaster200 OK✓✓

aceito e enfileirado — message_id na resposta

image

image

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "image",
"link": "https://ex.com/produto.jpg",
"caption": "Nosso produto"
}
Bandmaster200 OK✓✓

aceito e enfileirado

video

video

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "video",
"link": "https://ex.com/tutorial.mp4",
"caption": "Tutorial"
}
Bandmaster200 OK✓✓

aceito e enfileirado

audio

O caption é aceito pelo schema mas descartado no envio — áudio vai sem legenda.

audio

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "audio",
"link": "https://ex.com/welcome.mp3"
}
Bandmaster200 OK✓✓

aceito e enfileirado

document

document

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "document",
"link": "https://ex.com/catalogo.pdf",
"caption": "Catálogo 2025",
"filename": "catalogo-2025.pdf"
}
Bandmaster200 OK✓✓

aceito e enfileirado

sticker

Sem legenda.

sticker

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "sticker",
"link": "https://ex.com/thumbs-up.webp"
}
Bandmaster200 OK✓✓

aceito e enfileirado

Mídia é sempre por URL

image, video, audio, document e sticker aceitam apenas link — uma URL pública que o WhatsApp baixa. Não existe upload de mídia nem envio por id/handle. (O handle de POST /template/media-handle serve só para o header de um template, não para estes tipos.)

location

Atenção: latitude e longitude são strings. Os quatro campos são obrigatórios.

location

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "location",
"location": {
  "longitude": "-46.6333824",
  "latitude": "-23.5505199",
  "name": "Shopping ABC",
  "address": "Av. Paulista, 1000, São Paulo - SP"
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

contacts

name e phones são obrigatórios em cada contato; emails é opcional.

contacts

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "contacts",
"contacts": [
  {
    "name": {
      "first_name": "João",
      "last_name": "Silva",
      "formatted_name": "João Silva"
    },
    "phones": [
      { "phone": "+5511999998888", "type": "WORK", "wa_id": "5511999998888" }
    ],
    "emails": [{ "email": "joao@empresa.com", "type": "WORK" }]
  }
]
}
Bandmaster200 OK✓✓

aceito e enfileirado

template

Para iniciar uma conversa. Você manda o template_id e, se o template tiver variáveis, os components.

template_id é o id, não o nome

O template_id é o ObjectId de 24 caracteres hexadecimais do template no Bandmaster — obtido em GET /template. Mandar o nome do template resulta em 400. Nome, idioma e namespace são resolvidos pelo servidor a partir do id.

template com header de imagem, corpo e botão

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "template",
"template_id": "6650f2a1b3c4d5e6f7a8b9c0",
"components": [
  {
    "type": "header",
    "parameters": [
      { "type": "image", "image": { "link": "https://ex.com/h.jpg" } }
    ]
  },
  {
    "type": "body",
    "parameters": [
      { "type": "text", "text": "João" },
      { "type": "text", "text": "123456" }
    ]
  },
  {
    "type": "button",
    "sub_type": "url",
    "index": "0",
    "parameters": [{ "type": "text", "text": "order/12345" }]
  }
]
}
Bandmaster200 OK✓✓

aceito e enfileirado

Só um template aprovado pode ser enviado — veja enviar templates. Um template_id que não existe, ou um template de categoria AUTHENTICATION enviado a um BSUID, viram um webhook de erro de template.

interactive

Um interactive com interactive.type decidindo o formato. São sete:

interactive.typePara quê
buttonaté 3 botões de resposta rápida
listmenu com seções e linhas
productum produto do catálogo
product_listvários produtos, em seções
order_detailscobrança (WhatsApp Pay: pix, boleto ou link)
order_statusatualizar o status de um pedido cobrado
request_contact_infopedir o telefone a um usuário BSUID

button

interactive · button

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "interactive",
"interactive": {
  "type": "button",
  "body": { "text": "Deseja continuar?" },
  "action": {
    "buttons": [
      { "type": "reply", "reply": { "id": "yes", "title": "Sim" } },
      { "type": "reply", "reply": { "id": "no", "title": "Não" } }
    ]
  }
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

A resposta do cliente chega no seu webhook de mensagem, com o id do botão que ele tocou.

list

interactive · list

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "interactive",
"interactive": {
  "type": "list",
  "body": { "text": "Selecione uma categoria:" },
  "action": {
    "button": "Ver opções",
    "sections": [
      {
        "title": "Produtos",
        "rows": [
          {
            "id": "prod_1",
            "title": "Eletrônicos",
            "description": "Smartphones, notebooks"
          },
          { "id": "prod_2", "title": "Roupas" }
        ]
      }
    ]
  }
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

product e product_list

product mostra um item do catálogo; product_list, vários agrupados em seções. Os dois exigem o catalog_id.

interactive · product_list

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "interactive",
"interactive": {
  "type": "product_list",
  "header": { "type": "text", "text": "Ofertas da semana" },
  "body": { "text": "Escolha um produto:" },
  "action": {
    "catalog_id": "1234567890",
    "sections": [
      {
        "title": "Eletrônicos",
        "product_items": [{ "product_retailer_id": "SKU-001" }]
      }
    ]
  }
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

order_details

Cobrança pelo WhatsApp Pay (Brasil). O action.name é sempre review_and_pay, o payment_type é br e a moeda, BRL. O pagamento pode ser pix (pix_dynamic_code), boleto (digitable_line) ou link (payment_link) — de um a dois métodos por cobrança.

Valores são inteiros com offset: 100 (centavos: 19990 = R$ 199,90), e vale a regra: total = subtotal + taxa + frete − desconto.

interactive · order_details (pix)

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "interactive",
"interactive": {
  "type": "order_details",
  "body": { "text": "Confira seu pedido e pague:" },
  "action": {
    "name": "review_and_pay",
    "parameters": {
      "reference_id": "pedido-12345",
      "type": "physical-goods",
      "payment_type": "br",
      "currency": "BRL",
      "payment_settings": [
        {
          "type": "pix_dynamic_code",
          "pix_dynamic_code": {
            "code": "00020126...5204000053039865802BR",
            "merchant_name": "Loja ABC",
            "key": "12345678000199",
            "key_type": "CNPJ"
          }
        }
      ],
      "total_amount": { "value": 19990, "offset": 100 },
      "order": {
        "status": "pending",
        "items": [
          {
            "retailer_id": "SKU-001",
            "name": "Fone de ouvido",
            "amount": { "value": 17990, "offset": 100 },
            "quantity": 1
          }
        ],
        "subtotal": { "value": 17990, "offset": 100 },
        "tax": { "value": 2000, "offset": 100, "description": "Impostos" }
      }
    }
  }
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

order_status

Atualiza o pedido cobrado. action.name é review_order, e o order.status é um de: pending, processing, partially_shipped, shipped, completed, canceled.

interactive · order_status

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "interactive",
"interactive": {
  "type": "order_status",
  "body": { "text": "Seu pedido foi enviado!" },
  "action": {
    "name": "review_order",
    "parameters": {
      "reference_id": "pedido-12345",
      "order": { "status": "shipped", "description": "A caminho" }
    }
  }
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

request_contact_info

Pede o telefone a um usuário identificado por BSUID.

interactive · request_contact_info

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "BR.1729384756102938",
"type": "interactive",
"interactive": {
  "type": "request_contact_info",
  "body": { "text": "Podemos falar com você por telefone?" },
  "action": { "name": "request_contact_info" }
}
}
Bandmaster200 OK✓✓

aceito e enfileirado

typing

O único tipo sem destinatário: ele responde a uma mensagem recebida, endereçado pelo message_id dela (o wamid que veio no webhook). Marca a mensagem como lida e mostra "digitando…".

typing

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"type": "typing",
"message_id": "wamid.HBgNNTUxMTk4ODg4Nzc3Nx...",
"typing_indicator": { "type": "text" }
}
Bandmaster200 OK✓✓

aceito e enfileirado

Enviar várias de uma vez

Mande um objeto com batch: uma lista de mensagens completas, de tipos diferentes se quiser. A resposta é uma lista, na ordem enviada.

Recomendamos até 10 mensagens por lote — o limite não é imposto pela API, mas lotes grandes demoram mais para serem aceitos e não trazem ganho de entrega.

batch

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"batch": [
  { "to": "558899442560", "type": "text", "text": "Olá!" },
  {
    "to": "5511999998888",
    "type": "image",
    "link": "https://ex.com/produto.jpg",
    "caption": "Nosso produto"
  }
]
}
Bandmaster200 OK✓✓
[
{
  "index": 0,
  "message": "To search your message later, use this ID",
  "message_id": "6650f2a1b3c4d5e6f7a8b9c0"
},
{
  "index": 1,
  "message": "To search your message later, use this ID",
  "message_id": "6650f2a1b3c4d5e6f7a8b9c1"
}
]

Erros

Falha de validação do corpo responde HTTP 422:

corpo inválido — falta o campo do tipo

VocêPOST/message/
headers
authorization:
Bearer <token>
identifier:
<identifier-do-numero>
{
"to": "558899442560",
"type": "text"
}
Bandmaster422 Unprocessable Content
{
"status": 400,
"message": "Erro de validação na mensagem",
"errors": [
  {
    "path": "body",
    "message": "O formato da mensagem não corresponde ao tipo \"text\". Verifique os campos obrigatórios na documentação."
  }
]
}

O status HTTP e o campo status do corpo não batem

Numa falha de validação, o HTTP é 422 e o campo status dentro do corpo vale 400. É assim que a API responde hoje. Confie no código HTTP, não no campo do corpo.

Tabela completa, pelo código HTTP:

HTTPQuando
422validação do corpo (campo obrigatório faltando, tipo inválido, formato que não corresponde a nenhum tipo) e também header authorization ou identifier ausente
400destinatário inválido, template_id que não é um ObjectId de 24 hex, identifier sem número correspondente na sua empresa, ou a fila recusando a mensagem
401token mal formado, inválido ou expirado
500erro nosso

Erros de validação (422) trazem errors[]. Quando a mensagem não corresponde a nenhum tipo válido — o caso mais comum, um campo obrigatório faltando — a lista vem com uma única entrada de nível de corpo (path: "body"), apontando o tipo que você declarou; ela não enumera campo a campo. Os demais erros trazem { success: false, message, status, exception_type }.

Não existe 429 neste endpoint: mensagens em excesso são enfileiradas, não recusadas.

Campos desconhecidos

Campos que não pertencem ao tipo não fazem a mensagem falhar — eles são simplesmente ignorados.

O que este endpoint não faz

  • Não responde a uma mensagem específica — não há campo de context/reply.
  • Não tem preview_url para links no texto.
  • Não envia reações nem fluxos (flow).
  • Não aceita mídia por upload — só URL.

Depois do envio

O envio termina no message_id. O resto da história chega nos webhooks: status a cada passo (enviado, entregue, lido) e falha de envio quando não dá certo.

Nesta página