> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unifokal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Impedidos de apostar

> O módulo betting_barred confere o titular contra as listas públicas de pessoas vedadas de apostar pela Lei 14.790/2023, Art. 26.

## Impedidos de apostar

O módulo `betting_barred` confere o **CPF e o nome lidos do documento** contra as listas públicas de pessoas vedadas de apostar pela **Lei 14.790/2023 (Art. 26)**, a obrigação legal do operador de apostas de quota fixa perante a SPA/MF. 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.

**Cobertura deste módulo**, fonte a fonte, e nada além dela: **agentes públicos** dos órgãos de regulação e fiscalização do setor de apostas (download de servidores do Portal da Transparência, filtrado por lotação). A base é **mensal** e o órgão publica com até dois meses de defasagem, então o competente que entrou no cargo no mês passado ainda não está nela: `dataset_versions` devolve a data em que nós ingerimos, não a data de referência do arquivo do órgão. **Não** estão incluídos, e não os anunciamos: cônjuge e parentes (o vínculo familiar do Art. 26 exige bureau e entra como produto separado), dirigentes de clube, agentes do próprio operador, intermediários e outros esportes. E este módulo **não substitui o SIGAP**: a consulta ao bloco de proteção (menores, beneficiários de programas sociais e autoexcluídos) é uma API do Serpro liberada só para o operador licenciado, que a sua operação já é obrigada a consultar diretamente.

> [!WARNING]
>
> **Atleta e árbitro NÃO entram, e preferimos dizer isso a listar sem consultar.** A CBF não publica base para conferência automática: o Boletim Informativo Diário é uma página de consulta um a um e os quadros de arbitragem não têm arquivo. Ler aquilo por raspagem de página produziria um "nada consta" falso no dia em que a página mudasse de formato, que é justamente o resultado que gera multa para o operador. As duas fontes aparecem na resposta como `disabled` em `dataset_versions`: você vê, por fonte, o que foi consultado e o que não foi.

> [!WARNING]
>
> **Este módulo nunca reprova sozinho.** O casamento é por **CPF parcial** (o Portal publica `***.NNN.NNN-**`) mais o nome, ou seja, homônimo continua sendo possível. Um sinal leva a verificação para `review` com a evidência no webhook, para a sua análise decidir. Nunca a `denied` automático.

Cada resposta carimba as fontes que a sustentaram em `coverage` e a idade de cada base em `dataset_versions`: é a sua **prova de diligência** ("na data do cadastro checamos estas bases nestas versões"). Se uma fonte que entraria na resposta estiver vencida, ou ainda sem carga, o módulo devolve `pending` com `dataset_stale` e a verificação vai para `review`: nós não afirmamos "nada consta" sobre base que não conseguimos atualizar, e esse caso **não é cobrado**.

**A lista só é consultada quando a verificação comprova que a pessoa presente é a dona do documento**: Face Match, Liveness e leitura do documento aprovados, sem indício de ataque. Sem essa prova o módulo sai `pending` com `identity_not_proven`, a lista não é consultada e o módulo **não é cobrado**. Com `pending`, os campos `is_restricted` e `flagged` não afirmam nada: leia o `reason`. Quando a verificação é aprovada manualmente no painel, a lista roda na aprovação e o módulo é cobrado pelo preço de sempre. Se a resposta pedir análise (restrição, política, base vencida), a aprovação não aprova: a verificação vai para `review` com o resultado, e quem aprova confere e aprova de novo.

A política **"impedimento reprova?"** é sua: por padrão a restrição **não reprova**, sai como sinalização com evidência e você decide no seu backoffice. Para que a restrição derrube o check, desligue no flow ou por sessão ao criar com chave secreta mandando `{ "policy": { "allow_betting_ban": false } }`. Chave de política desconhecida é 400 `unknown_policy_key`. Flows com este módulo não permitem renovação de sessão pelo widget: a renovação é sempre pelo seu servidor.

**A lista de restrições tem teto de 20, e o corte vem declarado.** O casamento por CPF parcial mais nome produz homônimo em volume, e um payload sem limite viraria incidente de custo e de leitura do seu lado. Passando de 20, `restrictions` sai cortado e `restrictions_truncated` vem `true`. O que continua verdadeiro no corte: `restrictions_total` declara o número **real**, `aggregates` é calculado sobre o conjunto **completo** (então `is_restricted` e `strongest_match` nunca mentem por causa do corte), e a ordenação é determinística **antes** dele: documento, depois documento parcial, depois nome, e maior similaridade primeiro.

**Coincidência de CPF parcial sem o nome confirmar tem resposta própria.** Parte das listas publica o CPF **mascarado**. Quando a máscara do titular coincide com uma linha da lista e o nome do documento **não** confirma, o módulo não devolve `clear`: o `reason` vem `mask_unconfirmed` (ou `mask_unconfirmed_allowed`, se a sua política aceita impedido), `flagged` vem `true` e `mask_unconfirmed_total` diz quantas linhas coincidiram. `restrictions` continua **vazio** e `is_restricted` continua `false`: não há restrição provada, e a linha da pessoa não confirmada nunca viaja. No resumo da verificação esse caso aparece como `inconclusive`, que é diferente de `restricted` e de `clear`. Os quatro valores possíveis em `checks.betting_barred` são `clear`, `restricted`, `inconclusive` e `pending`.

```
// betting_barred: nada consta (fonte fresca)
{ "module": "betting_barred", "passed": true, "outcome": "approved", "score": 95,
  "data": { "is_restricted": false, "flagged": false, "matched_by": "none", "reason": "clear",
            "restrictions": [], "restrictions_total": 0, "restrictions_truncated": false,
            "mask_unconfirmed_total": 0,
            "aggregates": { "is_restricted": false, "restriction_types": [], "strongest_match": null },
            "policy": { "allow_betting_ban": true, "source": "flow" },
            "coverage": ["ptransp_servidores_reg"],
            "coverage_degraded": [],
            // as fontes da CBF viajam SEMPRE, marcadas como nao consultadas
            "dataset_versions": { "ptransp_servidores_reg": { "ingested_at": "2026-08-29T05:41:24Z",
                                                              "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" } }

// betting_barred: agente publico casado por CPF PARCIAL + nome, com a politica reprovando -> review
{ "module": "betting_barred", "passed": false, "outcome": "failed", "score": 20,
  "data": { "is_restricted": true, "flagged": true, "matched_by": "document_partial",
            "reason": "restricted_document_partial",
            "restrictions": [ { "type": "agente_publico", "link_level": 0, "sport": null,
                                "entity": "MINISTERIO DA FAZENDA",
                                "source": "ptransp_servidores_reg",
                                "matched_by": "document_partial", "similarity": 100,
                                "birth_date_mismatch": false,
                                "entry_ref": "ptransp_servidores_reg:e_a8954835",
                                "details": { "agency": "MINISTERIO DA FAZENDA",
                                             "position": "ANALISTA TRIBUTARIO REC FEDERAL BRASIL" } } ],
            "restrictions_total": 1,
            "aggregates": { "is_restricted": true, "restriction_types": ["agente_publico"],
                            "strongest_match": "document_partial" },
            "policy": { "allow_betting_ban": false, "source": "session" } } }

// betting_barred: a mascara publicada coincidiu e o nome NAO confirmou -> review, sem restricao
{ "module": "betting_barred", "passed": false, "outcome": "failed", "score": 45,
  "data": { "is_restricted": false, "flagged": true, "matched_by": "none",
            "reason": "mask_unconfirmed",
            "restrictions": [], "restrictions_total": 0, "mask_unconfirmed_total": 1,
            "policy": { "allow_betting_ban": false, "source": "session" } } }

// betting_barred: identidade nao comprovada -> lista NAO consultada, pending, NAO cobrado
{ "module": "betting_barred", "passed": null, "outcome": "pending", "score": 0,
  "data": { "is_restricted": false, "flagged": false, "matched_by": "none",
            "reason": "identity_not_proven" } }

// betting_barred: fonte vencida -> pending, review, e NAO cobrado
{ "module": "betting_barred", "passed": null, "outcome": "pending", "score": 0,
  "data": { "reason": "dataset_stale", "coverage": [],
            "coverage_degraded": ["ptransp_servidores_reg"] } }
```

Em sandbox nada é consultado: o desfecho vem do sufixo do documento. `02` devolve um agente público casado por CPF parcial, `01` o caminho de fonte vencida (pendente, não cobrado) e `33` um homônimo abaixo do corte, que aprova. O portão de identidade também vale no sandbox: com um desses sufixos e o Face Match, a Liveness ou a leitura do documento reprovados, o módulo sai `pending` com `identity_not_proven`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.