Atualizado em 25/10/2026
Para enviar código de verificação (OTP) pelo WhatsApp, a Meta exige um template de autenticação: texto pré-definido (“123456 é seu código de verificação.”), um botão de OTP (copiar código, preenchimento com um toque ou zero-tap) e nenhuma URL, mídia ou emoji. Você cria o template uma vez, a Meta aprova e, a cada login, sua aplicação envia o código como parâmetro. Para destinatários no Brasil, cada mensagem de autenticação entregue custa R$ 0,0350 na tabela em reais em vigor desde 1º de outubro de 2026, com desconto por volume.
Este guia mostra os três tipos de botão, os payloads de criação e envio, como configurar validade e TTL e os cuidados de segurança que a Meta recomenda.
Por que precisa ser template de autenticação
A Meta é explícita: só templates de autenticação podem enviar senha de uso único para verificar identidade. Marketing e utilidade não podem. Se a Meta detectar um template de outra categoria sendo usado para isso, ela avisa e muda o status dele para REJECTED no primeiro dia do mês seguinte, sem direito a revisão. As regras completas de categoria estão em como a Meta classifica seu template.
Para ser classificado como autenticação, o template precisa:
- usar os modelos de autenticação da Cloud API, com texto fixo definido pela Meta;
- ter um botão de OTP;
- não ter URL, mídia nem emoji, no conteúdo ou nos parâmetros;
- usar parâmetros de no máximo 15 caracteres.
Casos de uso aceitos: criação de conta, recuperação ou integridade de acesso e confirmação de pedidos ou transações.
O texto é fixo: o que você pode configurar
O corpo não é escrito por você. A Meta usa um texto pré-definido, traduzido para o idioma do template, e permite dois complementos opcionais:
| Opção | Campo | Efeito |
|---|---|---|
| Aviso de segurança | add_security_recommendation: true no corpo | Acrescenta uma frase pedindo para não compartilhar o código |
| Validade do código | code_expiration_minutes no rodapé (1 a 90) | Acrescenta no rodapé o aviso de que o código expira em N minutos |
| Tempo de vida da mensagem | message_send_ttl_seconds (30 a 900) | Se não for entregue nesse prazo, a mensagem é descartada |
O TTL padrão de templates de autenticação é de 10 minutos (templates criados antes de 23 de outubro de 2024 tinham 30 dias). A Meta recomenda um TTL igual ou menor que a validade do código: não faz sentido entregar um código que já expirou. Como a Meta só cobra mensagens entregues, mensagens descartadas pelo TTL não entram na conta.
Os três tipos de botão
| Tipo | Como funciona | Plataforma | Exige integração no app? |
|---|---|---|---|
Copiar código (COPY_CODE) | O usuário toca no botão, o código vai para a área de transferência e ele cola no app | Todas | Não |
Um toque (ONE_TAP) | O botão abre o seu app já com o código preenchido | Android | Sim: handshake e activity para receber o código |
Zero-tap (ZERO_TAP) | Sem botão: o app recebe o código por broadcast e o usuário nem sai da tela | Android | Sim: handshake, broadcast receiver e aceite de termos |
No iOS 26 ou superior, o próprio teclado sugere o código recebido no WhatsApp, sem integração. Em versões anteriores do iOS, o usuário vê o botão de copiar código.
Um ponto importante: one-tap e zero-tap têm fallback. Se o handshake não aconteceu, se o app não confere ou se o destinatário não está no Android, o WhatsApp mostra o botão de copiar código (e, no zero-tap, tenta primeiro o one-tap). Por isso, um template one-tap ou zero-tap sempre funciona como copiar código no pior caso.
Criando o template com botão de copiar código
Na Cloud API direta, o template é criado no endpoint message_templates da conta do WhatsApp Business:
curl -X POST "https://graph.facebook.com/v26.0/SEU_WABA_ID/message_templates" \
-H "Authorization: Bearer TOKEN_DA_META" \
-H "Content-Type: application/json" \
-d '{
"name": "codigo_verificacao",
"language": "pt_BR",
"category": "AUTHENTICATION",
"message_send_ttl_seconds": 300,
"components": [
{ "type": "BODY", "add_security_recommendation": true },
{ "type": "FOOTER", "code_expiration_minutes": 5 },
{
"type": "BUTTONS",
"buttons": [
{ "type": "OTP", "otp_type": "COPY_CODE", "text": "Copiar código" }
]
}
]
}'
Repare que não há campo text no corpo: a Meta preenche. O rótulo do botão (text) tem até 25 caracteres e é opcional; sem ele, a Meta usa um rótulo padrão traduzido. Depois da criação, o botão OTP aparece como tipo URL quando você consulta o template, e isso é esperado.
Variação one-tap (Android)
Para one-tap, troque o botão e informe os apps autorizados:
{
"type": "OTP",
"otp_type": "ONE_TAP",
"text": "Copiar código",
"autofill_text": "Preencher",
"supported_apps": [
{ "package_name": "br.com.exemplo.app", "signature_hash": "K8a/AINcGX7" }
]
}
Regras do one-tap, segundo a documentação de autofill:
supported_appsaceita até 5 pares de pacote e hash;package_nametem até 224 caracteres, com pelo menos dois segmentos separados por ponto;signature_hashtem exatamente 11 caracteres;autofill_textetexttêm até 25 caracteres;- o app precisa iniciar um handshake com o WhatsApp antes do envio e ter uma activity com a ação
com.whatsapp.otp.OTP_RETRIEVED; - o handshake vale por 10 minutos, ou pelo tempo de
code_expiration_minutes, se definido.
A Meta recomenda o SDK oficial para o handshake. O método baseado em PendingIntent está sendo descontinuado em 15 de outubro de 2026.
Variação zero-tap (Android)
O zero-tap usa "otp_type": "ZERO_TAP", os mesmos supported_apps e o campo zero_tap_terms_accepted: true. Sem esse aceite, o template não é criado. O app precisa de um broadcast receiver para com.whatsapp.otp.OTP_RETRIEVED. Mesmo no zero-tap, o usuário vê no WhatsApp a mensagem com o texto fixo.
Para depurar one-tap e zero-tap no Android, o WhatsApp envia sinais de erro por broadcast com a ação com.whatsapp.OTP_ERROR, com chaves como otp_request_expired e missing_handshake_or_disorder.
Enviando o código
O envio é um template comum, com uma particularidade: o código aparece duas vezes, no parâmetro do corpo e no parâmetro do botão. O código tem no máximo 15 caracteres.
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "5584999999999",
"type": "template",
"template": {
"name": "codigo_verificacao",
"language": { "code": "pt_BR" },
"components": [
{
"type": "body",
"parameters": [{ "type": "text", "text": "482913" }]
},
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [{ "type": "text", "text": "482913" }]
}
]
}
}
Um exemplo de função em Node.js que gera o código, guarda o hash e envia:
import crypto from 'node:crypto';
export async function enviarOtp(telefone, db) {
const codigo = String(crypto.randomInt(0, 1_000_000)).padStart(6, '0');
const hash = crypto.createHash('sha256').update(codigo).digest('hex');
await db.salvarOtp(telefone, hash, Date.now() + 5 * 60 * 1000); // 5 minutos
const corpo = {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to: telefone,
type: 'template',
template: {
name: 'codigo_verificacao',
language: { code: 'pt_BR' },
components: [
{ type: 'body', parameters: [{ type: 'text', text: codigo }] },
{ type: 'button', sub_type: 'url', index: '0', parameters: [{ type: 'text', text: codigo }] },
],
},
};
const r = await fetch(process.env.WHATSAPP_URL, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify(corpo),
});
return r.json(); // guarde o wamid para cruzar com o webhook de status
}
Acompanhe o status pelo webhook: se o delivered não chegar dentro do TTL, considere a mensagem descartada e ofereça outro canal. Os estados possíveis estão em status de mensagem via webhook.
Segurança: o que a Meta recomenda
A página de boas práticas de autenticação traz alguns cuidados que vale levar a sério:
- Número reciclado. O WhatsApp só verifica a posse do número no registro. Um número pode mudar de dono. Na Cloud API, guarde o hash de identidade recebido depois do primeiro OTP validado e inclua-o nos envios seguintes: se o número for de outra pessoa, a entrega falha em vez de chegar ao novo dono.
- Desafio extra em fluxos sensíveis. Para recuperação de conta, combine o código do WhatsApp com outra verificação.
- Encaminhamento bloqueado. O WhatsApp desativa o encaminhamento de mensagens de autenticação, o que reduz phishing.
- Escolha do canal. Peça consentimento e ofereça opções (WhatsApp, e-mail, SMS). Confirme com o usuário qual número ele usa no WhatsApp, que pode ser diferente do número do SMS.
- WhatsApp instalado. No Android, verifique os pacotes
com.whatsappecom.whatsapp.w4b; no iOS, se o esquemawhatsapp://otppode ser aberto. - Uma conta por empresa. Cada empresa precisa da própria conta, conta de mensagens e número. Compartilhar entre empresas viola a política.
Quanto custa cada código
A Meta cobra autenticação por mensagem entregue. Para destinatários no Brasil, a tabela em reais em vigor desde 1º de outubro de 2026 tem desconto progressivo por volume mensal, somado em todas as contas do portfólio:
| Mensagens de autenticação por mês (Brasil) | Preço por mensagem (BRL) |
|---|---|
| Até 500.000 | R$ 0,0350 |
| 500.001 a 3.000.000 | R$ 0,0333 |
| 3.000.001 a 5.250.000 | R$ 0,0315 |
| 5.250.001 a 10.000.000 | R$ 0,0298 |
| 10.000.001 a 20.000.000 | R$ 0,0280 |
| Acima de 20.000.000 | R$ 0,0263 |
As faixas zeram todo mês. A tarifa de autenticação internacional, cobrada em alguns mercados, não se aplica ao Brasil. Mensagens enviadas dentro de uma janela de ponto de entrada gratuito, aberta por anúncios de clique para o WhatsApp, não são cobradas. Para simular volumes, veja quanto custa uma campanha no WhatsApp e o artigo de preços da API no Brasil.
Como fazer com a Vectalk
Na Vectalk, o template de autenticação é criado em POST /api/templates com o mesmo corpo da Meta, usando um token de instância:
curl -X POST https://apis.vectalk.com.br/api/templates \
-H "Authorization: Bearer SEU_TOKEN_DE_INSTANCIA" \
-H "Content-Type: application/json" \
-d '{
"name": "codigo_verificacao",
"language": "pt_BR",
"category": "AUTHENTICATION",
"components": [
{ "type": "BODY", "add_security_recommendation": true },
{ "type": "FOOTER", "code_expiration_minutes": 5 },
{ "type": "BUTTONS", "buttons": [ { "type": "OTP", "otp_type": "COPY_CODE", "text": "Copiar código" } ] }
]
}'
O envio usa POST https://apis.vectalk.com.br/api/messages com o payload da seção anterior. No código Node.js acima, basta apontar WHATSAPP_URL para esse endpoint e usar o token da Vectalk. Veja a documentação de templates, crie sua conta em apps.vectalk.com.br/register e, se estiver começando, leia o guia da API oficial do WhatsApp.
Perguntas frequentes
Posso escrever meu próprio texto no código de verificação?
Não. O texto do template de autenticação é pré-definido pela Meta. Você só escolhe o idioma, se inclui o aviso de segurança, a validade em minutos e o rótulo dos botões.
O código pode ter letras?
Sim, a Meta fala em códigos geralmente alfanuméricos. O limite é de 15 caracteres por parâmetro, e o mesmo valor vai no corpo e no botão.
O one-tap funciona no iPhone?
Não. One-tap e zero-tap são exclusivos do Android. No iPhone, o usuário vê o botão de copiar código; no iOS 26 ou superior, o teclado também sugere o código automaticamente.
Preciso de template diferente para cada idioma?
Sim. Cada idioma é um template. Na criação em massa da Meta, o endpoint upsert_message_templates aceita uma lista de idiomas de uma vez.
Um template de autenticação pode ser reprovado?
Sim, por formato ou parâmetros inválidos. Ele não sofre a regra de duplicidade, já que o texto é padrão. Veja template reprovado no WhatsApp.
Fontes oficiais consultadas em 25/10/2026: Templates de autenticação, Botão de copiar código, Botão one-tap, Zero-tap, Sinais de erro, Boas práticas de autenticação, Time-to-live, Categorização de templates, Preços e planilha “Níveis de volume em BRL” (vigência 1º/10/2026).
