Link wa.me com mensagem pronta e QR code para agentes de IA
Como montar um link do WhatsApp (wa.me) com mensagem pronta, gerar o QR code e descobrir qual usuário escreveu, com TypeScript funcionando e a API da whasp.

O essencial
- Um link wa.me é https://wa.me/ mais o número internacional completo, sem sinal de mais, zeros à esquerda, parênteses nem traços, e ?text= acrescenta uma mensagem codificada em URL que aparece na caixa de texto do usuário.
- O usuário ainda precisa tocar em enviar e pode editar o texto pronto, então um código dentro dele é uma afirmação a conferir nos seus registros, não prova de identidade.
- Com a whasp, GET /v1/numbers/pick devolve o número com mais espaço e um wa_link pronto, então todo chat começa com o usuário escrevendo primeiro.
- Um QR code é o mesmo link codificado, e tudo o que você imprimir deve codificar a URL de um redirect seu, porque os números enchem e podem ser substituídos.
Um link wa.me é a URL de clique para conversar (click to chat) do WhatsApp. O formato é https://wa.me/<número>, com o número em formato internacional completo, sem sinal de mais, zeros à esquerda, parênteses nem traços, e ?text= acrescenta uma primeira mensagem codificada em URL. Tocar no link abre um chat com o número do seu agente, então o usuário escreve primeiro e o agente pode responder.
Qual é o formato do link wa.me com mensagem pronta?
A página de ajuda do clique para conversar do WhatsApp documenta três formas:
https://wa.me/15555550100
https://wa.me/15555550100?text=Oi%20Ava
https://wa.me/?text=Oi%20Ava
A primeira abre um chat com aquele número. A segunda também coloca o texto na caixa de mensagem. A terceira não tem número: o WhatsApp mostra uma lista de contatos para enviar a mensagem, então serve para compartilhar, não para iniciar um chat com o seu agente.
A regra do número nessa página pede um número de telefone completo em formato internacional, sem zeros, parênteses nem traços. O exemplo do que não usar é https://wa.me/+001-(XXX)XXXXXXX. A whasp devolve os números em formato E.164 (+15555550100), então tire o sinal de mais.
Três comportamentos para conhecer:
- O link funciona em celulares e no WhatsApp Web.
- Funciona para um número que não está na agenda do usuário, desde que o número tenha uma conta ativa no WhatsApp.
- O texto pronto cai na caixa de texto. Ele não é enviado. O usuário toca em enviar e pode editar ou apagar o texto antes.
Como montar o link no código?
Tire do número E.164 tudo o que não for dígito e depois codifique o texto em URL. Nunca cole texto cru na URL: um & encerra o parâmetro antes da hora e um # abre um fragmento. O encodeURIComponent resolve os dois casos.
export function waLink(e164: string, text?: string): string {
const digits = e164.replace(/\D/g, "").replace(/^0+/, ""); // "+1 555 555 0100" -> "15555550100"
return `https://wa.me/${digits}` + (text ? `?text=${encodeURIComponent(text)}` : "");
}
Quatro erros para evitar:
- Manter o sinal de mais, um
00à esquerda ou espaços no número. A página do WhatsApp diz para tirá-los. - Pular a codificação, de modo que um
&na mensagem corta o texto. - Montar o link uma vez e guardá-lo em cache. Os números enchem e são substituídos.
- Tratar a mensagem pronta como enviada. Ela fica na caixa de texto até o usuário tocar em enviar.
Mantenha o texto pronto curto e simples. A página do WhatsApp não informa limite de tamanho para ele, mas a Meta limita o texto pronto a 140 caracteres nos seus próprios QR codes e links curtos, um teto sensato para qualquer mensagem de entrada.
Evite emoji nesse texto. Em 19 de outubro de 2026 pedimos links wa.me com emoji em ?text=, e o redirect para api.whatsapp.com/send voltou com o emoji trocado pelo caractere de substituição do Unicode (%EF%BF%BD). As letras latinas acentuadas passaram intactas, e o mesmo texto enviado direto para api.whatsapp.com/send manteve o emoji. Você pode repetir a verificação:
curl -sI "https://wa.me/15555550100?text=Oi%20%F0%9F%91%8B" | grep -i location
O WhatsApp pode mudar isso, então teste em celulares reais antes de contar com qualquer um dos dois comportamentos.
Como fazer um QR code para um link wa.me?
Um QR code de clique para conversar é o próprio link, codificado. Gere-o a partir da URL completa com qualquer biblioteca de QR code e mostre-o em páginas de desktop, onde o usuário não está segurando o celular. A câmera do celular lê um QR code que contém uma URL e oferece abri-la, e o wa.me então passa o chat para o WhatsApp. A documentação da Meta descreve o mesmo fluxo de escanear com a câmera para os QR codes dela.
import QRCode from "qrcode";
const link = waLink("+15555550100", "Oi Ava");
const svg = await QRCode.toString(link, { type: "svg", margin: 2, errorCorrectionLevel: "M" });
await QRCode.toFile("ava.png", link, { width: 512, margin: 2 });
Esse é o pacote qrcode. Use o SVG para impressão, porque ele escala sem borrar (a documentação de QR codes da Meta faz a mesma recomendação), e o PNG para telas. Uma URL mais curta gera um código mais simples, que escaneia melhor. Teste o código impresso no tamanho final, em dois ou três celulares diferentes, antes de encomendar mil adesivos.
Não confunda com os QR codes e links curtos da própria Meta. Esse recurso pertence à WhatsApp Business Platform: até 2.000 por número de telefone comercial, texto pronto de até 140 caracteres, sem análise de escaneamentos, gerenciado pela Business Management API. Um número da whasp é uma conta pessoal de WhatsApp, então você usa links wa.me simples.
Como o agente sabe quem acabou de escrever?
Um evento message.received traz o número de telefone do remetente (chat), o nome dele no WhatsApp (sender_name) e o texto. Não traz o id do seu usuário. Se a pessoa clicou em um botão dentro do seu app, você quer ligar as duas coisas. Coloque um código de uso único no texto pronto.
import { randomBytes } from "node:crypto";
const API = "https://api.whasp.ai/v1";
const pending = new Map<string, { userId: string; expires: number }>(); // use o seu banco de dados
export async function startChat(userId: string) {
const code = randomBytes(3).toString("hex"); // ex.: "9f3a1c"
pending.set(code, { userId, expires: Date.now() + 24 * 60 * 60 * 1000 });
const text = `Oi Ava, meu código é ${code}`;
const res = await fetch(`${API}/numbers/pick?text=${encodeURIComponent(text)}`, {
headers: { Authorization: `Bearer ${process.env.WHASP_API_KEY}` },
});
if (res.status === 409) return null; // no_capacity: todos os números estão cheios, offline ou com a saúde comprometida
if (!res.ok) throw new Error(`whasp answered ${res.status}`);
return (await res.json()) as { number: string; wa_link: string };
}
// No seu handler de message.received: quem é essa pessoa?
export function claimCode(text: string): string | null {
const code = /meu código é ([0-9a-f]{6})\b/i.exec(text)?.[1]?.toLowerCase();
const hit = code ? pending.get(code) : undefined;
if (!code || !hit || hit.expires < Date.now()) return null;
pending.delete(code); // uso único
return hit.userId;
}
Quando claimCode devolve um id de usuário, salve o par: o chat do remetente, o number que recebeu a mensagem e o seu usuário. Dali em diante, identifique essa pessoa pelo número de telefone. O tratamento do webhook em si (checagem da assinatura, deduplicação pelo id do evento) está em Webhook do WhatsApp: assinatura, novas tentativas e duplicatas.
O código é uma afirmação, não uma prova. O usuário pode editar o texto, e qualquer pessoa que receba o link pode enviá-lo. Deixe o código de uso único e de vida curta, mantenha-o opaco (nunca um e-mail nem um token) e nunca ponha um segredo em um link que vai parar no histórico do navegador e em um chat.
Como a whasp escolhe o número do link?
O GET /v1/numbers/pick da whasp devolve o número saudável e online com mais espaço para um novo usuário, mais um wa_link com o seu text já preenchido. Ele responde 409 no_capacity quando todos os números estão cheios, offline ou com a saúde comprometida. Um número aceita até 100 chats ativos em 30 dias e 40 chats novos em 24 horas, e depois sai do pick (as mensagens recebidas continuam chegando). Chame o pick quando o usuário pedir o chat, não na hora do build e não uma vez para uma campanha inteira.
Usuários que voltam devem ir para o mesmo número. O evento message.received inclui o number que o recebeu, e um envio sem from sai do número para o qual a pessoa escreveu por último. Guarde-o junto do usuário e monte o próximo link dele com waLink(number, text).
Os números também mudam. Se o WhatsApp banir um, a whasp o aposenta e entrega um substituto. As conversas não migram, e o número novo não pode escrever primeiro, então um link que aponta para o número antigo está morto. Gere os links sob demanda e leia Número banido no WhatsApp: como migrar usuários para um novo para o roteiro completo. Quantos números de WhatsApp o seu agente de IA precisa? trata da capacidade.
Por que ajuda o usuário escrever primeiro?
Um número da whasp não consegue abrir um chat: um envio para quem nunca escreveu devolve 409 chat_not_open. O link e o QR code são a porta de entrada. Eles também mantêm o número saudável. Desenvolvedores que usam bibliotecas não oficiais relatam o erro 463, o “reachout timelock”, desde pelo menos março de 2026, e a teoria mais comum o liga ao envio de mensagens para pessoas que nunca escreveram. Erro 463 do WhatsApp e o reachout timelock separa o que está confirmado do que é teoria. Com o click to chat, toda conversa começa com uma mensagem recebida, e uma mensagem pronta dá ao agente a primeira entrada na hora.
Onde colocar o link e o QR code?
| Onde | O que mostrar | Por quê |
|---|---|---|
| Página de sucesso do cadastro, no celular | Um botão com o link por usuário | Um toque, com o código incluído |
| Mesma página, no navegador do desktop | Um QR code desse link, ao lado do botão | A câmera do celular faz a passagem |
| E-mail de boas-vindas | Um botão que aponta para a sua própria URL | O link é montado no clique, então nunca expira nem aponta para um número aposentado |
| Impressos, embalagens, perfis em redes sociais | Um QR code da sua própria URL, não do link wa.me | Você pode trocar o número por trás dele sem reimprimir |
Para as duas últimas linhas, aponte para um redirect no seu domínio que pede um número novo à whasp e manda o visitante em frente:
import { createServer } from "node:http";
createServer(async (req, res) => {
if (req.url !== "/chat") return void res.writeHead(404).end();
const pick = await fetch(`https://api.whasp.ai/v1/numbers/pick?text=${encodeURIComponent("Oi Ava")}`, {
headers: { Authorization: `Bearer ${process.env.WHASP_API_KEY}` },
});
if (pick.ok) {
const { wa_link } = (await pick.json()) as { wa_link: string };
res.writeHead(302, { Location: wa_link }).end();
} else {
res.writeHead(503).end("Todos os nossos números estão ocupados. Tente de novo em alguns minutos.");
}
}).listen(3000);
Um visitante anônimo não tem código, então deixe o agente pedir o que precisa depois que o chat estiver aberto. Para um usuário conhecido, como na linha do e-mail, faça o redirect chamar startChat(userId), da seção anterior, em vez de usar um texto fixo. O WhatsApp também publica um botão oficial “Chat on WhatsApp” em verde e branco, e a página de ajuda manda usá-lo sem alterações.
O que fazer agora
Crie um número no painel e siga o quickstart para receber o primeiro evento message.received. Adicione o redirect acima ao seu site, coloque a URL dele atrás de um botão e de um QR code, e teste o caminho completo em um iPhone e em um Android. Se você está construindo um companheiro, Como lançar um companheiro de IA no WhatsApp em 2026 mostra onde esse link se encaixa no onboarding.
Perguntas
Como criar um link do WhatsApp com mensagem pronta?
Use https://wa.me/<número>?text=<texto codificado>, com o número em formato internacional completo e o texto codificado em URL. No código, monte a parte do texto com encodeURIComponent. A mensagem aparece na caixa de texto e o usuário toca em enviar.
O link wa.me funciona se o número não estiver salvo nos contatos do usuário?
Funciona. A página de ajuda do WhatsApp diz que o clique para conversar inicia um chat sem o número salvo na agenda, desde que o número tenha uma conta ativa no WhatsApp. Vale para celulares e para o WhatsApp Web.
Como transformar um link wa.me em QR code?
Um QR code de clique para conversar é só a URL codificada. Passe o link wa.me completo para qualquer biblioteca de QR code, como o pacote qrcode do Node, e exporte SVG para impressão ou PNG para telas.
Posso usar emoji na mensagem pronta de um link wa.me?
Teste antes. Quando verificamos, em 19 de outubro de 2026, o wa.me trocou o emoji do texto por um caractere de substituição, enquanto as letras latinas acentuadas passaram intactas. Texto simples é a escolha segura.
Meu agente na whasp pode mandar mensagem antes de o usuário escrever?
Não. Um número da whasp não consegue abrir um chat a frio e a API responde 409 chat_not_open. O usuário escreve primeiro, e um link wa.me ou um QR code é o jeito de levá-lo a isso.


