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/jsonO 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
/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?"
}'{
"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:
| Campo | Obrigatório | Observação |
|---|---|---|
type | sim | qual dos tipos abaixo |
to | sim¹ | número do destinatário, só dígitos, sem + — ou um BSUID (BR.17293847...) |
phone | — | forma 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
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "BR.1729384756102938",
"type": "text",
"text": "Olá! Recebemos seu pedido."
}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
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "558899442560",
"type": "text",
"text": "Olá! Como posso ajudá-lo?"
}aceito e enfileirado — message_id na resposta
image
image
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "558899442560",
"type": "image",
"link": "https://ex.com/produto.jpg",
"caption": "Nosso produto"
}aceito e enfileirado
video
video
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "558899442560",
"type": "video",
"link": "https://ex.com/tutorial.mp4",
"caption": "Tutorial"
}aceito e enfileirado
audio
O caption é aceito pelo schema mas descartado no envio — áudio vai sem
legenda.
audio
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "558899442560",
"type": "audio",
"link": "https://ex.com/welcome.mp3"
}aceito e enfileirado
document
document
/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"
}aceito e enfileirado
sticker
Sem legenda.
sticker
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "558899442560",
"type": "sticker",
"link": "https://ex.com/thumbs-up.webp"
}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
/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"
}
}aceito e enfileirado
contacts
name e phones são obrigatórios em cada contato; emails é opcional.
contacts
/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" }]
}
]
}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
/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" }]
}
]
}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.type | Para quê |
|---|---|
button | até 3 botões de resposta rápida |
list | menu com seções e linhas |
product | um produto do catálogo |
product_list | vários produtos, em seções |
order_details | cobrança (WhatsApp Pay: pix, boleto ou link) |
order_status | atualizar o status de um pedido cobrado |
request_contact_info | pedir o telefone a um usuário BSUID |
button
interactive · button
/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" } }
]
}
}
}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
/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" }
]
}
]
}
}
}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
/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" }]
}
]
}
}
}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)
/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" }
}
}
}
}
}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
/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" }
}
}
}
}aceito e enfileirado
request_contact_info
Pede o telefone a um usuário identificado por BSUID.
interactive · request_contact_info
/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" }
}
}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
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"type": "typing",
"message_id": "wamid.HBgNNTUxMTk4ODg4Nzc3Nx...",
"typing_indicator": { "type": "text" }
}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
/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"
}
]
}[
{
"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
/message/›headers
- authorization:
- Bearer <token>
- identifier:
- <identifier-do-numero>
{
"to": "558899442560",
"type": "text"
}{
"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:
| HTTP | Quando |
|---|---|
| 422 | validaçã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 |
| 400 | destinatá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 |
| 401 | token mal formado, inválido ou expirado |
| 500 | erro 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_urlpara 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.