Quickstart
Da API key ao primeiro envio e ao primeiro webhook, em poucos passos.
Do zero ao primeiro envio e ao primeiro webhook. Os passos abaixo são o caminho feliz; cada seção do menu detalha as opções.
1. Gere uma API key
Crie sua conta no console do BSP, verifique o e-mail e gere uma API key de tenant. A key aparece uma única vez — copie-a na hora. Depois disso, o console só mostra os últimos 4 caracteres.
A key é um segredo de servidor
sk_tn_… não são keys reais.2. Instale o SDK
npm install @wabroker/sdk3. Instancie o cliente
O único argumento obrigatório do construtor é apiKey — ela vai só no header Authorization, nunca no corpo nem na URL. baseUrl é opcional: por padrão o SDK aponta para https://api.grwthy.com (o SaaS); sobrescreva-a só se você opera um self-host do broker. apiVersion também é opcional (default v1) e compõe o path das chamadas.
import { WaBroker } from '@wabroker/sdk'
const wa = new WaBroker({
apiKey: process.env.WABROKER_API_KEY!, // sk_tn_…
})
// sem baseUrl: aponta para https://api.grwthy.com por padrãoRodando seu próprio broker (self-host) ou testando contra outra versão da API? Sobrescreva baseUrl e/ou apiVersion:
const wa = new WaBroker({
apiKey: process.env.WABROKER_API_KEY!,
baseUrl: 'https://broker.example.com', // self-host — sobrescreve o default
apiVersion: 'v2', // opcional — default 'v1'
})Opções extras
timeoutMs ajusta o teto por requisição (default 15s) e fetch injeta uma implementação própria (útil em testes ou runtimes sem fetch global).4. Conecte um número
Escolha a trilha conforme a kind do número:
Não-oficial (QR) — crie o número sem credenciais e faça polling da conexão até parear:
// 1) inicia a tentativa (ainda NÃO há canal); nasce em 'connecting' sem QR
const attempt = await wa.channels.startConnect({
label: 'Atendimento',
riskAcceptance: { termsVersion: 'unofficial-v1' }, // exigido no não-oficial (senão risk_acceptance_required)
})
// 2) polling do estado até parear — exiba o QR quando o estado for 'scan_qr'
let status = await wa.channels.connectStatus(attempt.attemptId)
while (status.state === 'connecting' || status.state === 'scan_qr') {
if (status.state === 'scan_qr' && status.qr) showQrToUser(status.qr)
await sleep(2000)
status = await wa.channels.connectStatus(attempt.attemptId)
}
if (status.state === 'connected') {
console.log('pareado — canal', status.channelId, 'número', status.number)
}O connectStatus evolui por connecting → scan_qr (traz o qr a exibir/renovar) → connected (traz o channelId e o number reais — o canal só nasce nesse momento, promovido a partir da tentativa). Terminais sem sucesso: expired (TTL da tentativa venceu) e failed (o connector falhou).
Oficial — o caminho recomendado é o Embedded Signup, conduzido pelo seu backend a partir do que o popup do Facebook devolve. Veja meta.embeddedSignupConfig() e meta.completeEmbeddedSignup()na seção Números & conexão.
5. Envie uma mensagem
Envie por um número connected. Endereçe pelo telefone do número (a chave estável — channel.number), não pelo ch_…, que muda se o número for recriado. Toda mensagem exige uma idempotencyKey sua — reenviar a mesma key devolve o resultado do primeiro envio em vez de duplicar. (Um número oficial não tem telefone conectado — nesse caso use channel.id.)
const result = await wa.messages.send(channel.number, {
// 1º arg = o número do canal (E.164 sem '+'), estável; 'to' é o destinatário.
to: '5511999998888',
content: { kind: 'text', text: 'Olá! Sua conta foi criada.' },
idempotencyKey: 'pedido-1234-saiu',
})
console.log(result.messageId, result.state, result.idempotent)Resposta 202
{
"idempotencyKey": "pedido-1234-saiu",
"idempotent": false,
"messageId": "msg_7b3e1d9a2c4f6081",
"state": "queued",
"traceId": "tr_2f8b6d0a4c1e3597"
}6. Receba um webhook
Configure a URL do seu endpoint e um segredo (veja Autenticação e Webhooks). O broker entrega eventos assinados; verifique a assinatura com verifyAndParse antes de confiar no corpo:
import { verifyAndParse } from '@wabroker/sdk'
// Handler HTTP (Express-like). rawBody é o TEXTO CRU — não reserialize.
app.post('/webhooks/wabroker', (req, res) => {
try {
const event = verifyAndParse(req.rawBody, req.headers, process.env.WABROKER_WEBHOOK_SECRET!)
// event.type já é tipado: message.received, message.status, ...
handleEvent(event)
res.sendStatus(200)
} catch {
res.sendStatus(400) // assinatura inválida ou corpo malformado
}
})Próximos passos
- Autenticação — rotacione e revogue keys com segurança.
- Enviar mensagens — mídia, templates e envio em lote.
- Webhooks — todos os eventos e os detalhes da verificação HMAC.
- Erros — a taxonomia de códigos e como tratar cada um.