Skip to main content

Autenticação

string
required
Bearer vg_live_<sua_chave> — API Key com escopo conversations:send (escopo dedicado, sem herança de conversations:read).
Diferente de 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)
Este é o recurso mais sensível da API — envio para números novos (cold outreach). Ele tem limites mais apertados que o envio em conversa existente: 10 req/min por IP e teto absoluto de 5 mensagens/min por chave (fail-closed), além de um cap diário de números novos por workspace. Cada envio consome a cota diária de mensagens do plano.

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.
Conexão Evolution (não oficial): o envio de texto livre para número novo funciona, mas fazer cold outreach por uma conexão Evolution tem risco real de banimento do número pelo WhatsApp. Para prospecção em escala, use a API Oficial com template aprovado.

Formato do telefone

O campo phone 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 opcional Idempotency-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

  1. Descubra o instanceId com GET /api/v1/instances (necessário se o workspace tiver mais de uma conexão; escolha uma connected).
  2. Envie com POST /api/v1/messages, usando Idempotency-Key para tornar o retry seguro.
  3. Para número novo em conexão Cloud, use sempre type: "template" — texto/mídia caem em 422 WINDOW_CLOSED.

Erros

Autenticação e limites

Corpo e roteamento

Envio