Autenticação
string
required
Bearer vg_live_<sua_chave> — API Key com escopo conversations:send (escopo dedicado, sem herança de conversations:read).POST /conversations/{id}/messages — que exige uma conversa já existente — este endpoint recebe apenas o phone: ele faz find-or-create do contato e da conversa e então envia, reusando a mesma infraestrutura do chat humano (janela de 24h, cota diária de mensagens do plano, primitivos do provedor e mapeamento de erro da Meta).
POST /api/v1/messages · Escopo conversations:send · Rate limit: perfil de envio a frio (send-cold)
Como escolher o type
O corpo é discriminado pelo campo type. Quando type é omitido, assume-se text.
Regra da Meta para número novo (API Oficial / Cloud): um número sem conversa prévia está fora da janela de 24h. A Meta só aceita template aprovado nesse caso. Enviar
text ou mídia para um número novo em uma conexão Cloud retorna 422 WINDOW_CLOSED.Formato do telefone
O campophone exige o número internacional brasileiro completo: 55 + DDD (2 dígitos) + número. O formato é flexível — +, espaços, parênteses e traços são ignorados —, mas o 55 e o DDD são obrigatórios.
9º dígito: as duas formas do mesmo celular — com o
9 (5511987654321) e sem o 9 (551187654321) — resolvem no mesmo contato e na mesma conversa. Você não precisa saber qual forma a Meta usa: o CRM canonicaliza no matching (igual ao webhook de entrada) e, no envio Cloud, ainda reconcilia com o wa_id autoritativo devolvido pela Meta, para que a resposta do lead caia sempre na mesma conversa. Números ambíguos (sem 55/DDD) são rejeitados com 400 INVALID_PHONE — o CRM não adivinha país nem DDD, para não criar contato duplicado.Body
string
required
Telefone do destinatário no formato
55 + DDD + número (ex.: 5511987654321). Máx. 32 caracteres.string
Conexão (instância WhatsApp) usada para enviar. Opcional quando o workspace tem uma única conexão. Obrigatório quando há mais de uma (senão retorna
422 INSTANCE_REQUIRED). Obtenha os IDs em GET /instances.string
text (padrão), image, video, audio, document ou template.string
Obrigatório quando
type é text. Conteúdo da mensagem, 1 a 4096 caracteres.string
Obrigatório para mídia (
image/video/audio/document). URL https pública de onde a Meta/Evolution baixa o arquivo (passa por checagem anti-SSRF). Máx. 2048 caracteres.string
Legenda opcional da mídia (máx. 1024 caracteres).
string
Nome do arquivo exibido, útil para
document (máx. 255 caracteres).string
Obrigatório para
template. Nome exato do template aprovado na sua WABA.string
Obrigatório para
template. Código de idioma do template (ex.: pt_BR). 2 a 15 caracteres.string[]
Valores posicionais das variáveis do corpo do template, na ordem — a 1ª entrada preenche
{{1}}, a 2ª {{2}}, e assim por diante. Máx. 20 valores, cada um até 1024 caracteres. A contagem precisa bater com o template aprovado (senão 422 TEMPLATE_INVALID).Limites de mídia (Meta)
Mídia acima do limite retorna
422 MEDIA_TOO_LARGE.
Idempotência
Envie o header opcionalIdempotency-Key (qualquer string única sua, ex.: um UUID) para evitar envio duplicado em retries. A chave é reservada atomicamente antes do envio: dois POSTs concorrentes com a mesma chave nunca enviam duas vezes — o segundo recebe 409 IN_PROGRESS (ainda em andamento) ou a resposta memoizada (200, mesmo corpo) por 10 minutos. Uma falha de envio libera a reserva para permitir novo retry com a mesma chave.
Exemplos
Resposta 201
string
ID interno da mensagem criada no CRM.
string
Sempre
sent quando a resposta é 201.string
text, image, video, audio, document ou template.string
Conversa (nova ou existente) onde a mensagem foi registrada.
string
Contato (novo ou existente) resolvido pelo telefone.
object
{ "contact": boolean, "conversation": boolean } — indica se o contato e/ou a conversa foram criados por esta requisição (false = já existiam).Se o envio falhar depois de criar contato/conversa (ex.:
WINDOW_CLOSED, TEMPLATE_INVALID, Evolution desconectada), o CRM faz rollback: remove o contato/conversa recém-criados e devolve a cota e o slot diário — nada de contato fantasma nem cota queimada por uma tentativa que não entregou.Fluxo recomendado
- Descubra o
instanceIdcomGET /api/v1/instances(necessário se o workspace tiver mais de uma conexão; escolha umaconnected). - Envie com
POST /api/v1/messages, usandoIdempotency-Keypara tornar o retry seguro. - Para número novo em conexão Cloud, use sempre
type: "template"— texto/mídia caem em422 WINDOW_CLOSED.