Risco de IP e de e-mail
Dois módulos avaliam o contexto da verificação, e não a identidade: Verificação de IP (ip_risk) e Risco de e-mail (email_risk). Nenhum dos dois pede passo novo ao usuário, e nenhum dos dois reprova sozinho: são portões suaves, como os módulos de canal. Um sinal aqui leva a verificação para review com a evidência no webhook, nunca a denied automático.
Dois campos do payload merecem leitura antes de você programar contra ele. provider_verdict diz se a camada de reputação de rede/endereço estava disponível para aquela consulta: quando vem not_cached, os campos que dependem dela chegam null e isso significa não medido, jamais “limpo”. No ip_risk existe ainda o network_measured: quando ele vem false, nenhuma camada de rede respondeu e o módulo sai pending em vez de dizer que está limpo (e nesse caso ele não é cobrado). E scope, no email_risk, diz o que foi de fato analisado: mailbox quando o flow também tem email_otp (é dele que o endereço vem, digitado pelo titular no widget) e domain quando só o domínio existia. No escopo domain, role_based e plus_alias vêm null: não havia caixa para olhar. Combine sempre email_risk com email_otp no mesmo flow: sem ele o endereço nunca chega ao produto (você não envia contato na criação), o módulo sai pending com reason: "email_not_provided", a verificação vai para revisão e o módulo não é cobrado.
O ip_risk devolve derivados do endereço, e não o endereço: país, ASN, organização do ASN e a classe da conexão. O IP, a cidade e a coordenada não trafegam. No email_risk vale a mesma regra dos módulos de canal: só o domínio, a máscara e o email_fp (o mesmo HMAC que a Validação de e-mail publica para o mesmo endereço, para você correlacionar sem receber o dado em claro).
No ip_risk, proxy e VPN saem separados porque a pergunta que você faz sobre cada um é diferente, e anonymizer é apenas o “ou” dos dois. Ao lado deles viaja o comportamento recente do endereço, como o fornecedor o declara: recent_abuse (houve abuso conhecido a partir dali), bot (tráfego automatizado) e abuse_velocity, um ordinal fechado em none, low, medium e high. Valor fora desse vocabulário vira null, nunca um veredito por acidente. E vale para todos eles a regra do provider_verdict: null significa que o fornecedor não respondeu sobre aquele ponto, jamais que respondeu que está limpo.
No email_risk, disposable_listed e forwarder_listed declaram de onde veio a afirmação: eles são a nossa lista curada de domínios descartáveis e de encaminhadores mascarados, que soma ao veredito do fornecedor em vez de substituí-lo. Assim disposable: true com disposable_listed: false quer dizer “quem afirmou foi o fornecedor”, e a nossa lista, que é curta por desenho, não transforma o próprio false em “medimos e está limpo”. Outros dois campos olham o formato do endereço, e só existem no escopo mailbox: digits_heavy marca o local-part dominado por dígitos (uma corrida de cinco ou mais, ou mais da metade dos caracteres), o padrão do endereço fabricado em massa, calibrado de propósito para não pegar o apelido com ano de nascimento; e name_email_score mede, de 0 a 1, quanto do local-part é coberto pelo nome lido no documento. Este último é informativo e não pontua: apelido legítimo é comum demais para virar agravante, e ele vem null quando não há caixa, não há OCR na verificação, ou o local-part não tem nenhum token com cara de nome.
ip_risk: 33 datacenter, 44 saída Tor fora do país e 55 reputação indisponível (not_cached). Para o email_risk: 33 domínio descartável, 44 caixa de função com alias e 55 escopo de domínio.
A mesma dupla tem uma versão avançada, com um terceiro módulo de telefone ao lado: Verificação avançada de IP (ip_risk_plus), Risco avançado de e-mail (email_risk_plus) e Risco de telefone (phone_risk). Os dois primeiros devolvem os MESMOS campos dos módulos de origem acima, com uma diferença de entrega: aqui o veredito nunca chega como não medido. Sem resposta da consulta o módulo defere, e o deferimento tem forma própria no payload: o item de check_details continua vindo com data, e é dentro dele que o deferimento se declara, com provider_verdict: "unavailable", reason: "provider_unavailable" e null em tudo que não foi medido. Nessa passagem o módulo não é cobrado: sai da conta só ele, e o resto do flow continua sendo cobrado normalmente. Nenhum campo é completado com “limpo”.
O phone_risk exige sms_otp no mesmo flow: o número analisado é o que o titular já provou controlar pelo código por SMS, nunca um número solto. Ele confirma a linha, não a pessoa, e não substitui a prova de posse por SMS nem a biometria. O número completo não trafega: só a máscara e o phone_fp, o mesmo pseudônimo que o sms_otp publica para o mesmo número. line_class é vocabulário fechado nosso (mobile, landline, voip, toll_free, premium, satellite, pager, unknown), nunca a string crua do fornecedor, e high_risk é derivado por nós: não há score cru de fornecedor no payload. Os três são portões suaves: um sinal alto leva a verificação para review com a evidência no webhook, nunca a denied automático.
passed, outcome e score continuam saindo da tabela de sufixos do sandbox (00, 01 e 02), e qualquer outro sufixo aprova. Para o ip_risk_plus: 33 responde com rede de datacenter e 44 com saída Tor fora do país. Para o email_risk_plus: 33 domínio descartável, 44 caixa de função com alias e 55 escopo de domínio, com o veredito medido. Para o phone_risk: 33 abuso recente, 44 linha VOIP e 55 número fora da faixa atribuída pela base. Ou seja: em sandbox dá para ver um payload de risco alto junto de outcome: "approved", o que não acontece em produção. Programe contra os campos, nunca contra o par que o sandbox mostra.