A API do WhatsApp, documentada.
REST para enviar e ler, webhooks assinados para receber e um servidor MCP pronto para o seu agente. Integre o WhatsApp no seu produto com line_id e chaves de API.
De zero a sua primeira mensagem em 3 passos.
1. Conecta uma linha
Na console, escaneie o QR com o WhatsApp do número que deseja usar. Você obtém um line_id.
2. Crie uma chave de API
Na console, gere uma chave de API. Começa com wzb_live_ e é exibida apenas uma vez.
3. Chame a API
Use seu line_id e sua API key para enviar a primeira mensagem (exemplo abaixo).
curl -X POST https://www.wazion.com/api/bridge/v1/messages/send \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{"line_id":"TU_LINE_ID","to":"+34600000000","message":"Olá do WAzion Bridge"}'
A consola é onde você gerencia linhas, chaves de API e webhooks. A documentação descreve a mesma API que você pode testar lá.
Base da API e autenticação.
| Base REST | https://www.wazion.com/api/bridge/v1 |
|---|---|
| Servidor MCP | https://www.wazion.com/api/bridge/mcp |
| Cabeçalho | Authorization: Bearer wzb_live_... |
Toda solicitação é autenticada com uma chave de API no cabeçalho Authorization (também é aceito X-Bridge-Key). As chaves de API são criadas no console e começam por wzb_live_. Cada resposta inclui um cabeçalho X-Request-Id útil para suporte e depuração. A API suporta CORS (Access-Control-Allow-Origin: *).
Authorization: Bearer wzb_live_xxxxxxxxxxxxxxxxxxxxxxxx Content-Type: application/json
Como está organizado o Bridge.
line_id
Identifique uma linha de WhatsApp conectada por QR. Toda solicitação de envio ou leitura usa um line_id.
API key
Credencial wzb_live_ que autentica sua aplicação. Você pode criar, girar e revogar várias na console.
Webhook
Você recebe eventos de entrada (mensagens, estados) assinados com HMAC na URL que você configurar.
Você sempre trabalha com line_id e chaves de API. O Bridge oculta a sessão interna do WhatsApp: você nunca expõe nem usa a session_key.
Endpoints REST.
| Ação | Endpoint |
|---|---|
| Conta, plano e limites | GET /v1/me |
| Consumo do período | GET /v1/usage |
| Listar linhas | GET /v1/lines |
| Detalhe de uma linha | GET /v1/lines/{line_id} |
| Enviar texto | POST /v1/messages/send |
| Enviar mídia | POST /v1/messages/send-media |
| Responder citando | POST /v1/messages/reply |
| Reagir com emoji | POST /v1/messages/react |
| Marcar como lido | POST /v1/messages/read |
| Arquivar chat | POST /v1/chats/archive |
| Listar chats | GET /v1/chats |
| Ler mensagens | GET /v1/messages |
| Listar / criar webhooks | GET /v1/webhooks · POST /v1/webhooks |
| Testar um webhook | POST /v1/webhooks/{id}/test |
POST /v1/messages/send
| Parâmetro | Tipo | Descrição | |
|---|---|---|---|
line_id | string | obrigatório | Linha conectada a partir da qual é enviado. |
to | string | obrigatório | Telefone de destino em formato internacional, por exemplo, +34600000000. |
message | string | obrigatório | Texto da mensagem. |
archive_policy | enum | opcional | never · always · preserve_if_previously_archived |
Os envios (send, send-media, reply) aceitam o cabeçalho Idempotency-Key. As leituras GET /v1/chats e GET /v1/messages limitam o resultado a 500 e 200, respectivamente.
Enviar uma mensagem na sua língua.
curl -X POST https://www.wazion.com/api/bridge/v1/messages/send \
-H "Authorization: Bearer wzb_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1001" \
-d '{"line_id":"line_xxx","to":"+34600000000","message":"Pedido confirmado"}'
// Node 18+ (fetch nativo)
const res = await fetch("https://www.wazion.com/api/bridge/v1/messages/send", {
method: "POST",
headers: {
"Authorization": "Bearer wzb_live_xxx",
"Content-Type": "application/json",
"Idempotency-Key": "order-1001"
},
body: JSON.stringify({
line_id: "line_xxx",
to: "+34600000000",
message: "Pedido confirmado"
})
});
console.log(await res.json());
import requests
r = requests.post(
"https://www.wazion.com/api/bridge/v1/messages/send",
headers={
"Authorization": "Bearer wzb_live_xxx",
"Idempotency-Key": "order-1001",
},
json={
"line_id": "line_xxx",
"to": "+34600000000",
"message": "Pedido confirmado",
},
)
print(r.json())
<?php
$ch = curl_init("https://www.wazion.com/api/bridge/v1/messages/send");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer wzb_live_xxx",
"Content-Type: application/json",
"Idempotency-Key: order-1001",
],
CURLOPT_POSTFIELDS => json_encode([
"line_id" => "line_xxx",
"to" => "+34600000000",
"message" => "Pedido confirmado",
]),
]);
echo curl_exec($ch);
Enviar imagem, vídeo, áudio ou documento.
Use media_type com um destes valores: image, video, audio, document. O campo media_url deve ser uma URL pública que o servidor possa baixar.
| Parâmetro | Tipo | Descrição | |
|---|---|---|---|
line_id | string | obrigatório | Linha de envio. |
to | string | obrigatório | Telefone de destino. |
media_url | string (URL) | obrigatório | URL pública do arquivo. |
media_type | enum | opcional | image · video · audio · document (por defeito imagem) |
caption | string | opcional | Texto anexado ao arquivo. |
curl -X POST https://www.wazion.com/api/bridge/v1/messages/send-media \
-H "Authorization: Bearer wzb_live_xxx" \
-H "Content-Type: application/json" \
-d '{"line_id":"line_xxx","to":"+34600000000","media_url":"https://tu-cdn.com/foto.jpg","media_type":"image","caption":"Olá"}'
Idempotência.
Para não enviar a mesma mensagem duas vezes (tentativas de rede, reinicializações), envie o cabeçalho. Idempotency-Key com um identificador único da sua operação. Se você repetir a mesma chave com o mesmo corpo, o Bridge devolve a resposta salva sem reenviar. A chave é lembrada por 24 horas e se aplica a send, send-media e reply.
-H "Idempotency-Key: pedido-1001"
Se você reutiliza a mesma chave com um corpo diferente, recebe 409 idempotency_conflict.
Receber eventos assinados.
Crie um webhook com uma URL HTTPS pública. O Bridge enviará um POST para essa URL em cada evento. Cada webhook tem seu próprio segredo. (wzb_whsec_...) que é mostrado uma única vez ao criá-lo.
Eventos que você pode assinar (são entregues exatamente como o motor do WhatsApp os produz): message.received, message.sent, message.status, line.status.
Cada entrega inclui estas cabeçalhos:
X-WAzion-Bridge-Event: message.received
X-WAzion-Bridge-Signature: sha256=<hmac>
Content-Type: application/json
{
"event": "message.received",
"line_id": "line_xxx",
"data": { ... }
}
Verificar a assinatura
A assinatura é um HMAC-SHA256 do corpo em bruto usando o segredo do webhook. Compare sempre antes de processar:
// Node.js
import crypto from "node:crypto";
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
);
}
<?php
// PHP
$raw = file_get_contents("php://input");
$sig = $_SERVER["HTTP_X_WAZION_BRIDGE_SIGNATURE"] ?? "";
$expected = "sha256=" . hash_hmac("sha256", $raw, $secret);
if (!hash_equals($expected, $sig)) { http_response_code(401); exit; }
Você pode lançar um evento de teste para o seu webhook a partir do console ou com POST /v1/webhooks/{id}/test.
Tratamento de erros.
Os erros de autenticação, conta e servidor usam um envelope normalizado:
{
"ok": false,
"error": { "code": "unauthorized", "message": "...", "retryable": false }
}
Os erros de validação e de negócio usam uma forma plana com o código em erro:
{ "error": "quota_exceeded", "message": "Monthly quota exceeded", "metric": "sent_messages", "used": 10000, "limit": 10000, "plan": "pro" }
| Código | HTTP | Significado |
|---|---|---|
unauthorized | 401 | Chave de API ausente, inválida ou revogada. |
subscription_required | 402 | A assinatura Bridge não está ativa. |
validation_error | 400 | Faltam campos ou são inválidos. |
line_not_found | 404 | O line_id não existe na sua conta. |
line_not_connected | 409 | A linha não está conectada ao WhatsApp. |
idempotency_conflict | 409 | Mesma Idempotency-Key com corpo diferente. |
quota_exceeded | 429 | Você superou a cota do período. |
line_limit_reached | 429 | Você atingiu o máximo de linhas do plano. |
server_error | 500 | Erro interno; você pode tentar novamente. |
Cotas por plano.
- As cotas (mensagens enviadas, eventos de webhook, número de linhas) são por conta e são contadas dentro do seu ciclo de faturamento.
- Ao ultrapassar uma cota, você recebe 429 (quota_exceeded ou line_limit_reached) com os detalhes de used, limit e plan.
- GET /v1/chats retorna no máximo 500 chats e GET /v1/messages no máximo 200 mensagens por solicitação.
- Por estabilidade do WhatsApp, os envios de uma mesma linha são espaçados por alguns segundos; distribui os envios em massa ao longo do tempo.
Consulte seu consumo a qualquer momento com GET /v1/usage. Os limites concretos de cada plano estão em a página de planos.
Servidor MCP para o seu agente.
Bridge expõe um servidor MCP (Model Context Protocol) para que seu agente envie e leia WhatsApp sem escrever código REST. Adicione-o com:
claude mcp add --transport http wazion-bridge \ https://www.wazion.com/api/bridge/mcp \ --header "Authorization: Bearer wzb_live_xxx"
| Tool | Parâmetros |
|---|---|
bridge_list_lines | — |
bridge_send_message | line_id, to, message, archive_policy? |
bridge_send_media | line_id, to, media_url, media_type?, caption? |
bridge_reply_message | line_id, to, message, quoted_message_id |
bridge_react_message | line_id, jid, message_id, emoji |
bridge_get_chats | line_id, limit?, archived? |
bridge_get_messages | line_id, phone, limit? |
bridge_archive_chat | line_id, phone, archive? |
Pronto para integrar.
Conecte uma linha, crie sua chave de API e teste cada endpoint a partir do console.