Sign inGet Started

Enviando verificações

Verificar um usuário exige duas chamadas. POST /v1/verify/verifications envia um código de verificação para um endereço de e-mail ou número de telefone. POST /v1/verify/verifications/check submete o valor que o usuário digitou e informa se houve correspondência. Bird gera o código, não o retorna em uma resposta API e aplica os limites de expiração e tentativas.

Enviar um código

A menor solicitação válida é um destinatário to:

const verification = await bird.verify.verifications.create({
  to: { phone_number: "+15551234567" },
});
console.log(verification.id, verification.status);

Use seu host regional (https://us1.platform.bird.com ou https://eu1.platform.bird.com) com uma chave bk_{region}_... correspondente.

Destinatário

to identifica o destinatário com um email, um phone_number no formato E.164, ou ambos. Um endereço de e-mail habilita a entrega por e-mail. Um número de telefone resolve para os canais disponíveis no país de destino, na ordem definida pela configuração de país. A maioria dos países tenta WhatsApp antes de SMS, enquanto alguns tentam SMS primeiro; o Telegram segue ambos na ordem de fallback da plataforma. Quando você fornece os dois endereços, uma tentativa que falhou pode avançar para outro canal disponível.

Opções

options sobrepõe configurações apenas para esta solicitação:

  • code_length: comprimento do código de verificação para esta verificação, 4 a 8 dígitos, sobrepondo o padrão.
  • channels: reordena ou restringe os canais de entrega para esta solicitação. Liste os nomes dos canais (sms, whatsapp, email, telegram) na ordem em que devem ser tentados; um canal omitido não é usado, e um nome que não faz parte do plano resolvido do destinatário é ignorado. Você não pode adicionar um canal dessa forma, apenas reduzir ou reordenar o que o destinatário e a configuração de país já permitem, e uma lista que não deixe nenhum canal utilizável faz a solicitação falhar com 422.
  • language: uma tag BCP 47 como fr ou pt-BR que escolhe qual tradução integrada a mensagem com o código usa. Omita-a e o idioma segue o número de telefone do destinatário; veja Idioma da mensagem.

Metadados

metadata é um objeto de formato livre retornado em toda leitura; use-o para carregar seu próprio ID de usuário ou referência de sessão. As escolhas de remetente e as configurações de verificação não vão na solicitação: elas vêm da configuração do seu espaço de trabalho, gerenciada no painel (veja Configurações de verificação).

A resposta

Exemplo de código
{
  "id": "vrf_01ky7q1fdze3695yvyz7z9nm3a",
  "status": "pending",
  "reason": null,
  "to": { "phone_number": "+15551234567" },
  "channels": [{ "channel": "whatsapp" }, { "channel": "sms" }],
  "last_channel": "whatsapp",
  "expires_at": "2026-07-23T14:55:58Z",
  "verified_at": null,
  "created_at": "2026-07-23T14:45:58Z",
  "updated_at": "2026-07-23T14:45:58Z"
}

channels é o plano de entrega ordenado para o qual esta verificação resolveu (um destinatário telefônico lista seus canais de telefone na ordem de tentativa), e last_channel é para onde o código mais recente foi enviado. expires_at é quando a verificação expira se nenhum código correto chegar; reenvios não estendem esse prazo.

Idioma da mensagem

As mensagens de SMS, e-mail e WhatsApp compartilhado do Bird são enviadas com 40 traduções integradas. Um remetente WhatsApp personalizado usa os idiomas aprovados do template de autenticação selecionado. O Telegram escreve a própria mensagem, então a configuração não tem efeito nesse canal.

Sem options.language, o idioma vem do número de telefone do destinatário. Um número francês recebe francês e um número japonês recebe japonês, sem que você precise pedir. Uma verificação sem número de telefone envia em inglês, assim como uma cujo país não tem tradução.

Defina options.language para escolher você mesmo, por exemplo para usar o idioma que o usuário selecionou no seu aplicativo em vez do país do número dele:

Exemplo de código
{
  "to": { "phone_number": "+15551234567" },
  "options": { "language": "es" }
}

Uma tag sem tradução integrada própria recorre ao idioma base e, depois, ao inglês: en-GB envia em inglês, pt-BR envia em português. Apenas uma tag malformada é rejeitada, com 422. Estas são as traduções integradas disponíveis, todas em SMS e e-mail, e todas exceto mongol no remetente WhatsApp compartilhado do Bird:

IdiomaTag
Árabear
Búlgarobg
Chinês (simplificado)zh
Chinês (tradicional)zh-TW
Croatahr
Tchecocs
Dinamarquêsda
Holandêsnl
Inglêsen
Finlandêsfi
Francêsfr
Alemãode
Gregoel
Hebraicohe
Hindihi
Húngarohu
Indonésioid
Italianoit
Japonêsja
Coreanoko
Letãolv
Lituanolt
Macedôniomk
Malaioms
Mongolmn
Norueguêsno
Norueguês Bokmålnb-NO
Polonêspl
Portuguêspt
Romenoro
Russoru
Sérviosr
Eslovacosk
Eslovenosl
Espanholes
Suecosv
Tailandêsth
Turcotr
Ucranianouk
Vietnamitavi

A referência de criação de verificação é a lista oficial.

O idioma é fixado quando a verificação é criada, então um reenvio ou uma troca para outro canal chega no mesmo idioma da primeira mensagem. Chamar create novamente para o mesmo destinatário com um language diferente reutiliza a verificação em andamento e não a altera.

A tradução usada no envio pode diferir da tag que você enviou quando houve fallback. Abra a verificação na página Verificações para confirmar: cada tentativa mostra o idioma renderizado como uma tag Template. O remetente WhatsApp compartilhado do Bird não tem template de mongol (mn), então envia em inglês para esse idioma, enquanto SMS e e-mail mantêm o mongol. Seu próprio template WhatsApp segue os idiomas aprovados e a política de idioma; um idioma que ele não consegue enviar pode fazer a tentativa WhatsApp falhar.

Você pode selecionar um idioma por solicitação, mas não pode enviar o texto da mensagem nessa solicitação. Um remetente WhatsApp personalizado usa o texto do template de autenticação selecionado. Remetentes e identidade visual mostra as opções de remetente e o texto da mensagem do Bird.

Verificar o código

Envie o que o usuário digitou para POST /v1/verify/verifications/check, usando o mesmo destinatário; não é necessário ID de verificação. Forneça exatamente o conjunto de to com que você criou a verificação: uma criada com ambos os endereços não é encontrada por nenhum dos endereços isoladamente.

const result = await bird.verify.verifications.check({
  to: { phone_number: "+15551234567" },
  code: "123456",
});
console.log(result.success);

A resposta indica se houve correspondência:

Exemplo de código
{
  "success": false,
  "reason": "incorrect_code",
  "attempts_remaining": 4,
  "verification": {
    "id": "vrf_01ky7q1fdze3695yvyz7z9nm3a",
    "status": "pending",
    "reason": null,
    "to": { "phone_number": "+15551234567" },
    "channels": [{ "channel": "whatsapp" }, { "channel": "sms" }],
    "last_channel": "whatsapp",
    "expires_at": "2026-07-23T14:55:58Z",
    "verified_at": null,
    "created_at": "2026-07-23T14:45:58Z",
    "updated_at": "2026-07-23T14:46:38Z"
  }
}

Trate estes dois comportamentos de resposta:

  • Um código errado retorna 200. Trate success: false com um reason (incorrect_code, expired, attempts_exhausted) como uma resposta normal. attempts_remaining informa quantas tentativas restam. Reserve o tratamento de erros para falhas na solicitação.
  • Uma verificação final não pode ser checada novamente. Depois que uma verificação atinge qualquer estado final, novas checagens retornam 404. Armazene o primeiro resultado definitivo em vez de checar novamente.

Se o usuário pediu um novo código, chame o endpoint de criação novamente com o mesmo destinatário: a verificação em andamento é reutilizada em vez de substituída. Quando o intervalo de reenvio expirar (60 segundos por padrão), um novo código é enviado; dentro do intervalo, a chamada retorna a verificação ativa sem enviar novamente. Todo código enviado para a verificação ativa permanece válido até que ela seja resolvida ou expire, então o usuário pode digitar qualquer um que tenha chegado.

Enviar o código por outro canal

Quando o usuário informa que nenhum código chegou, POST /v1/verify/verifications/next-channel avança a verificação para o próximo canal no plano e envia um novo código por lá. Este é o endpoint por trás de um botão "I didn't receive my code": seu aplicativo decide trocar de canal em vez de esperar um sinal de status de entrega.

Use o mesmo destinatário com que você criou a verificação, assim como na checagem:

const verification = await bird.verify.verifications.nextChannel({
  to: { phone_number: "+15551234567" },
});
console.log(verification.last_channel);

A resposta é a verificação, com last_channel indicando o canal para o qual o novo código foi enviado. Todo código já enviado permanece válido, então uma mensagem que chegue atrasada ainda pode ser checada.

Duas coisas diferenciam isso de um reenvio:

  • O intervalo de reenvio não se aplica. Uma troca deliberada de canal é um ato diferente de pedir o mesmo canal novamente, então o envio sai imediatamente.
  • Apenas o canal avança. A expiração, o limite de tentativas e o ID da verificação permanecem como estavam.

Use um reenvio quando o usuário quer outra tentativa em um canal que funciona, e este endpoint quando o próprio canal parece ser o problema. Um número de telefone cujo plano é WhatsApp e depois SMS avança para SMS; um destinatário com apenas um canal utilizável não tem para onde ir.

Quatro respostas precisam de tratamento em vez de uma simples nova tentativa:

StatusO que aconteceuO que fazer
404Não há verificação em andamento para esse destinatárioCrie uma
422 NoNextChannelO plano não tem mais nenhum canal para avançarReenvie no canal atual chamando create novamente
422 NoAvailableChannelTodos os canais restantes falharam ao enviarMostre a falha ao usuário; a verificação não pode ser entregue
429Envios para a conta estão sendo solicitados rápido demaisAguarde o período indicado no header Retry-After

Cada código enviado por este endpoint é cobrado como qualquer outro envio do Verify; veja Custo e cobrança.

Status

Uma verificação fica pending até ser resolvida em um estado final, com reason indicando o motivo:

StatusSignificadoRazão
verifiedUm código correto chegou a temponenhuma
failedTentativas incorretas demais, ou o plano de entrega terminou com falhas indicando que nenhum código de verificação foi enviadoattempts_exhausted, undeliverable
expiredA janela expirou antes de um código corretottl_elapsed

reason é um enum aberto. Preserve um valor não reconhecido em vez de tratar a resposta como inválida.

Um bounce, rejeição da operadora ou timeout de entrega pode deixar a sessão pendente porque o destinatário ainda pode ter um código válido. O esgotamento do plano de entrega por si só não significa que a sessão falhou. Consulte Eventos do Verify para as condições de falha.

Acompanhe verificações no dashboard

A página Verifications lista todas as verificações que o espaço de trabalho criou, filtrável por status. Cada linha abre o destinatário, plano de canais, último canal, horários de expiração e verificação, e metadados. O código gerado não é exibido.

A página Verifications listando verificações com colunas de status, destinatário, canal e horário de criação

Configurações de verificação

A página Configure define o ciclo de verificação do espaço de trabalho. Cada campo mostra o valor efetivo: sua substituição onde você definiu uma, caso contrário o padrão de plataforma do Bird.

  • Duration: por quanto tempo um código permanece válido. Padrão 10 minutos; 1 minuto a 999 minutos.
  • Maximum Retries: quantas tentativas de verificação antes que a verificação falhe com attempts_exhausted. Padrão 5; 1 a 10.
  • Retry Delay: o intervalo de espera antes que um novo código possa ser enviado ao mesmo destinatário. Padrão 60 segundos; 0 a 3.600.

A aba General da página Configure com os campos Duration, Maximum Retries e Retry Delay

O tamanho do código não é um campo nesta página: os códigos têm 6 dígitos numéricos por padrão, e options.code_length define de 4 a 8 dígitos por solicitação.

Proteções contra abuso

Independentemente das suas configurações, o Verify impõe limites de plataforma para impedir que o tráfego de OTP seja explorado, seja contra a sua carteira (bombeamento de SMS) ou contra a caixa de entrada de uma vítima:

  • 5 envios por endereço por hora corrida, entre iniciar e reenviar verificações. Quando to contém ambos os endereços, cada um tem seu próprio orçamento.
  • 10 verificações por conjunto de endereços do destinatário por minuto, além do limite de tentativas da verificação.

O plano de canais, e não o limite por hora, delimita as trocas de canal. Cada chamada avança estritamente para frente, então uma verificação envia no máximo uma vez por canal restante.

Atingir um limite retorna 429; aguarde e tente novamente após o período no cabeçalho Retry-After. Os limites gerais de solicitação da sua conta são separados e proporcionais ao plano; consulte Limites de requisições.

Tentando novamente com segurança

Os três endpoints aceitam o cabeçalho Idempotency-Key. Envie um valor único por solicitação lógica. Após um timeout ou conexão perdida, tentar novamente com a mesma chave reproduz a resposta original. Uma reprodução não envia outro código nem consome outra tentativa de verificação, e inclui um cabeçalho Idempotency-Replay. Consulte idempotência para formato e retenção da chave.

Custo e cobrança

A cobrança se aplica a cada código enviado. Cada código enviado é debitado da sua carteira pela tarifa do canal para o destino. Um reenvio ou fallback para outro canal adiciona uma cobrança por envio. A taxa própria do Bird é cobrada enquanto o envio é processado e vale independentemente de o código chegar; no SMS e no WhatsApp uma taxa de terceiros vem em seguida quando a mensagem é entregue. Rotas gratuitas e verificações não custam nada; um envio rejeitado antes da cobrança não é cobrado. Métodos de pagamento e carteira cobre saldo e recargas.

O Telegram cobra em um ponto diferente do envio. Antes de uma mensagem sair, o Telegram é consultado sobre se o número pode recebê-la; a cobrança é vinculada quando a resposta é sim, a uma tarifa fixa mundial, e um número que não pode ser alcançado é gratuito e avança para o próximo canal sem cobrança. Portanto, uma cobrança do Telegram significa que a mensagem foi aceita para entrega, não que chegou: um código que depois não é entregue continua cobrado, e a verificação paga novamente pelo canal para o qual cai. Quando você não quer essa segunda cobrança, remova o Telegram da ordem de canais para esses países na página Countries.

Próximos passos

PáginaO que cobre
Remetentes e identidade visualComo são as mensagens de código e como enviar a partir do seu próprio domínio
Configuração por paísOrdem de canais por país, habilitação e substituições de remetente
EventosO ciclo de vida da verificação e os eventos de entrega, e seus payloads de webhook
IdempotênciaTentativas seguras com o cabeçalho Idempotency-Key
Referência API: criar uma verificaçãoSchema e detalhes de erro do endpoint de envio
Referência API: verificar um códigoSchema e detalhes de erro do endpoint de verificação
Referência API: avançar para o próximo canalSchema e detalhes de erro do próximo canal