Documentação da API
Integre o envio de WhatsApp ao seu sistema com requisições HTTP simples. Base da API: https://zap.ementai.com.br/api
Início rápido
Em três passos você envia sua primeira mensagem.
- Assine um plano e conecte seu número lendo o QR Code no painel.
- Copie a API Key do número (ela aparece uma única vez, ao criar ou regenerar).
- Faça uma chamada
POST https://zap.ementai.com.br/api/v1/sendcom a chave no cabeçalhox-api-key.
curl -X POST "https://zap.ementai.com.br/api/v1/send" \
-H "x-api-key: SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"recipient":"5511999999999","text":"Olá! Mensagem enviada pela API do Ementai Zap."}'{
"success": true,
"messageId": "3EB0C767D0A1B2C3D4E5"
}Enviar mensagem
POST ou GET /v1/send — responde em JSON.
Envie os dados como JSON (POST) ou como query string (GET). A chave pode ir no cabeçalho x-api-key (recomendado), Authorization: Bearer ou no parâmetro apikey.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| recipient | string | sim | Número com DDI + DDD, só dígitos. Ex.: 5511999999999. |
| text | string | não | Texto da mensagem (até 4.096 caracteres). Vira legenda quando há mídia. |
| imageUrl | string | não | URL pública (http/https) de uma imagem. |
| documentUrl | string | não | URL pública (http/https) de um documento (PDF, planilha etc.). |
Evite envios duplicados
Idempotency-Key com um valor único por mensagem. Se você repetir a chamada em até 24 horas (por exemplo, após um timeout), devolvemos o resultado original sem enviar de novo.Modo compatível (GET, estilo TextMeBot)
curl -G "https://zap.ementai.com.br/api/v1/send" \
--data-urlencode "apikey=SUA_API_KEY" \
--data-urlencode "recipient=5511999999999" \
--data-urlencode "text=Olá! Mensagem enviada pela API do Ementai Zap."Prefira POST com cabeçalho: chaves em URLs podem aparecer em logs de proxies e navegadores.
Imagens e documentos
Informe a URL pública do arquivo; ela precisa estar acessível pela internet.
curl -X POST "https://zap.ementai.com.br/api/v1/send" \
-H "x-api-key: SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipient": "5511999999999",
"text": "Segue o comprovante.",
"documentUrl": "https://exemplo.com/comprovante.pdf"
}'URLs que apontam para redes internas (localhost, IPs privados) são recusadas por segurança.
Status e consumo
GET /v1/status — confira a conexão e a cota antes de disparar.
curl "https://zap.ementai.com.br/api/v1/status" -H "x-api-key: SUA_API_KEY"{
"success": true,
"connection": "connected",
"plan": "INDIVIDUAL",
"usage": { "month": 128, "monthlyLimit": 1000, "messagesPerMinute": 20 }
}Webhooks
Receba as mensagens e eventos do seu número em uma URL sua (HTTPS).
Cadastre a URL no painel, em Números › seu número › Webhook. Cada entrega é um POST JSON com os cabeçalhos x-ementai-event, x-ementai-timestamp e x-ementai-signature (HMAC-SHA256 de timestamp.corpo com o seu segredo). Responda com HTTP 2xx em até 10 segundos; fazemos até 3 tentativas.
{
"event": "message",
"instanceId": "clx...",
"createdAt": "2026-10-29T18:30:00.000Z",
"data": { }
}Validando a assinatura (Node.js)
import crypto from "node:crypto";
// Express: use express.raw({ type: "application/json" }) nesta rota
app.post("/webhook", (req, res) => {
const timestamp = req.header("x-ementai-timestamp");
const signature = req.header("x-ementai-signature");
const body = req.body.toString("utf8");
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.EMENTAI_WEBHOOK_SECRET)
.update(timestamp + "." + body)
.digest("hex");
const ok =
signature?.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!ok) return res.sendStatus(401);
const event = JSON.parse(body);
console.log(event.event, event.data);
res.sendStatus(200);
});Limites e erros
Todas as respostas de erro seguem o mesmo formato.
{
"success": false,
"error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Limite de mensagens por minuto excedido." }
}| HTTP | Código | Significado |
|---|---|---|
| 401 | API_KEY_MISSING / API_KEY_INVALID | Chave ausente ou incorreta. |
| 402 | SUBSCRIPTION_INACTIVE | Assinatura inativa ou vencida. |
| 403 | INSTANCE_BLOCKED | Número bloqueado por pendência de pagamento. |
| 409 | IDEMPOTENCY_IN_PROGRESS | Já existe uma chamada em andamento com esta Idempotency-Key. |
| 422 | VALIDATION_ERROR / INVALID_MEDIA_URL | Parâmetros inválidos. |
| 429 | RATE_LIMIT_EXCEEDED / MONTHLY_QUOTA_EXCEEDED | Limite por minuto ou cota mensal atingidos. Veja o cabeçalho Retry-After. |
| 502 | PROVIDER_ERROR | WhatsApp indisponível ou número desconectado. |
As respostas de envio trazem X-RateLimit-Limit e X-RateLimit-Remaining.