curl --request POST \
--url https://api-v2.manybot.com.br/messages/send-template \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"channelId": "clh1234567890",
"phone": "+5511999999999",
"templateName": "confirmacao_pedido",
"language": "pt_BR",
"params": {
"contact_first_name": "João",
"contact_email": "joao@email.com"
}
}
'{
"success": true,
"chatId": "clh0987654321",
"externalChatId": "5511999999999@s.whatsapp.net",
"message": "Template enviado com sucesso",
"wamid": "wamid.HBgNNTUxMTk5OTk5OTk5FQIAERgSQjYxNzc2..."
}{
"success": true,
"chatId": "clh0987654321",
"externalChatId": "5511999999999@s.whatsapp.net",
"message": "Template enviado com sucesso",
"wamid": "wamid.HBgNNTUxMTk5OTk5OTk5FQIAERgSQjYxNzc2..."
}{
"statusCode": 400,
"message": "Template \"meu_template\" não está aprovado (status: REJECTED)"
}{
"statusCode": 404,
"message": "Template \"meu_template\" (pt_BR) não encontrado"
}{
"statusCode": 409,
"error": "request_in_progress"
}Send Template
Envia um template aprovado na Meta. O backend busca a estrutura do template automaticamente e monta os parâmetros (components) a partir dos valores informados.
curl --request POST \
--url https://api-v2.manybot.com.br/messages/send-template \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"channelId": "clh1234567890",
"phone": "+5511999999999",
"templateName": "confirmacao_pedido",
"language": "pt_BR",
"params": {
"contact_first_name": "João",
"contact_email": "joao@email.com"
}
}
'{
"success": true,
"chatId": "clh0987654321",
"externalChatId": "5511999999999@s.whatsapp.net",
"message": "Template enviado com sucesso",
"wamid": "wamid.HBgNNTUxMTk5OTk5OTk5FQIAERgSQjYxNzc2..."
}{
"success": true,
"chatId": "clh0987654321",
"externalChatId": "5511999999999@s.whatsapp.net",
"message": "Template enviado com sucesso",
"wamid": "wamid.HBgNNTUxMTk5OTk5OTk5FQIAERgSQjYxNzc2..."
}{
"statusCode": 400,
"message": "Template \"meu_template\" não está aprovado (status: REJECTED)"
}{
"statusCode": 404,
"message": "Template \"meu_template\" (pt_BR) não encontrado"
}{
"statusCode": 409,
"error": "request_in_progress"
}Idempotência (X-Request-Id)
Envie o header opcional X-Request-Id para evitar o disparo duplicado da mesma mensagem quando você precisar repetir uma requisição (retry). O valor é uma chave de idempotência gerada por você e deve ser um UUID válido.
| Header | Tipo | Obrigatório | Descrição |
|---|---|---|---|
X-Request-Id | string (UUID) | Não | Chave de idempotência gerada pelo integrador. Gere um UUID por mensagem lógica e reenvie o mesmo valor se precisar repetir a requisição. |
Exemplo de requisição
curl -X POST https://api-v2.manybot.com.br/messages/send-template \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-H "X-Request-Id: 11111111-1111-4111-8111-111111111111" \
-d '{
"channelId": "clh1234567890",
"phone": "+5511999999999",
"templateName": "confirmacao_pedido",
"language": "pt_BR",
"params": {
"contact_first_name": "João"
}
}'
Comportamento
| Situação | Resposta |
|---|---|
| Header não enviado | O endpoint funciona exatamente como antes, sem deduplicação. |
| Header enviado com valor que não é um UUID válido | 400 com key: "invalid_request_id". |
Já existe uma requisição com o mesmo X-Request-Id processada com sucesso | 200 com o mesmo resultado da primeira vez (mesmo wamid, chatId etc.). A mensagem não é enviada novamente (replay). |
Já existe uma requisição com o mesmo X-Request-Id ainda em processamento | 409 com error: "request_in_progress". Tente novamente em instantes. |
A tentativa anterior com o mesmo X-Request-Id falhou | A falha libera a chave: a nova requisição envia a mensagem de fato. |
channelId). O mesmo X-Request-Id usado em canais diferentes é tratado como envios distintos.X-Request-Id continuam funcionando sem nenhuma alteração.Boas práticas
- Gere um UUID novo para cada mensagem lógica.
- Em caso de erro de rede, timeout ou resposta
5xx, repita a requisição com o mesmoX-Request-Id. Assim, se a mensagem já tiver sido enviada, você recebe o resultado original em vez de um envio duplicado.
Metadados (metadata)
Você pode anexar metadados livres à mensagem para controle/consulta posterior (ex.: id do pedido, id do cliente). São gravados na mensagem e não aparecem para o destinatário.
"metadata": { "pedidoId": "PED-5521", "clienteId": "c_789" }
metadata também é aceito no send-flow. Use-o para rastrear de qual processo/registro a mensagem veio.Disparar um Flow via template (flowData)
Para enviar um WhatsApp Flow de forma proativa (fora da janela de 24h), use um template aprovado que tenha um botão de Flow e passe os dados iniciais em flowData. O backend localiza o botão de Flow no template, gera o flow_token e injeta os dados — você não precisa informar flowId nem montar o botão.
{
"channelId": "clh1234567890",
"phone": "+5511999999999",
"templateName": "agendamento_consulta",
"language": "pt_BR",
"params": { "contact_first_name": "Maria" },
"metadata": { "agendamentoId": "AG-1024", "clienteId": "c_789" },
"flowData": {
"agendamentoId": "AG-1024",
"nome": "Maria",
"servico": "Consulta de rotina",
"horarios": [
{ "id": "2026-11-03T09:00", "title": "03/11 · 09:00" },
{ "id": "2026-11-03T14:00", "title": "03/11 · 14:00" }
]
}
}
flowData é o dataset completo do flow, enviado de uma vez. Os dados entram pela tela de entrada (único ponto que o WhatsApp permite pré-preencher no disparo) e, em flows multi-tela, são repassados internamente para as telas seguintes — você não divide o flowData por tela. O flow é apenas um molde com placeholders ${data.campo} — a Meta substitui cada placeholder pelo valor enviado em flowData no momento do envio (o __example__ do flow serve só para o preview do Builder, não para produção). Portanto o flowData precisa ter a estrutura exata que o flow espera.flowData e receber a resposta do flow está detalhado em Flows via Template.Authorizations
Token JWT da sua conta. Use o formato: Bearer {seu-jwt-token}
Headers
Chave de idempotência gerada pelo integrador para evitar disparo duplicado da mesma mensagem em caso de retry. Gere um UUID por mensagem lógica e reenvie o mesmo valor se precisar repetir a requisição. A chave é única por canal (channelId). Se não for um UUID válido, a API responde 400 (key: "invalid_request_id"). Se omitido, não há deduplicação.
"11111111-1111-4111-8111-111111111111"
Body
Dados para enviar um template de mensagem aprovado na Meta
ID do canal para envio.
"clh1234567890"
Número do destinatário (formato internacional).
"+5511999999999"
Nome do template aprovado na Meta.
"confirmacao_pedido"
Código do idioma do template (ex: pt_BR, en_US, es_AR). Normalmente use pt_BR.
"pt_BR"
Parâmetros de variáveis do template. Chave = nome da variável (ex: contact_first_name), valor = texto. Para templates posicionais use "1", "2", etc. Para botões de URL dinâmico use "button_url_0", "button_url_1", etc.
Show child attributes
Show child attributes
{
"contact_first_name": "João",
"contact_email": "joao@email.com"
}
Mídia do header do template. Informe apenas um dos campos: imageUrl, videoUrl ou documentUrl.
Show child attributes
Show child attributes
Dados iniciais do flow quando o template tem um botão de Flow. Alimentam a 1ª tela do flow (referenciados via ${data.campo}). Use para disparar um WhatsApp Flow de forma proativa via template.
{
"agendamentoId": "AG-1024",
"nome": "Maria",
"servico": "Consulta de rotina"
}
Metadados livres do integrador, gravados na mensagem para controle/consulta posterior (ex.: id do pedido, id do cliente).
{
"pedidoId": "PED-5521",
"clienteId": "c_789"
}
Response
Replay: uma requisição com o mesmo X-Request-Id já foi processada com sucesso neste canal. A mensagem não é reenviada e a resposta traz o mesmo resultado da primeira vez (mesmo wamid, chatId etc.).
Indica se o envio foi bem-sucedido.
true
ID interno do chat.
"clh0987654321"
ID externo do chat (número do WhatsApp).
"5511999999999@s.whatsapp.net"
Mensagem de confirmação.
"Template enviado com sucesso"
WhatsApp Message ID retornado pela Meta.
"wamid.HBgNNTUxMTk5OTk5OTk5FQIAERgSQjYxNzc2..."

