Enviar template em massa (Bulk Send)
ENVIO EM MASSA DE TEMPLATES DO WHATSAPP
Envia mensagens de template do WhatsApp para múltiplos contatos de uma só vez. Esta é uma funcionalidade poderosa para campanhas de marketing, notificações em massa e comunicações importantes.
📋 Estrutura da Requisição
A requisição deve ser feita como multipart/form-data com os seguintes campos:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
inboxId | string | ✅ Sim | ID do inbox pelo qual as mensagens serão enviadas |
templateName | string | ✅ Sim | Nome do template aprovado no WhatsApp (3-512 caracteres) |
languageCode | string | ✅ Sim | Código de idioma (ex: pt_BR, en_US, es_ES, pt_PT) |
components | array | ❌ Não | Array de componentes do template (header, body, buttons) |
contacts | array | ⚠️ Condicional | Array de contatos (obrigatório se não enviar arquivo) |
file | file | ⚠️ Condicional | Arquivo CSV/XLSX (obrigatório se não enviar contacts) |
📝 Schema Zod dos DTOs
BulkContactSchema
{
name: string, // Nome do contato (obrigatório, mín. 1 caractere)
phone: string // Telefone do contato (obrigatório, mín. 1 caractere)
}
TemplateParameterSchema
{
type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time' | 'payload',
// Campos opcionais (usar conforme o tipo):
text?: string, // Para tipo 'text'
image?: { link?: string }, // Para tipo 'image'
document?: {
link?: string,
filename?: string
}, // Para tipo 'document'
video?: { link?: string }, // Para tipo 'video'
currencyCode?: string, // Para tipo 'currency' (ex: 'BRL', 'USD')
currencyAmount?: number, // Para tipo 'currency'
dateTime?: string, // Para tipo 'date_time' (ISO 8601)
payload?: string, // Para tipo 'payload' (botões)
// Campos alternativos (compatibilidade):
value?: string,
link?: string,
imageUrl?: string,
imageId?: string,
documentUrl?: string,
documentFilename?: string,
videoUrl?: string,
parameter_name?: string
}
TemplateComponentSchema
{
type: 'header' | 'body' | 'button',
sub_type?: 'quick_reply' | 'url' | 'phone_number', // Apenas para buttons
index?: string, // Índice do botão (apenas para buttons)
parameters?: TemplateParameter[] // Array de parâmetros
}
SendBulkTemplateMessageDto
{
inboxId: string, // Obrigatório, mín. 1 caractere
templateName: string, // Obrigatório, 3-512 caracteres, lowercase, sem espaços
languageCode: string, // Obrigatório, formato: xx_XX
components?: TemplateComponent[], // Opcional
contacts?: BulkContact[] // Opcional (se não enviar arquivo)
}
👥 Formatos de Contatos
Opção 1: JSON (campo contacts)
{
"inboxId": "65f1a2b3c4d5e6f7g8h9i0j1",
"templateName": "welcome_message",
"languageCode": "pt_BR",
"contacts": [
{ "name": "João Silva", "phone": "5511999999999" },
{ "name": "Maria Santos", "phone": "5511888888888" }
]
}
Opção 2: Arquivo CSV
name,phone
João Silva,5511999999999
Maria Santos,5511888888888
Pedro Costa,5511777777777
Opção 3: Arquivo XLSX
Arquivo Excel com colunas obrigatórias: name | phone
🎨 Componentes de Template
Templates do WhatsApp são compostos por componentes que podem ter parâmetros dinâmicos.
Tipos de Componentes:
| Tipo | Descrição | Parâmetros Permitidos |
|---|---|---|
| header | Cabeçalho do template | text, image, video, document |
| body | Corpo principal | text, currency, date_time |
| button | Botões interativos | text, payload |
Sub-tipos de Botão:
quick_reply: Resposta rápida (payload)url: Botão com link dinâmico (text para variável da URL)phone_number: Botão de telefone
📝 Exemplos Práticos
1️⃣ Template Simples de Texto
Template aprovado no WhatsApp:
Olá {{1}}! Bem-vindo à nossa loja.
Requisição:
{
"inboxId": "65f1a2b3c4d5e6f7g8h9i0j1",
"templateName": "welcome_message",
"languageCode": "pt_BR",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "João" }
]
}
],
"contacts": [
{ "name": "João Silva", "phone": "5511999999999" }
]
}
Resultado: “Olá João! Bem-vindo à nossa loja.”
2️⃣ Template com Header de Imagem
Template aprovado:
[HEADER: IMAGEM]
Olá {{1}}!
Confira nossa promoção de {{2}}.
Requisição:
{
"inboxId": "...",
"templateName": "promotion",
"languageCode": "pt_BR",
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"image": { "link": "https://example.com/promo.jpg" }
}
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "João" },
{ "type": "text", "text": "Black Friday" }
]
}
],
"contacts": [...]
}
3️⃣ Template com Botão URL Dinâmico
Template aprovado:
Olá! Seu pedido #{{1}} foi confirmado.
[BOTÃO URL: Rastrear Pedido - https://example.com/track/{{1}}]
Requisição:
{
"inboxId": "...",
"templateName": "order_confirmation",
"languageCode": "pt_BR",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "12345" }
]
},
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [
{ "type": "text", "text": "12345" }
]
}
],
"contacts": [...]
}
4️⃣ Template com Documento no Header
Template aprovado:
[HEADER: DOCUMENTO]
Olá {{1}}, segue seu boleto de cobrança.
Requisição:
{
"inboxId": "...",
"templateName": "invoice",
"languageCode": "pt_BR",
"components": [
{
"type": "header",
"parameters": [
{
"type": "document",
"document": {
"link": "https://example.com/boleto.pdf",
"filename": "boleto_janeiro.pdf"
}
}
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "João Silva" }
]
}
],
"contacts": [...]
}
5️⃣ Template com Moeda e Data
Template aprovado:
Olá {{1}}!
Sua fatura de {{2}} no valor de {{3}} vence em {{4}}.
Requisição:
{
"inboxId": "...",
"templateName": "billing",
"languageCode": "pt_BR",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "João" },
{ "type": "text", "text": "Janeiro/2024" },
{
"type": "currency",
"currencyCode": "BRL",
"currencyAmount": 150.50
},
{
"type": "date_time",
"dateTime": "2024-01-31T23:59:59Z"
}
]
}
],
"contacts": [...]
}
Resultado: “Olá João! Sua fatura de Janeiro/2024 no valor de R$ 150,50 vence em 31/01/2024.”
6️⃣ Template Carousel (Carrossel)
Templates tipo carrossel permitem enviar múltiplos cards deslizáveis.
{
"inboxId": "...",
"templateName": "product_catalog",
"languageCode": "pt_BR",
"isCarousel": true,
"carouselCards": [
{
"card_index": 0,
"components": [
{
"type": "HEADER",
"parameters": [
{
"type": "image",
"image": { "link": "https://example.com/product1.jpg" }
}
]
},
{
"type": "BODY",
"parameters": [
{ "type": "text", "text": "Produto 1" },
{ "type": "text", "text": "R$ 99,90" }
]
},
{
"type": "BUTTON",
"sub_type": "quick_reply",
"index": 0,
"parameters": [
{ "type": "payload", "payload": "product_1" }
]
}
]
},
{
"card_index": 1,
"components": [
// Componentes do card 2...
]
}
],
"contacts": [...]
}
📊 Resposta da API
Schema de Resposta:
{
totalProcessed: number, // Total de contatos processados
sentCount: number, // Quantidade enviada com sucesso
errorCount: number, // Quantidade de erros
sentContacts: [ // Contatos enviados com sucesso
{
conversationId: string, // ID da conversa criada/utilizada
phoneNumber: string // Número de telefone formatado
}
],
errors: [ // Erros detalhados
{
row: number, // Linha do erro (arquivo ou índice)
contact: string, // Nome do contato
error: string // Descrição do erro
}
]
}
Exemplo de Resposta:
{
"totalProcessed": 100,
"sentCount": 95,
"errorCount": 5,
"sentContacts": [
{
"conversationId": "65f1a2b3c4d5e6f7g8h9i0j1",
"phoneNumber": "5511999999999"
},
{
"conversationId": "65f1a2b3c4d5e6f7g8h9i0j2",
"phoneNumber": "5511888888888"
}
],
"errors": [
{
"row": 5,
"contact": "João Silva",
"error": "Número de telefone inválido"
},
{
"row": 23,
"contact": "Maria Santos",
"error": "Template não encontrado para este inbox"
}
]
}
⚠️ Observações Importantes
Validações e Restrições:
- ✅ Templates Aprovados: Só é possível enviar templates previamente aprovados pelo Meta/WhatsApp
- ⏱️ Limite de Taxa: O WhatsApp possui limites de envio (tier-based):
- Tier 1: até 1.000 conversas únicas/dia
- Tier 2: até 10.000 conversas únicas/dia
- Tier 3: até 100.000 conversas únicas/dia
- 📞 Validação de Números: Números são validados automaticamente (formato internacional E.164)
- 🕐 Janela de 24h: Templates podem ser enviados FORA da janela de 24 horas
- 🎯 Parâmetros Corretos: Número e tipo de parâmetros devem coincidir EXATAMENTE com o template
- 🔢 Índices de Botão: Botões dinâmicos são indexados começando em
"0"(string) - 🖼️ Formato de Mídia: Links de mídia devem ser URLs públicas HTTPS acessíveis
- 📦 Tamanho de Lote: Recomenda-se enviar em lotes de até 1.000 contatos por vez
Códigos de Idioma Aceitos:
| Código | Idioma |
|---|---|
pt_BR | Português (Brasil) |
pt_PT | Português (Portugal) |
en_US | Inglês (EUA) |
en_GB | Inglês (Reino Unido) |
es_ES | Espanhol (Espanha) |
es_MX | Espanhol (México) |
fr_FR | Francês |
de_DE | Alemão |
it_IT | Italiano |
Limites do WhatsApp por Tipo de Mídia:
| Tipo | Tamanho Máximo | Formatos Aceitos |
|---|---|---|
| Imagem | 5 MB | JPG, JPEG, PNG |
| Vídeo | 16 MB | MP4, 3GPP |
| Documento | 100 MB | PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT |
| Áudio | 16 MB | AAC, M4A, AMR, MP3, OGG |
🔗 Tipos de Parâmetros Suportados
| Tipo | Uso | Campos Obrigatórios | Exemplo |
|---|---|---|---|
text | Texto simples | text | { "type": "text", "text": "João" } |
image | Imagem (header) | image.link | { "type": "image", "image": { "link": "https://..." } } |
video | Vídeo (header) | video.link | { "type": "video", "video": { "link": "https://..." } } |
document | Documento (header) | document.link, document.filename | { "type": "document", "document": { "link": "https://...", "filename": "doc.pdf" } } |
currency | Valor monetário | currencyCode, currencyAmount | { "type": "currency", "currencyCode": "BRL", "currencyAmount": 99.90 } |
date_time | Data/hora | dateTime (ISO 8601) | { "type": "date_time", "dateTime": "2024-01-15T10:30:00Z" } |
payload | Dados para botão | payload | { "type": "payload", "payload": "button_data" } |
🚀 Boas Práticas
- Teste com poucos contatos antes de enviar para uma lista grande
- Valide seus números no formato internacional (ex: 5511999999999)
- Use templates específicos para cada caso de uso
- Monitore as estatísticas de entrega na resposta da API
- Respeite os limites de taxa do WhatsApp
- Mantenha templates atualizados e aprovados
- Use CSV/XLSX para listas grandes (melhor performance)
- Implemente retry para contatos que falharam
Authorizations
Token JWT de autenticação
Headers
Identificador da empresa-alvo. Obrigatório apenas para API Keys globais (type=global). Ignorado para API Keys de empresa e usuários humanos.
Body
ID do inbox/conexão WhatsApp que será usado para enviar
1Nome do template registrado no WhatsApp Business
1Código de idioma do template (formato: pt_BR, en_US, en, etc)
Lista de componentes do template com seus parâmetros/variáveis. Use para personalizar header, body e buttons com dados dinâmicos.
Lista de contatos que receberão o template. Opcional se você enviar um arquivo CSV/Excel com os contatos.
Define quem responderá após o envio do template. Valores: AGENT (agente IA), HUMAN (atendente humano). Padrão: AGENT
AGENT, HUMAN, UNASSIGNED ID do agente IA que será ativado para responder. Usado em conjunto com who_will_answer=AGENT
Response
Envio em massa executado com sucesso (retorna estatísticas detalhadas)
Total de contatos processados
Quantidade de mensagens enviadas com sucesso
Quantidade de erros durante o envio
Lista detalhada de erros ocorridos
Lista de contatos que receberam a mensagem com sucesso