DWM Systems

DWM Mensageria · API

Documentação da API

Para a equipe que vai integrar o sistema da empresa. O sistema faz uma chamada HTTPS, recebe um identificador e acompanha a mensagem até a entrega e a leitura, por consulta ou por webhook. Todo envio usa exclusivamente a API oficial da Meta (WhatsApp Cloud API), com o número e a conta da própria empresa.

1Ambientes e chaves

AmbienteURL baseChave começa com
Homologaçãohttps://www.dwmsystems.com.br/api/v1/mensageriadwmmsg_test_
Produçãohttps://www.dwmsystems.com.br/api/v1/mensageriadwmmsg_live_

A URL é a mesma. O que define o ambiente é a chave: cada ambiente é uma conta separada, com chaves próprias.

Homologação nunca envia mensagem real e não gera custo. Ela simula o ciclo completo: aceita → enviada → entregue → lida. Um número terminado em 0000 simula falha (código 131026, número sem WhatsApp). Os eventos de webhook saem iguais aos de produção.

Autenticação

Todas as chamadas levam o cabeçalho:

Authorization: Bearer dwmmsg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • A chave é entregue uma única vez, por canal seguro. A DWM guarda só o hash dela e não consegue recuperá-la: se perder, pedimos uma nova.
  • Rotação: a DWM gera uma chave nova e mantém a anterior valendo por um prazo combinado (por exemplo, 7 dias), para o sistema trocar sem parar.
  • Revogação: a chave para de valer na hora.
  • Só HTTPS (TLS 1.2 ou superior). A chave nunca vai na URL.
  • Use a chave só no servidor. Guarde em variável de ambiente ou cofre de segredos; nunca em aplicativo, página no navegador, log ou repositório de código. Se vazar, peça a revogação na hora.

Conectar o número da empresa

O número e a conta do WhatsApp Business continuam sendo da empresa, e a cobrança da Meta é feita na conta dela.

  1. A DWM envia um link de conexão. Ele vale 7 dias e serve para uma conexão.
  2. Quem administra a empresa na Meta abre o link e clica em Conectar com o Facebook.
  3. Na janela da Meta, a pessoa escolhe (ou cria) a conta do WhatsApp Business e o número, e autoriza a DWM Systems.

A DWM registra o número na API oficial e passa a receber os status de entrega. O acesso pode ser removido a qualquer momento nas Configurações do negócio da Meta.

2Enviar mensagem

POST /mensagens com Content-Type: application/json.

Cabeçalho opcional e recomendado: Idempotency-Key: <id único do seu lado> (até 100 caracteres). Se a mesma chave chegar de novo, por exemplo numa retentativa depois de um tempo esgotado na sua rede, a API devolve a mensagem original com 200, sem enviar de novo.

Campos

CampoTipoObrigatórioObservação
paratextosimNúmero com DDI e DDD, ex.: 5569999998888. Pontuação é ignorada. Sem o 55, ele é acrescentado quando o número tem 10 ou 11 dígitos.
tipotextosimtexto, imagem, documento ou modelo
textotextose tipo=textoaté 4.096 caracteres
arquivoobjetose imagem ou documentover abaixo
modeloobjetose tipo=modelover abaixo
referencia_externatextonãoseu identificador (ex.: nº do protocolo), até 100 caracteres; volta em consultas e webhooks

arquivo — informe um dos dois, url ou base64:

CampoObservação
urlendereço https público do arquivo; a Meta baixa o arquivo no momento do envio
base64conteúdo do arquivo. Documento: só PDF, até 10 MB. Imagem: JPEG ou PNG, até 5 MB
nomenome que o destinatário vê (documento). .pdf é acrescentado se faltar
legendatexto abaixo da imagem ou do documento (opcional)

modelo:

CampoObservação
nomenome do modelo aprovado pela Meta (minúsculas, números e _)
idiomapadrão pt_BR
parametroslista com os valores de {{1}}, {{2}}… do corpo, na ordem
cabecalhoopcional, para modelos com cabeçalho de mídia: {"tipo": "documento" | "imagem", "url" | "base64", "nome"}

Regra da Meta: modelo × mensagem livre

O WhatsApp só permite iniciar uma conversa com um modelo aprovado. Texto, imagem e documento avulsos só são entregues se o destinatário tiver escrito para o número nas últimas 24 horas. Para avisos ativos, use tipo: "modelo", com o PDF no cabeçalho do modelo quando houver arquivo. Fora da janela, a Meta recusa com o código 131047.

Exemplo — modelo com um PDF

Pedido
POST /api/v1/mensageria/mensagens
Authorization: Bearer dwmmsg_live_...
Idempotency-Key: protocolo-2026-000123
Content-Type: application/json

{
  "para": "5569999998888",
  "tipo": "modelo",
  "referencia_externa": "PROT-2026-000123",
  "modelo": {
    "nome": "documento_disponivel",
    "idioma": "pt_BR",
    "parametros": ["Maria", "PROT-2026-000123"],
    "cabecalho": { "tipo": "documento", "base64": "JVBERi0xLjQK...", "nome": "documento.pdf" }
  }
}
Resposta 202 Accepted
{
  "id": "msg_19a3f0c1d2e4a1b2c3d4e5f6",
  "referencia_externa": "PROT-2026-000123",
  "para": "5569*****8888",
  "tipo": "modelo",
  "status": "na_fila",
  "wamid": null,
  "erro": null,
  "tentativas": 0,
  "criada_em": "2026-11-03T09:15:02-03:00",
  "enviada_em": null,
  "entregue_em": null,
  "lida_em": null,
  "falhou_em": null
}

O envio é assíncrono. Normalmente sai em segundos; com a fila cheia ou à espera de uma retentativa, pode levar alguns minutos.

Mesmo envio com curl
curl -X POST https://www.dwmsystems.com.br/api/v1/mensageria/mensagens \
  -H "Authorization: Bearer $DWM_MENSAGERIA_CHAVE" \
  -H "Idempotency-Key: protocolo-2026-000123" \
  -H "Content-Type: application/json" \
  -d '{"para":"5569999998888","tipo":"texto","texto":"Seu protocolo foi recebido."}'

3Status

StatusSignificado
na_filaaceita pela DWM, aguardando envio (ou uma retentativa)
processandosendo enviada à Meta agora
enviadaaceita pela Meta (wamid preenchido)
entregueentregue no aparelho do destinatário
lidalida, quando o destinatário mantém a confirmação de leitura ligada
falhounão enviada ou não entregue (veja erro)

O status só anda para frente. Se uma confirmação da Meta chegar fora de ordem, ela não faz o status voltar.

Reenvio automático e duplicidade

A DWM reenvia sozinha só quando é certo que nada saiu: falha de conexão, limite de taxa ou indisponibilidade temporária da Meta. São até 6 tentativas, em 1, 2, 5, 15 e 60 minutos. Se a Meta recebeu o pedido mas não respondeu a tempo, a mensagem vai para falhou com o código resultado_incerto, sem reenvio, porque reenviar poderia duplicar a mensagem. Nesse caso, o seu sistema decide se envia de novo.

4Consultar

ChamadaDevolve
GET /mensagens/{id}a mensagem e a linha do tempo dos eventos
GET /mensagens?referencia_externa=PROT-2026-000123busca pelo seu identificador
GET /mensagens?status=falhou&desde=2026-11-01T00:00&ate=2026-12-01T00:00&limite=500datas em horário de Brasília; até 500 itens, os mais recentes primeiro
GET /contalimites e quantas mensagens já foram usadas hoje
GET /relatorio?mes=2026-11relatório mensal (seção 7)

5Webhook (eventos de status)

Se a empresa informar uma URL https, a DWM faz um POST a cada mudança de status:

EventoQuando
mensagem.aceitapedido aceito na fila
mensagem.enviadaaceita pela Meta
mensagem.entregueentregue ao destinatário
mensagem.lidalida
mensagem.falhoufalha (com o código)
Corpo
{
  "id": "evt_19a3f0c1d9f0aa11bb22cc33",
  "tipo": "mensagem.entregue",
  "ocorrido_em": "2026-11-03T09:15:09-03:00",
  "mensagem": { "id": "msg_19a3f0c1d2e4a1b2c3d4e5f6", "status": "entregue", "referencia_externa": "PROT-2026-000123", "...": "..." }
}

Cabeçalhos: X-DWM-Evento, X-DWM-Evento-Id, X-DWM-Timestamp e X-DWM-Assinatura.

  • Responda 2xx em até 10 segundos. Qualquer outra resposta gera nova tentativa em 1 min, 5 min, 30 min, 2 h, 6 h e 24 h. Depois disso o evento é marcado como não entregue, e a DWM é avisada.
  • Cada evento é entregue pelo menos uma vez. Use X-DWM-Evento-Id para descartar repetições.
  • A ordem de chegada não é garantida. O campo mensagem.status traz sempre o estado mais recente.
  • Um evento tipo: "teste" pode ser enviado a pedido, para validar a URL.

Conferindo a assinatura

X-DWM-Assinatura = "v1=" + hex(HMAC_SHA256(segredo_do_webhook, timestamp + "." + corpo_bruto))

Recuse o evento se a assinatura não bater ou se o timestamp estiver a mais de 5 minutos do seu relógio. Calcule sobre o corpo bruto recebido, antes de converter o JSON, e só processe o evento depois dessa conferência. O segredo do webhook segue as mesmas regras da chave: fica só no servidor.

Python
import hashlib, hmac, time

def evento_valido(segredo: str, headers: dict, corpo: bytes) -> bool:
    ts = headers["X-DWM-Timestamp"]
    if abs(time.time() - int(ts)) > 300:
        return False
    esperado = "v1=" + hmac.new(segredo.encode(), ts.encode() + b"." + corpo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, headers["X-DWM-Assinatura"])
PHP
function evento_valido(string $segredo, string $ts, string $assinatura, string $corpo): bool {
    if (abs(time() - (int) $ts) > 300) return false;
    $esperado = 'v1=' . hash_hmac('sha256', $ts . '.' . $corpo, $segredo);
    return hash_equals($esperado, $assinatura);
}

6Erros

Sempre neste formato:

{ "erro": { "codigo": "destinatario_invalido", "mensagem": "Número inválido. ..." } }
HTTPCódigoO que fazer
400json_invalidocorrigir o corpo
401chave_ausente, chave_invalidaconferir a chave (revogada ou expirada)
403conta_inativafalar com o suporte DWM
404mensagem_nao_encontradaconferir o id
413corpo_grandecorpo maior que 15 MB
422destinatario_invalido, tipo_invalido, texto_invalido, arquivo_obrigatorio, url_invalida, base64_invalido, formato_invalido, arquivo_grande, modelo_invalido, parametros_invalidos, cabecalho_invalido, referencia_invalida, idempotencia_invalidacorrigir o pedido; não repetir igual
429limite_diario_atingido, muitas_requisicoesaguardar (cabeçalho Retry-After)
5xx—repetir com a mesma Idempotency-Key

Erros de entrega

Aparecem em mensagem.erro.codigo, com o código da Meta. Os mais comuns:

CódigoSignificado
131026o número não tem WhatsApp ou não pode receber a mensagem
131047fora da janela de 24 h: use um modelo
131049a Meta não entregou para preservar a experiência do usuário (limite de mensagens de marketing)
132000, 132001parâmetros ou nome do modelo não conferem com o aprovado
131053a Meta não conseguiu baixar ou processar a mídia (url)
resultado_incertosem resposta da Meta; não reenviado para evitar duplicidade
temporario_esgotadoa Meta seguiu indisponível em todas as tentativas

7Limites, disponibilidade e relatório

  • Limite diário de mensagens por conta, definido no contrato (padrão: 1.000 por dia), e ritmo máximo de envio por minuto (padrão: 60).
  • O limite de conversas da própria Meta depende da verificação da empresa no Gerenciador de Negócios. Portfólios não verificados começam com limite baixo, e a DWM apoia esse processo.
  • Disponibilidade mensal mínima de 99%. Manutenção programada é avisada com 48 horas de antecedência.
  • GET /relatorio?mes=AAAA-MM traz mensagens processadas, enviadas, entregues, lidas e não entregues; falhas por código; percentual de disponibilidade; períodos de indisponibilidade; manutenções; chamados; incidentes de segurança; e entregas de webhook.

8Segurança e dados (LGPD)

  • A DWM trata somente os dados necessários ao envio (número, conteúdo e arquivo), sob as instruções da empresa contratante.
  • Arquivos enviados em base64 são apagados logo depois do envio; fica só o hash SHA-256, para auditoria.
  • Painéis e relatórios mostram o número mascarado (5569*****8888).
  • O token da conta oficial da empresa na Meta é guardado cifrado.
  • Incidentes de segurança são comunicados em até 24 horas da ciência.
  • No fim do contrato, a DWM entrega todos os registros em CSV, revoga as credenciais e depois anonimiza os dados (números mascarados e conteúdo apagado).

Mais detalhes na Política de Privacidade, nos Termos de Uso e em Exclusão de dados.

9Suporte

Em português, em dias úteis e horário comercial de Brasília, por e-mail (contato@dwmsystems.com.br), telefone ou WhatsApp ((31) 98105-2030). Para incidente que impeça o envio: resposta inicial em até 2 horas úteis e solução ou contorno em até 8 horas úteis.