apumail / blog

Como agentes de IA recebem códigos de verificação OTP

A verificação por e-mail é o primeiro muro que quase todo agente autônomo encontra. O formulário de cadastro é fácil. Os seis dígitos parados numa caixa de entrada que o agente não tem, não.

14 de julho de 2026

Um agente se cadastrando num serviço consegue talvez quarenta segundos de trabalho útil antes de chegar a uma tela que diz enviamos um código para o seu e-mail. Tudo o que vem depois depende de uma maquinaria que o agente normalmente não tem: um endereço que aceite e-mail, um jeito de saber que o e-mail chegou e um jeito de tirar seis dígitos de uma sopa de HTML escrita para o olho humano.

Há três tarefas escondidas nessa frase, e vale separá-las, porque a maior parte da dor vem de resolvê-las na ordem errada.

1. Um endereço que existe antes de você precisar dele

A abordagem ingênua é ligar o agente a uma caixa postal real: uma conta do Gmail com senha de app, ou uma conexão IMAP com uma caixa compartilhada do time. Funciona exatamente até você ter dois agentes. Aí um lê os códigos do outro, e a falha é não determinística e um tormento para depurar.

O que você realmente quer é um endereço descartável por agente e por tarefa, criado no momento em que é necessário e jogado fora depois. Isso significa que criá-lo tem que ser barato o bastante para fazer inline: sem painel, sem API key, sem humano no loop:

INBOX=$(curl -sS -X POST https://api.apumail.com/api/v1/inboxes)
ADDR=$(echo "$INBOX" | jq -r .address)
TOK=$(echo "$INBOX" | jq -r .token)

echo "$ADDR"   # vivid-llama-4a2c@apumail.com

Essa chamada não tem autenticação. O token que volta é a credencial daquela caixa e de mais nada, e é essa propriedade que torna seguro entregá-lo a um agente: o raio de estrago de um token vazado é uma caixa descartável.

2. Saber que o e-mail chegou, sem loop de polling

É aqui que a maioria das implementações caseiras erra. O instinto é fazer polling: checar a caixa, dormir dois segundos, checar de novo. Funciona no seu notebook e é um risco em produção: você queima tokens a cada despertar e corre contra um código que normalmente expira em dez minutos.

O long-polling inverte isso. O agente faz uma única requisição que fica bloqueada até o e-mail chegar ou o timeout expirar:

curl -sS -H "Authorization: Bearer $TOK" \
  "https://api.apumail.com/api/v1/inbox/$ADDR/wait?timeout=120"

Uma requisição. Um despertar. A conexão fica aberta e retorna no instante em que o listener SMTP aceita a mensagem. Para um agente isso importa mais do que para um serviço comum: cada polling extra é uma ida e volta ao modelo, e essas idas e voltas custam dinheiro de verdade e latência de verdade.

3. Tirar os dígitos

Esta é a parte que, silenciosamente, mais consome tempo de engenharia. Um e-mail de verificação é uma peça de marketing: tabelas aninhadas, pixels de rastreamento, um código embrulhado em três spans e uma tag font. Entregar isso a um LLM para "achar o código" funciona em cerca de 95% das vezes, o que é um número péssimo quando está no seu caminho crítico.

A versão viável é extrair no lado do servidor, na hora de salvar, antes de o agente sequer ver a mensagem. O apumail roda a extração quando o e-mail é aceito e coloca o resultado num campo otp da mensagem:

{
  "messages": [{
    "from": "noreply@stripe.com",
    "subject": "Your Stripe verification code",
    "otp": "482910"
  }]
}

O agente lê .messages[0].otp. Sem parsing, sem prompt, sem 95%. O fluxo inteiro (criar, esperar, extrair) são três chamadas sem nenhum envolvimento do modelo, o que significa que ele não tem como alucinar um código.

Tudo junto

# 1. provision
INBOX=$(curl -sS -X POST https://api.apumail.com/api/v1/inboxes)
ADDR=$(echo "$INBOX" | jq -r .address)
TOK=$(echo "$INBOX" | jq -r .token)

# 2. use $ADDR in the signup form, then block until the mail lands
CODE=$(curl -sS -H "Authorization: Bearer $TOK" \
  "https://api.apumail.com/api/v1/inbox/$ADDR/wait?timeout=120" \
  | jq -r '.messages[0].otp')

# 3. submit $CODE
echo "$CODE"   # 482910

Se o seu agente fala MCP, esses mesmos três passos são três chamadas de ferramenta e você pode pular o HTTP inteiro: veja e-mail temporário como servidor MCP. E se o muro que o seu agente encontrou foi um código por SMS em vez de um por e-mail, a mesma camada de espera/extração cobre números de telefone.

Experimente, sem cadastro

Um único POST sem autenticação retorna um endereço funcional e o token dele.

curl -sS -X POST https://api.apumail.com/api/v1/inboxes