WhatsMax

Enviar mensagens

POST /v1/messages

Exige o escopo send. A resposta é 202, com o id da mensagem: ela entrou na fila e será enviada respeitando o ritmo do número.

Texto

{
  "instance": "nome-do-numero",
  "to": "5542999999999",
  "type": "text",
  "content": { "text": "Sua sala está confirmada para amanhã às 14h." },
  "category": "transactional",
  "external_ref": "invoice:1234"
}
Campo O que é
instance Nome do número que envia
to Telefone com DDI e DDD, só números
type text ou media
content O conteúdo, conforme o tipo
category transactional, notification ou marketing: define a prioridade na fila e se o opt-out se aplica. Omitida, vale transactional, que não respeita opt-out nem a pausa noturna
external_ref Uma referência sua, devolvida nos webhooks
callback_url Webhook só desta mensagem, no lugar do configurado no projeto

Mídia

O gateway não recebe o arquivo: recebe uma URL pública e vai buscá-la.

{
  "to": "5542999999999",
  "type": "media",
  "content": {
    "media_url": "https://exemplo.com/exame.pdf",
    "media_type": "document",
    "text": "segue o seu exame"
  }
}

media_type aceita image, audio, video e document.

Template (número oficial)

No número oficial (API da Meta), fora da janela de 24 horas só sai template: um modelo de mensagem que a Meta aprovou antes. Você pode criá-los no Gerenciador do WhatsApp da sua empresa, ou por aqui.

GET    /v1/instances/{name}/templates                  os aprovados, com as variáveis de cada um (escopo send)
GET    /v1/instances/{name}/templates?status=all       todos, com status, rejected_reason e quality_score
POST   /v1/instances/{name}/templates                  cria na Meta: {name, category, language?, body, body_examples, footer?, buttons?} → 201 PENDING (manage_instances)
DELETE /v1/instances/{name}/templates/{templateName}   apaga na Meta → 204 (manage_instances)

A aprovação (minutos a 48 h) chega pelo webhook template.status. Erros ao criar voltam como 422 com error estável: nome_duplicado, exemplo_faltando, template_invalido, sem_permissao_de_gerenciamento (o token do número não tem whatsapp_business_management; templates_gerenciaveis em GET /v1/instances/{name} diz antes).

{
  "instance": "numero-oficial",
  "to": "5542999999999",
  "type": "template",
  "template": {
    "name": "lembrete_consulta",
    "language": "pt_BR",
    "body": ["Ana", "amanhã às 14h"],
    "header": { "type": "image", "media_url": "https://exemplo.com/clinica.jpg" },
    "buttons": [{ "index": 0, "type": "url", "value": "abc123" }]
  },
  "category": "notification"
}
Campo O que é
name, language O template, como aparece na lista. language padrão pt_BR
body As variáveis do corpo, na ordem ({{1}}, {{2}}…). Template com variáveis nomeadas: um objeto, {"nome": "Ana"}
header Só se o template tem cabeçalho variável: text (com text), ou image, video, document (com media_url pública)
buttons Só os botões que pedem valor: url (o pedaço final do link), quick_reply (o payload) ou copy_code (o cupom), cada um com o index dele

A Meta cobra cada template entregue, direto da conta da sua empresa. Responder quem escreveu dentro de 24 horas não é cobrado. Template só existe no número oficial: no número conectado por QR a resposta é 422 template_exige_numero_oficial.

Idempotência

Para ligar cada webhook ao seu lado (uma campanha, um pedido), mande metadata: um objeto JSON de até 1 KB, devolvido igual em message.sent, message.delivered, message.read e message.failed.

Mande um cabeçalho Idempotency-Key com um valor seu e único por envio. Repetir a chamada com a mesma chave (por exemplo, depois de um timeout) devolve a mesma mensagem, com 200 e idempotent_replay: true, em vez de enviar duas vezes.

As travas de proteção

O gateway recusa o que aumenta o risco de banimento. As recusas mais comuns:

Resposta Significado
422 fora_da_janela O contato não escreveu para este número nas últimas 24 horas. É definitivo: o contato precisa escrever primeiro. Não repita em loop; use outro canal (e-mail, SMS), ou, no número oficial, um template.
422 categoria_nao_permitida O projeto só responde, e a categoria marketing não é aceita. Projeto com a chave de campanha ligada manda marketing só por template, só pelo número oficial.
422 teto_marketing_do_dia O número oficial já alcançou o teto de contatos de marketing do dia. retry_after diz, em segundos, quando tentar de novo (meia-noite de Brasília).
409 O número pediu para não receber esta categoria (opt-out).
409 dados_excluidos A Idempotency-Key repetida é de uma mensagem cujo contato pediu a exclusão dos dados. Use outra chave.

Quando um contato pede a exclusão dos dados dele, as mensagens e a mídia daquele telefone passam a responder 404, e os avisos pendentes sobre elas não são entregues.

O campo error é o código estável; message, quando existe, é texto para humanos e pode mudar. Decida pelo error.

Consultar e cancelar

GET  /v1/messages/{id}          status e histórico de eventos (escopo read_logs)
POST /v1/messages/{id}/cancel   cancela se ainda não saiu (escopo send)

O que o WhatsMax não faz

Contato frio, envio em massa, lista de transmissão e qualquer coisa que ignore o opt-out ou o ritmo do número ficam de fora de propósito: é o que derruba números. Para avisar quem não escreveu, use e-mail ou SMS.