API querfalarcomigo.tech

API REST para enviar e receber mensagens de WhatsApp a partir do seu sistema. Cada cliente recebe uma instância (um número de WhatsApp) com seu próprio ID e API key.

Base URL {{BASE}}
Como conectar o número
  1. Pelo link de conexão: o suporte envia um link (/connect/...) válido por tempo limitado. Basta abrir e escanear o QR com o WhatsApp.
  2. Pelo seu sistema: consulte GET /status; se vier qr_pending, busque GET /qr e exiba a imagem para o usuário. Repita a cada 2–3s até o status virar connected. O QR muda a cada ~20s.
  3. Com o status connected, já é possível enviar mensagens e receber o webhook.
Autenticação
🔑

Todas as rotas exigem a API key da instância no header X-API-Key. A chave só é exibida uma vez, ao ser gerada — guarde-a no servidor, nunca no front-end/navegador. Se vazar, peça ao suporte uma nova (a antiga deixa de funcionar na hora).

bash
curl -H "X-API-Key: zb_sua_api_key" {{BASE}}/api/instances/INSTANCE_ID/status
Erros e limites

Erros sempre retornam JSON no formato { "error": "mensagem" }.

400Requisição inválida (campo faltando, URL não-https, número inválido) 401API key ausente ou inválida 403Instância suspensa 404QR / mensagem não disponível 409Instância não está conectada ao WhatsApp 429Limite excedido — respeite o header Retry-After (envio: 60 msgs/min por instância) 500Falha ao enviar pelo WhatsApp
Conexão
GET/api/instances/:id/statusStatus da conexão 🔑
bash
curl -H "X-API-Key: zb_sua_api_key" {{BASE}}/api/instances/INSTANCE_ID/status
resposta
{ "status": "connected", "phone": "5511999999999" }
Valores de status
connectingIniciando conexão
qr_pendingAguardando leitura do QR
connectedPronto para enviar/receber
disconnectedQueda temporária, reconectando automaticamente
logged_outDesconectado pelo celular — chame POST /reset para gerar novo QR
GET/api/instances/:id/qrQR code (base64) 🔑

Disponível somente com status qr_pending. Retorna uma imagem PNG em data URL, pronta para usar no <img src>. Faça a chamada pelo seu back-end e repasse a imagem ao navegador — não exponha a API key no front.

resposta
{ "qr": "data:image/png;base64,iVBORw0KGgo..." }
POST/api/instances/:id/resetDesconecta o número e gera novo QR 🔑

Use para trocar o número conectado ou quando o status for logged_out. Em seguida, acompanhe /status e exiba o /qr.

bash
curl -X POST -H "X-API-Key: zb_sua_api_key" {{BASE}}/api/instances/INSTANCE_ID/reset
Mensagens
POST/api/instances/:id/sendEnvia texto ou imagem 🔑
Body (JSON)
CampoTipoDescrição
tostringobrig.Número com DDI (5511999999999). Sem DDI (11999999999) assume Brasil.
messagestringtexto*Texto (até 4096 caracteres)
mediaUrlstringimagem*URL https pública de uma imagem (até 10MB)
captionstringopcionalLegenda da imagem

* Informe message ou mediaUrl.

bash
curl -X POST {{BASE}}/api/instances/INSTANCE_ID/send \
  -H "X-API-Key: zb_sua_api_key" \
  -H "Content-Type: application/json" \
  -d '{"to": "5511999999999", "message": "Olá! Seu pedido foi aprovado."}'
imagem
{ "to": "5511999999999", "mediaUrl": "https://seusite.com/boleto.png", "caption": "Seu boleto" }
resposta
{ "ok": true, "messageId": "3EB0C767D26A1D8E4A1B" }
GET/api/instances/:id/messages/:messageIdStatus de entrega 🔑

Guarda as últimas 200 mensagens enviadas por instância (em memória — some após reinício do servidor).

resposta
{
  "id": "3EB0C767D26A1D8E4A1B",
  "to": "5511999999999@s.whatsapp.net",
  "type": "text",
  "status": 3,
  "statusLabel": "delivered",  // pending | sent | delivered | read | played | error
  "timestamp": 1727359200000
}
Webhook
PUT/api/instances/:id/webhookDefine a URL que recebe as mensagens 🔑

A URL precisa ser https e pública. Envie null para desativar.

bash
curl -X PUT {{BASE}}/api/instances/INSTANCE_ID/webhook \
  -H "X-API-Key: zb_sua_api_key" \
  -H "Content-Type: application/json" \
  -d '{"webhookUrl": "https://seusistema.com/whatsapp/webhook"}'
POSTsua URL de webhookMensagem recebida
payload
{
  "instanceId": "a1b2c3d4e5f6",
  "event": "message.received",
  "data": {
    "id": "3EB0...",
    "from": "5511999999999@s.whatsapp.net",
    "pushName": "João",
    "timestamp": 1727359200,
    "type": "conversation",
    "text": "Oi, quero saber do meu pedido"
  }
}
Verificando a assinatura

Cada chamada traz X-Webhook-Timestamp e X-Webhook-Signature: sha256=<hex>, um HMAC-SHA256 de timestamp + "." + corpo_bruto com o segredo do webhook (whsec_..., fornecido pelo suporte). Rejeite chamadas com assinatura inválida ou timestamp com mais de 5 minutos.

php
$secret = getenv('WHATSAPP_WEBHOOK_SECRET');
$body   = file_get_contents('php://input');
$ts     = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$sig    = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
if (!hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
    http_response_code(401);
    exit;
}
$event = json_decode($body, true);
// ... processa $event['data']['text']
http_response_code(200);
node.js
import { createHmac, timingSafeEqual } from 'crypto'

function verify(rawBody, ts, sig, secret) {
  const expected = 'sha256=' + createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex')
  return sig?.length === expected.length
    && timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
    && Math.abs(Date.now() / 1000 - Number(ts)) < 300
}