Quickstart
Objetivo: sair de "sem conta" até "mensagem de WhatsApp enviada" em cinco passos. Aqui a gente usa curl. As mesmas chamadas funcionam em qualquer cliente HTTP.
Você vai precisar de uma conta real de WhatsApp para escanear o QR. Use um número secundário — o gateway abre uma sessão do WhatsApp Web nele, igual à aba do WhatsApp Web no seu navegador.
1 · Pegue uma chave de API
Entre no dashboard em https://app.whatisup.dev. Há três provedores de login suportados:
- E-mail + senha — instantâneo, sem terceiros.
- Google — OAuth em um clique.
- GitHub — OAuth em um clique, pede
read:user+user:emailpara a gente ter seu nome + e-mail no cadastro de cliente.
Escolha o que preferir. Se você se cadastrar por um provedor e depois entrar por outro usando o mesmo e-mail, o dashboard vincula os dois de forma transparente para você manter um único cadastro de cliente.
Depois Configurações → Chaves de API → Criar. Copie a chave — ela só é mostrada uma vez. Defina como variável de ambiente para os trechos abaixo funcionarem como estão:
export WHATISUP_API_KEY=zpk_••••••••
export WHATISUP_API=https://api.whatisup.dev2 · Crie um canal
Um canal é uma conexão lógica de WhatsApp. Cada um ganha seu próprio QR.
curl -sX POST "$WHATISUP_API/v1/channels" \
-H "Authorization: Bearer $WHATISUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"primary"}'Você vai receber algo assim de volta:
{
"id": "8d653c66-e4ff-43ee-97da-3de5ad5680d4",
"customer_id": "2696bc9b-2e37-43d9-a33b-5a79f81daeba",
"name": "primary",
"phone_number": null,
"status": "pending",
"last_seen_at": null,
"metadata": {},
"created_at": "2026-05-01T12:34:56.000Z",
"updated_at": "2026-05-01T12:34:56.000Z"
}Responde 201. status: "pending" significa que o gateway ainda não iniciou
uma sessão, e phone_number fica null até o pareamento terminar. Anote o id
— um UUID v4 — você vai usá-lo em tudo abaixo como CHANNEL_ID:
export CHANNEL_ID=8d653c66-e4ff-43ee-97da-3de5ad5680d4Multi-tenant? Passe "issue_scoped_key": true nesta chamada e a resposta traz
também scoped_key.secret — uma chave de API que só alcança este canal.
Mostrada uma vez, nunca mais legível.
3 · Pegue o código QR
Chame o endpoint de QR até ele retornar um. O canal inicia uma sessão na primeira busca de QR.
curl -s "$WHATISUP_API/v1/channels/:id/qr" \
-H "Authorization: Bearer $WHATISUP_API_KEY"A resposta carrega exatamente dois campos:
{
"qr_png_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
"expires_at": 1779425257573
}| Campo | Tipo | Notas |
|---|---|---|
qr_png_base64 | string | Base64 pura de um PNG. Sem prefixo data: — coloque o seu. |
expires_at | number | Epoch Unix em milissegundos, não uma string ISO. |
Não existe raw / string de formato de rede na resposta. Para ver:
curl -s -H "Authorization: Bearer $WHATISUP_API_KEY" \
"$WHATISUP_API/v1/channels/$CHANNEL_ID/qr" \
| jq -r .qr_png_base64 | base64 -d > qr.png && open qr.pngEscaneie pelo WhatsApp → Configurações → Aparelhos conectados → Conectar um aparelho.
Se o canal ainda não tem QR, você recebe 409 no_qr — essa é a resposta
normal de "tente de novo em instantes" enquanto a sessão sobe, não um erro para
abortar.
Prefere não escanear? POST /v1/channels/$CHANNEL_ID/pair-code com
{"phone_number":"5511999999999"} devolve um código de 8 caracteres que você
digita no WhatsApp → Aparelhos conectados → Conectar com número de telefone.
A interface do dashboard faz isso para você em tempo real via SSE. Se você prefere não lidar com o encanamento do QR na mão, aponte o dashboard para o seu gateway e clique em Parear.
4 · Espere por connected
Consulte o canal até o status virar connected:
curl -s "$WHATISUP_API/v1/channels/:id" \
-H "Authorization: Bearer $WHATISUP_API_KEY"…ou, bem melhor, assine os Server-Sent Events e reaja ao channel.connected:
curl -s "$WHATISUP_API/v1/events" \
-H "Authorization: Bearer $WHATISUP_API_KEY"5 · Envie sua primeira mensagem
curl -sX POST "$WHATISUP_API/v1/channels/:id/messages" \
-H "Authorization: Bearer $WHATISUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"text","to":"5511999999999@s.whatsapp.net","text":"Hello from WhatIsUp.dev"}'to é um JID do WhatsApp — <dígitos>@s.whatsapp.net (código do país + número
nacional, sem +, depois @s.whatsapp.net). O gateway retorna 202:
{
"message_id": "3EB0C9A17F2B4D8E1A05",
"client_ref": null,
"status": "sent"
}status é "sent" quando o canal estava conectado e o WhatsApp aceitou a
mensagem, ou "queued" quando o canal estava em recuperação e vamos retentar.
Nos dois casos você recebe o mesmo message_id, e um webhook message.sent
dispara no sucesso.
Para acompanhar a entrega depois, use o webhook message.status (sent →
delivered → read), ou leia GET /v1/messages — o gateway mantém sim um
histórico de mensagens paginável, com corpos e as entregas de webhook que
carregaram cada uma.
Para onde ir agora
- Conecte um webhook para parar de ficar consultando: Conceitos → Webhooks.
- Verifique assinaturas de webhook: Webhooks → Verificação de assinatura.
- Explore a superfície REST completa: Referência da API → Canais.