Criar conta grátis

Documentação
Ver em Markdown

PEP e listas restritivas

PEP e listas restritivas

O módulo pep_sancoes confere o CPF e o nome lidos do documento contra listas oficiais de pessoas expostas politicamente e de sanções. Ele exige Verificação de Identidade + Face Match + Liveness no mesmo flow: o dado consultado vem do documento apresentado por quem está vivo na frente da câmera, nunca de um CPF digitado. O widget não ganha nenhum passo novo.

!Este módulo nunca reprova sozinho. Um resultado positivo é candidato, não veredito: nomes brasileiros repetem muito (dentro da própria lista de PEP há um nome com 13 CPFs diferentes). Por isso um sinal leva a verificação para review, com a evidência (lista, referência da entrada, score e motivo) no webhook, para a sua análise decidir. Nunca a denied automático.

Cobertura desta fase, e nada além dela: PEP federal e expulsões da administração federal (CGU: PEP e CEAF), empresas e pessoas inidôneas ou punidas (CGU: CEIS e CNEP) e as listas internacionais de sanções da ONU (obrigatória no Brasil pela Lei 13.810/2019), do OFAC (Tesouro dos EUA) e do Reino Unido (UK Sanctions List, do FCDO). Não estão incluídos, e não os anunciamos: a lista de sanções da União Europeia (a fonte exige uma credencial que ainda não temos, então ela nasce desabilitada e sai marcada como tal em dataset_versions), parentes e associados de PEP, PEP estadual/municipal, PEP estrangeiro, improbidade do CNJ e adverse media.

Cada resposta carimba a idade e o tamanho de cada lista em dataset_versions (ingested_at, age_hours e record_count). Se uma lista que entraria na resposta estiver vencida, o módulo devolve pending com dataset_stale e a verificação vai para review: nós não afirmamos "nada consta" sobre uma base que não conseguimos atualizar, e esse caso não é cobrado. Sem CPF legível no documento o resultado também é pending.

A mesma regra vale quando a lista não foi consultada, e não só quando ela envelheceu. A resposta sai pending com no_coverage quando nenhuma lista do módulo está disponível, e com critical_source_disabled quando uma lista que a resposta não pode dispensar está fora do ar. Os dois casos vão para review e não são cobrados, pelo mesmo motivo do dataset_stale: um veredito de "nada consta" só vale se alguma lista tiver sido de fato consultada. E quando uma lista específica não entrou na consulta, ela aparece em aggregates.by_list com null em vez de sumir do objeto, para que "não foi olhada" nunca se pareça com "olhada e sem resultado" no seu código.

A política "aceito clientes que são PEP?" é sua: por padrão ser PEP não reprova (sai como sinalização, que é o que a regulação pede: diligência reforçada, não recusa). Você pode desligá-la no flow, ou por sessão ao criar com sk_ mandando { "policy": { "allow_pep": false } }. Só o vínculo atual reprova; vínculo passado nunca. Chave de política desconhecida é 400 unknown_policy_key.

O resumo pronto de PEP e sanção. Você não precisa refazer a conta em cada integração. O bloco pep_status diz se há função pública em exercício (current) e se a pessoa deixou a função no último ano, nos últimos três ou nos últimos cinco anos (last_1y, last_3y, last_5y), contados do fim do exercício. roles traz a descrição da função como a fonte oficial publica, e só quando o casamento foi pelo documento e forte: semelhança de nome nunca traz cargo. Em aggregates, is_pep, has_sanctions_br (lista publicada por órgão brasileiro) e has_sanctions_intl (lista publicada por organismo ou governo estrangeiro) resumem os hits, worst_severity dá a pior zona entre eles (no_hit, weak ou strong), e sanction_windows e pep_windows separam as janelas por tipo de lista. windows continua no payload como a soma das duas, marcado como depreciado: prefira as separadas.

Programe contra source, não contra list. Em cada hit, source é o identificador estável da lista (cgu_pep, cgu_ceis, ofac_sdn) e não muda; list é o rótulo legível e pode mudar de texto. Na lista de PEP, left_at é o fim do período em que a pessoa é considerada politicamente exposta, e exercise_end é o fim do exercício da função; pep_in_carency marca quem já deixou a função e ainda está dentro dos cinco anos.

Cota diária do módulo. Cada organização tem uma cota diária de sessões novas com este módulo em produção. Passando dela, a criação de sessão responde 429 module_quota_reached com Retry-After até a virada do dia (meia-noite UTC). A renovação de uma sessão não conta de novo. Se o seu volume pede mais, fale com a gente: o ajuste é por organização.

A lista de hits tem teto, e o corte vem declarado. Nome comum produz muito candidato, e um payload sem limite viraria incidente de custo e de leitura do seu lado. Passando do teto, hits sai cortado e hits_truncated vem true. Duas garantias tornam o corte seguro de programar: os aggregates são calculados sobre o conjunto completo (a contagem continua verdadeira mesmo com a lista cortada), e a ordem é determinística antes do corte, com hit forte na frente do fraco e casamento por documento na frente do casamento por nome. O que fica de fora é sempre a cauda mais fraca, nunca a evidência que decide.

// pep_sancoes: nada consta
{ "module": "pep_sancoes", "passed": true, "outcome": "approved", "score": 95,
  "data": { "pep": false, "flagged": false, "matched_by": "none", "reason": "clean",
            "pep_status": { "current": false, "last_1y": false, "last_3y": false, "last_5y": false,
                            "roles": [] },
            "hits": [], "hits_truncated": false,
            "aggregates": { "total": 0, "pep": 0, "sanctions": 0, "strong": 0,
                            "is_pep": false, "has_sanctions_br": false, "has_sanctions_intl": false,
                            "worst_severity": "no_hit",
                            "pep_windows": { "d30": 0, "d90": 0, "d180": 0, "d365": 0, "d1825": 0, "total": 0 },
                            "sanction_windows": { "d30": 0, "d90": 0, "d180": 0, "d365": 0, "d1825": 0, "total": 0 },
                            "windows": { "d30": 0, "d90": 0, "d180": 0, "d365": 0, "d1825": 0, "total": 0 } },
            "policy": { "allow_pep": true, "source": "flow" },
            "dataset_versions": { "cgu_pep": { "ingested_at": "2026-08-21T03:10:00Z", "age_hours": 9.2,
                                               "record_count": 133880,
                                               "stale": false, "disabled": false } } } }

// pep_sancoes: PEP atual, política do flow permitindo (sinaliza, NÃO reprova)
{ "module": "pep_sancoes", "passed": true, "outcome": "approved", "score": 70,
  "data": { "pep": true, "flagged": true, "matched_by": "document", "reason": "pep_current",
            "pep_status": { "current": true, "last_1y": false, "last_3y": false, "last_5y": false,
                            "roles": [ "DIRETOR" ] },
            "hits": [ { "source": "cgu_pep", "list": "PEP", "matched_by": "document", "strong": true,
                        "similarity": 1, "precision": 1, "listed_at": "2025-02-01", "left_at": null,
                        "current": true, "entry_ref": "cgu_pep:8831",
                        "exercise_end": null, "pep_in_carency": false,
                        "details": { "funcao": "DIRETOR", "orgao": "MINISTERIO X" } } ] } }

// pep_sancoes: deixou a função há dois anos e segue exposta pela carência de cinco anos
{ "module": "pep_sancoes", "passed": true, "outcome": "approved", "score": 70,
  "data": { "pep": true, "flagged": true, "matched_by": "document", "reason": "pep_current",
            "pep_status": { "current": false, "last_1y": false, "last_3y": true, "last_5y": true,
                            "roles": [ "SECRETARIO" ] },
            "hits": [ { "source": "cgu_pep", "list": "PEP", "matched_by": "document", "strong": true,
                        "similarity": 1, "precision": 1, "listed_at": "2019-01-01",
                        "left_at": "2028-12-31", "current": true, "entry_ref": "cgu_pep:9120",
                        "exercise_end": "2023-12-31", "pep_in_carency": true,
                        "details": { "funcao": "SECRETARIO", "orgao": "MINISTERIO X" } } ] } }

// pep_sancoes: semelhança de NOME numa lista internacional (candidato, não veredito)
// repare no que NÃO vem: nome, documento, cargo ou texto livre do terceiro.
{ "module": "pep_sancoes", "passed": true, "outcome": "approved", "score": 60,
  "data": { "pep": false, "flagged": true, "matched_by": "name", "reason": "sanction_name_weak",
            "hits": [ { "source": "ofac_sdn", "list": "OFAC SDN", "matched_by": "name",
                        "strong": false, "similarity": 0.82, "precision": 0.64,
                        "listed_at": "2019-05-10", "left_at": null, "current": true,
                        "entry_ref": "ofac_sdn:4417" } ] } }

// pep_sancoes: lista nossa vencida, pending, review, e NÃO cobrado
// QUAL lista venceu você lê em dataset_versions, na fonte com "stale": true.
{ "module": "pep_sancoes", "passed": null, "outcome": "pending", "score": 0,
  "data": { "pep": false, "flagged": false, "matched_by": "none", "reason": "dataset_stale",
            "hits": [], "hits_truncated": false, "aggregates": null,
            "policy": { "allow_pep": true, "source": "flow" },
            "dataset_versions": { "cgu_pep": { "ingested_at": "2026-08-19T03:10:00Z",
                                               "age_hours": 51.4, "record_count": 133880,
                                               "stale": true, "disabled": false } } } }

// pep_sancoes: nenhuma lista do modulo disponivel, pending, review, e NAO cobrado
// dataset_versions continua vindo inteiro: voce ve exatamente quais listas ficaram de fora.
{ "module": "pep_sancoes", "passed": null, "outcome": "pending", "score": 0,
  "data": { "pep": false, "flagged": false, "matched_by": "none", "reason": "no_coverage",
            "hits": [], "hits_truncated": false, "aggregates": null,
            "policy": { "allow_pep": true, "source": "flow" },
            "dataset_versions": { "cgu_pep": { "ingested_at": "2026-08-21T03:10:00Z",
                                               "age_hours": 9.2, "record_count": 133880,
                                               "stale": false, "disabled": true } } } }

// pep_sancoes: uma lista que a resposta nao pode dispensar esta fora do ar
{ "module": "pep_sancoes", "passed": null, "outcome": "pending", "score": 0,
  "data": { "pep": false, "flagged": false, "matched_by": "none",
            "reason": "critical_source_disabled",
            "hits": [], "hits_truncated": false, "aggregates": null,
            "policy": { "allow_pep": true, "source": "flow" } } }

// pep_sancoes: lista NAO consultada aparece como null em by_list (nunca ausente)
{ "module": "pep_sancoes", "passed": true, "outcome": "approved", "score": 95,
  "data": { "pep": false, "flagged": false, "matched_by": "none", "reason": "clean",
            "aggregates": { "total": 0, "pep": 0, "sanctions": 0, "strong": 0,
                            "by_list": { "TCU": null },
                            "windows": { "d30": 0, "d90": 0, "d180": 0, "d365": 0, "total": 0 } } } }

Em sandbox nada é consultado: o desfecho vem do sufixo do documento, como no resto do ambiente de testes. 66 devolve PEP atual com a política recusando, 77 PEP atual com a política permitindo, 44 PEP que deixou a função há dois anos e segue na carência, 88 sanção por documento no CEIS e 99 um homônimo na OFAC com semelhança 0,82. O pep_status e os agregados do sandbox saem da mesma conta da produção.

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