Criar conta grátis

Documentação
Ver em Markdown

Vínculos, listas restritivas e processos

Vínculos, listas restritivas e processos

Seis módulos de compliance aprofundam o screening além do titular: pep_parentes (parentes de pessoa exposta politicamente), impedidos_vinculos (vínculo familiar com impedido de apostar, a fase 2 da Lei 14.790/2023, Art. 26), pep_lista_restritiva (listas restritivas), antecedentes_estaduais, processos_judiciais e scr_bacen (retrato de endividamento no SCR). Todos partem do CPF lido do documento, e exigem Documento, Face Match e Liveness no mesmo flow pela mesma razão do pep_sancoes: nada aqui é consultado a partir de um número digitado. A consulta à fonte é pelo CPF; o nome só entra no impedidos_vinculos, e ainda assim como nome do parente, dentro do nosso motor local de vedação.

Venda pausada hoje, os seis. Eles aparecem na tabela de preços e no GET /v1/capabilities com preço e status coming_soon, e não podem ser ligados num flow enquanto a credencial do fornecedor não existir na conta. O estado vem do catálogo vivo, e esta página acompanha. O payload abaixo é o contrato que já está implementado e que passa a valer no dia da abertura.

!Nunca leia só flagged nestes módulos. Quando a fonte não é chamada (credencial ausente, portão de identidade fechado, consulta adiada), o check sai pending e ainda assim traz data, preenchido com os valores neutros: flagged: false, matched_by: "none", aggregates: null e o bloco da fonte null. Isso é "não perguntamos", e é indistinguível de "nada consta" se você olhar só a flag. Ramifique por outcome primeiro, sempre.

Outro campo que promete mais do que entrega: nestes módulos matched_by: "document" é derivado de flagged, não é a prova de que o casamento se deu por CPF. Ele diz "houve resultado", e não "casou pelo documento". A única exceção é o impedidos_vinculos, onde ele é medido de verdade e distingue document, document_partial e name. E ele nem existe em dois dos seis: antecedentes_estaduais e scr_bacen não emitem a chave. Onde ela aparece fora do impedidos_vinculos, trate-a como sinônimo de flagged.

// pep_parentes: parente PEP encontrado. "parentes" é o dossiê da fonte passando por nós.
{ "module": "pep_parentes", "passed": false, "outcome": "failed", "score": 40,
  "data": { "flagged": true,
            "matched_by": "document",   // derivado de flagged, NÃO é prova de match por CPF
            "reason": null,
            "parentes": { "parentescosPEP": [
              { "nome": "MARIA SILVA", "cpf": "***456789**", "grauParentesco": "MAE",
                "pep": { "nome": "JOSE SILVA", "funcao": "DEPUTADO FEDERAL",
                         "orgao": "CAMARA MOCK", "nivel": "FEDERAL" } } ] } } }

// pep_lista_restritiva: o bloco "listas" é a resposta da fonte, como ela manda.
{ "module": "pep_lista_restritiva", "passed": false, "outcome": "failed", "score": 40,
  "data": { "flagged": true, "matched_by": "document",
            "listas": { "listas": [ { "lista": "LISTA RESTRITIVA MOCK", "nome": "JOAO SILVA",
                                      "origem": "MOCK", "dataInclusao": "2025-03-01" } ] } } }

// antecedentes_estaduais: repare no tri-estado de "nada_consta" e na cobertura FIXA de UFs.
{ "module": "antecedentes_estaduais", "passed": false, "outcome": "failed", "score": 40,
  "data": { "nada_consta": false,      // true | false | null. null = a fonte NÃO afirmou nada.
            "flagged": true,
            "cobertura_uf": ["CE", "MG", "MT", "RS"],   // as UFs cobertas hoje, e só elas
            "antecedentes": { "nadaConsta": false,
                              "ocorrencias": [ { "uf": "MG", "tribunal": "TJMG",
                                                 "classe": "Acao Penal", "ano": 2024 } ] } } }

// processos_judiciais: "encontrados" é contado por nós sobre a resposta, não é campo da fonte.
{ "module": "processos_judiciais", "passed": false, "outcome": "failed", "score": 40,
  "data": { "flagged": true, "matched_by": "document", "encontrados": 2,
            "processos": { "totalProcessos": 2,
                           "processos": [ { "numero": "0001234-56.2024.8.13.0000",
                                            "tribunal": "TJMG", "classe": "Execucao de Titulo",
                                            "polo": "passivo", "status": "ativo" } ] } } }

// scr_bacen: INFORMACIONAL. O dossiê é o produto, e "flagged" é sempre false.
{ "module": "scr_bacen", "passed": true, "outcome": "approved", "score": 100,
  "data": { "flagged": false,
            "scr": { "dataBase": "2026-07", "quantidadeInstituicoes": 1,
                     "quantidadeOperacoes": 2,
                     "carteira": { "vencido": 0, "aVencer": 8765.43 } } } }

Duas leituras que evitam conclusão errada. nada_consta, no antecedentes_estaduais, tem três estados e não dois: false quando há ocorrência, true só quando a fonte afirma que nada consta, e null quando não houve ocorrência e a fonte também não afirmou nada. Campo ausente na resposta nunca vira atestado nosso. E scr_bacen.flagged é sempre false, por construção: o módulo é informacional, o produto dele é o retrato de endividamento, e não existe caminho no código que o marque. Não escreva alerta em cima dessa flag.

O impedidos_vinculos é o mais denso dos seis, porque ele precisa provar duas coberturas ao mesmo tempo: de onde veio o grafo familiar (graph_coverage, hoje sempre "pep_relatives", ou seja a fonte de parentesco de PEP e mais nada) e quais bases de vedação sustentaram a triagem de cada parente (coverage e dataset_versions, as mesmas do módulo Impedidos de apostar). E ele conta os parentes de forma auditável: relatives_total é quanto a fonte devolveu, relatives_screened é quanto o motor de fato respondeu, e relatives_unscreened agrupa por motivo quem ficou de fora. Essa lista tem vocabulário fechado de seis valores: degree_unknown, degree_out_of_scope, document_missing, name_missing, screening_indeterminate e over_cap. Repare que relatives_total menos relatives_screened não é o tamanho dessa lista: ela é agrupada, e cada item traz o próprio count.

// impedidos_vinculos: parente de 1o grau na base de impedidos -> review COM evidência
{ "module": "impedidos_vinculos", "passed": false, "outcome": "failed", "score": 40,
  "data": { "is_restricted": true, "flagged": true,
            "matched_by": "name",            // aqui ele é MEDIDO: document | document_partial | name
            "reason": "family_link_restricted",
            "restrictions": [ { "type": "vinculo_familiar_1g", "link_level": 1, "sport": null,
                                "entity": null, "source": "ptransp_servidores_reg",
                                "matched_by": "name",
                                "similarity": 91,       // 0..100, NÃO 0..1
                                "listed_at": null, "left_at": null,
                                "birth_date_mismatch": false,
                                "entry_ref": "ptransp_servidores_reg:e_a8954835" } ],
            "restrictions_total": 1, "restrictions_truncated": false,
            "aggregates": { "is_restricted": true,
                            "restriction_types": ["vinculo_familiar_1g"],
                            "strongest_match": "name" },
            "graph_coverage": "pep_relatives",
            "relatives_total": 2, "relatives_screened": 2, "relatives_unscreened": [],
            "coverage": ["ptransp_servidores_reg"], "coverage_degraded": [],
            "dataset_versions": { "ptransp_servidores_reg": { "ingested_at": "2026-09-01T03:00:00Z",
                                                              "age_hours": 4, "stale": false,
                                                              "disabled": false },
                                  "cbf_bid":      { "ingested_at": null, "age_hours": null,
                                                    "stale": false, "disabled": true },
                                  "cbf_arbitros": { "ingested_at": null, "age_hours": null,
                                                    "stale": false, "disabled": true } },
            "name_source": "ocr" } }

// o caminho que MAIS importa: o parente existe e NÃO foi rastreável.
// Não é "nada consta": é "não deu para perguntar", e a contagem diz por quê.
{ "module": "impedidos_vinculos", "passed": null, "outcome": "pending", "score": 0,
  "data": { "is_restricted": false, "flagged": false, "matched_by": "none",
            "reason": "relatives_unscreenable",
            "restrictions": [], "restrictions_total": 0, "restrictions_truncated": false,
            "aggregates": null,
            "graph_coverage": "pep_relatives",
            "relatives_total": 1, "relatives_screened": 0,
            "relatives_unscreened": [ { "reason": "degree_unknown", "count": 1 } ],
            // vazios porque o motor local NEM FOI CHAMADO: sem grau de parentesco não há o
            // que triar, então não há cobertura a declarar. Não confunda com base vencida.
            "coverage": [], "coverage_degraded": [], "dataset_versions": null,
            "name_source": null } }   // null porque nem chegamos a usar um nome

Nenhum dos seis reprova sozinho, pela mesma regra do pep_sancoes: um resultado é candidato, vai para review com a evidência no webhook, e a sua análise decide. E vale a mesma minimização: o que sai do impedidos_vinculos sobre o parente é contagem e restrição minimizada, nunca nome, CPF ou datas de terceiro. O nome e o documento do parente entram na consulta e morrem lá.

!No sandbox, o desfecho destes módulos não acompanha o resultado, e isso é deliberado do ambiente de testes. Os sufixos 88 (hit) e 77 (indeterminado, só no impedidos_vinculos) escolhem o dado, mas o outcome continua vindo da tabela universal do sandbox, onde só 00, 01 e 02 mudam o desfecho. Ou seja: em sandbox você vê outcome: "approved" com flagged: true. Em produção o mesmo hit sai failed e a verificação vai a revisão. Use os sufixos para exercitar o parser, e 02 para exercitar o desfecho.

Pronto para integrar? A chave de sandbox sai no painel, logo depois do cadastro. Criar conta grátis