Comprovante de endereço
Comprovante de endereço
O módulo endereco_ocr lê o comprovante de endereço que o titular envia e devolve o endereço impresso nele. Valem conta de luz, água, gás, telefone ou internet, fatura ou extrato bancário, contrato de aluguel e documento de órgão público. Além do endereço, ele responde duas perguntas que a leitura sozinha não responde: o comprovante é recente? e o nome dele é o mesmo do documento de identidade lido neste fluxo?
Um passo novo no widget, e zero código a mais do seu lado. O titular envia um PDF ou uma foto, de até 4 MB, na mesma jornada em que fotografa o documento e faz a selfie. Do PDF vale a primeira página: é nela que o comprovante precisa trazer o nome, o endereço e a data de emissão, e o widget avisa isso na tela de envio. O arquivo não passa pelo seu front nem chega ao seu backend, e a mídia fica no painel com acesso restrito por papel, como as demais.
Dependências e preço. Ele exige cpf_ocr e face no mesmo flow, porque o nome cruzado é o que foi lido do documento de identidade: sem eles não há contra o que cruzar. Por isso o número que importa é o do conjunto, e não o do módulo sozinho: o flow mínimo com este módulo (cpf_ocr + face + endereco_ocr) custa - por verificação, e é esse o valor que entra na sua fatura. O unitário de cada módulo está na tabela de preços, lida do mesmo catálogo.
// endereco_ocr no check_details: o endereço lido, a recência e os dois cruzamentos
{ "module": "endereco_ocr", "passed": true, "outcome": "approved", "score": 92,
"data": { "doc_type": "utility_bill", // utility_bill | bank_statement | telecom |
// rent_contract | government | other
"cep": "01310930", "city": "São Paulo", "uf": "SP",
"issue_date": "2026-08-20", // data de emissão lida do comprovante
"issue_age_days": 27, // há quantos dias ele foi emitido
"name_match": true, // o nome do comprovante é o do documento de identidade?
"address_match": "match", // match | mismatch | unknown
"declared_address_match": "cep_match", // cep_match | uf_match | mismatch | unknown
"cep_consistency": "ok" } } // ok | cep_fora_da_base | uf_divergente | unknown
// nome divergente: NUNCA é recusa. O portão é soft, e a verificação vai para revisão humana.
{ "module": "endereco_ocr", "passed": false, "outcome": "failed", "score": 40,
"data": { "doc_type": "utility_bill",
"cep": "01310930", "city": "São Paulo", "uf": "SP",
"issue_date": "2026-08-20", "issue_age_days": 27,
"name_match": false, "address_match": "match",
"reason": "name_mismatch" } }
// comprovante fora do prazo: o titular reenvia um mais novo, ninguém é reprovado por isso.
// passed null + outcome "pending" são o shape de "ainda não dá para afirmar nada".
{ "module": "endereco_ocr", "passed": null, "outcome": "pending", "score": 0,
"data": { "doc_type": null,
"cep": "01310930", "city": "São Paulo", "uf": "SP",
"issue_date": "2025-11-02", "issue_age_days": 318,
"name_match": null, "address_match": "unknown",
"reason": "address_doc_expired" } }
// reason só aparece quando existe: no caminho aprovado a chave não vem.No resumo checks o módulo aparece com vocabulário próprio, e não com o pass/fail dos módulos de identidade: verified (extraiu, está no prazo e o nome cruzou), mismatch (o cruzamento de nome reprovou) e pending (toda a família de indeterminado, com o motivo fino em data.reason). Aqui não há lista consultada, há um documento conferido, e o vocabulário diz isso.
A recência é regra do produto, não detalhe. Um comprovante vale por até 90 dias contados da emissão. A idade em dias vem no payload (issue_age_days) para você aplicar uma régua mais apertada se a sua política pedir: a nossa é o teto, nunca o piso.
Os motivos, e o que fazer com cada um. Eles vêm em reason dentro do data do check, e se dividem em dois grupos com ações opostas. Pedem o reenvio do arquivo, e nunca são veredito contra o titular: address_not_found (o endereço não foi localizado no comprovante), address_doc_expired (o comprovante passou dos 90 dias) e address_doc_unreadable (o arquivo não pôde ser lido). Levam a revisão humana, com a evidência na mão de quem revisa: name_mismatch (o nome do comprovante diverge do nome do documento), identity_name_unavailable (o nome do documento não estava disponível para o cruzamento) e injection_suspected_text (o arquivo pede conferência humana antes de qualquer cruzamento) e address_doc_reused (o mesmo arquivo de comprovante já foi enviado por outro titular da sua conta; nunca compara com outras contas). Quando o módulo segura a verificação, o decision_reason dela é address_proof_review.
Opcional: o endereço que você já tem em cadastro. Na criação da sessão, do seu servidor, você pode enviar expected_address e ligar o sinal address_match. Ele aceita só CEP e UF, de propósito: é o recorte que responde "é o mesmo endereço?" sem que você precise nos mandar a rua e o número do titular. Sem o campo, o sinal sai unknown, que não é mismatch e muito menos match: é "não havia com o que comparar".
// criação de sessão (servidor, sk_): o campo é opcional e só aceita CEP e UF
{ "flow_id": "flow_...", "reference_id": "user_123",
"expected_address": { "cep": "01310930", "uf": "SP" } }Mandar expected_address num flow que não tem endereco_ocr é 422 expected_address_not_supported, nunca aceito e ignorado. CEP ou UF fora do formato é 400 validation_error com o campo nomeado.
Em sandbox nada é lido: o desfecho vem do sufixo do documento. 01 devolve o reenvio por endereço não localizado, 02 o nome divergente (que vai para revisão) e qualquer outro sufixo aprova. Com expected_address na sessão, o address_match do sandbox também vem do sufixo: 83 devolve mismatch e os demais match. Sem o campo, unknown, como em produção.
Quando o fluxo também tem a consulta cadastral de endereços, o data traz declared_address_match: o CEP e a UF do comprovante contra os endereços dessa consulta, com cep_match, uf_match, mismatch ou unknown quando falta um dos lados. É informação para você e nunca reprova a verificação.
Em todo comprovante o data traz também cep_consistency: o CEP lido conferido contra uma base de endereços, com ok (o CEP está na base, na mesma UF do comprovante), uf_divergente (está na base, em outra UF), cep_fora_da_base ou unknown (não houve conferência, por exemplo quando o CEP não foi lido). Fora da base não quer dizer inexistente: CEP novo ou de grande usuário pode faltar nela. É informação para a sua política, e nunca muda o desfecho da verificação.
Pronto para integrar? A chave de sandbox sai no painel, logo depois do cadastro. Criar conta grátis