# Monitoramento contínuo

<https://unifokal.com/docs/modulos/monitoring-aml>

## Monitoramento contínuo

O módulo `monitoring_aml` é o único que **não roda durante uma verificação**. Depois que o titular foi aprovado, ele fica sob vigilância nas mesmas listas de PEP e de sanções do `pep_sancoes`, e quando o nome dele **aparece numa lista em que não constava no onboarding**, nós criamos uma verificação de acompanhamento e mandamos o webhook. Nenhuma captura nova, nenhum passo para o titular. A cobrança é **por titular monitorado por mês**, e os alertas entre as reconciliações já estão inclusos.

**Disponível desde 11 de setembro de 2026**, a 10 centavos por titular por mês. Ele aparece na tabela de preços e no `GET /v1/capabilities` com preço e status `available`.

**Atenção a como ele se liga, porque não é como os outros: ele não é item do array `modules` de um flow**, e pedir isso continua sendo recusado. Quem liga o monitoramento é o campo `monitoring_enabled` do flow, em `POST /v1/flows` e em `PATCH /v1/flows/{id}`, ou o bloco `monitoring` da criação da sessão. Esses campos deixaram de responder `422 monitoring_unavailable`: agora são aceitos. A razão de ele ficar fora da lista de módulos é que ele não é etapa da verificação: nada dele roda enquanto o titular está na jornada.

! **O alerta chega num evento próprio, `verification.monitoring`, e não em `verification.completed`.** Ele é gerado pelo nosso vigia, não por uma jornada que alguém percorreu. Se o seu handler só trata `verification.completed`, o alerta passa despercebido; e se ele guarda "a última verificação por `reference_id`", o alerta sobrescreve o resultado do onboarding. Trate o evento pelo nome.

```
// monitoring_aml: o titular apareceu numa lista DEPOIS do onboarding
{ "module": "monitoring_aml", "passed": false, "outcome": "failed", "score": 40,
  "data": { "monitoring": {
      "flagged": true,
      "reason": "monitoring_new_listing",     // monitoring_new_listing | monitoring_clear
      "trigger": "delta",                     // delta (lista mudou) | reconcile (varredura periódica)
      // SÓ o que MUDOU nesta passagem. Não é a lista de hits do titular.
      "changes": [ { "source": "ofac_sdn", "list": "OFAC_SDN", "matched_by": "name",
                     "strong": false, "similarity": 0.82, "precision": 0.82,
                     "listed_at": "2026-01-02", "left_at": null, "current": true,
                     "entry_ref": "ofac_sdn:8f31c2a0" } ],
      "hits_total": 1,                        // o total da triagem, novos E antigos
      "origin_verification_id": "ver_2f8c1a90" } } }   // a verificação que o inscreveu
// repare no que NÃO está aqui: "dataset_versions". No trilho "delta" a chave não viaja.

// o MESMO alerta, achado pela varredura periódica. Aí sim a chave de frescor vem junto.
{ "module": "monitoring_aml", "passed": false, "outcome": "failed", "score": 40,
  "data": { "monitoring": {
      "flagged": true, "reason": "monitoring_new_listing", "trigger": "reconcile",
      "changes": [ { "source": "cgu_pep", "list": "PEP", "matched_by": "document",
                     "strong": true, "similarity": 1, "precision": 1,
                     "listed_at": "2026-08-30", "left_at": null, "current": true,
                     "entry_ref": "cgu_pep:8831" } ],
      "hits_total": 2,
      "origin_verification_id": "ver_2f8c1a90",
      "dataset_versions": { "cgu_pep": { "ingested_at": "2026-09-05T03:00:00Z",
                                         "age_hours": 6, "stale": false,
                                         "disabled": false } } } } }
```

**`changes` é o delta, e `hits_total` é o total.** Os dois quase nunca batem, e isso é o desenho: o alerta existe para dizer **o que mudou**, não para reenviar a triagem inteira toda vez. Um titular com três hits antigos e um novo chega com `changes` de tamanho 1 e `hits_total` 4. `origin_verification_id` é a verificação de onboarding que inscreveu o titular, e é por ela que você liga o alerta ao cadastro no seu lado. `dataset_versions` é **opcional de verdade**: a chave só aparece na varredura periódica, e some no alerta em tempo real.

**Você só recebe evento quando algo mudou.** A varredura que não encontra novidade nenhuma não emite webhook: ela registra internamente que o titular continua limpo e segue. Ou seja, não existe um "pulso" periódico de tranquilidade chegando no seu endpoint, e silêncio aqui significa **nada mudou**. Se você precisa provar diligência continuada numa data específica, a fonte disso é o painel, não a ausência de webhook.

**Avisos de ciclo de vida.** Além do alerta, o mesmo `verification.monitoring` carrega os seis avisos de que a assinatura do titular mudou de estado. Eles chegam como verificação `failed`, **sem checks e sem cobrança**, e o que os distingue é o `decision_reason`: `monitor_paused_no_credits` e `monitor_paused_source_unavailable` (a varredura parou, e retoma sozinha), `monitor_resumed` (voltou), `monitor_ended_window` (a janela acabou), `monitor_ended_erased` (o titular foi apagado a pedido dele) e `monitor_ended_client` (você encerrou). Tratar esses seis como alerta faria a sua fila de revisão encher de eventos que não são achado nenhum.

**A carteira, a janela de cada titular e o encerramento ficam no painel**, em Monitoramento: é lá que você vê quem está sendo verificado, até quando, quando foi a última varredura de cada um, e é de lá que se encerra o monitoramento de alguém.

O alerta **nunca decide**: ele sai sempre como revisão, com a evidência minimizada, e quem julga é você. E vale a mesma minimização do `pep_sancoes`: hit por nome traz fonte, lista, scores, datas e uma referência opaca, sem nome, documento ou texto livre do terceiro.
