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

# Regras de eventos: velocidade, proporção, sequência

> Com a Didit, crie regras de velocidade, proporção, sequência ordenada e correlação sobre eventos, no mesmo construtor das regras de transação.

[Eventos](https://docs.didit.me/pt-br/transaction-monitoring/events.md) são avaliados pelo mesmo mecanismo que as transações. Há um único modelo de regra, um único vocabulário de condições e um único conjunto de ações: a regra apenas declara a quais tipos de registro se aplica.

## Aplica-se a

`scope.record_types` define a quais registros uma regra se aplica.

| `record_types` | Dispara em |
| - | - |
| omitido ou `["transaction"]` | Apenas transações (**o padrão**) |
| `["event"]` | Apenas eventos |
| `["transaction", "event"]` | Ambos |

> [!NOTE]
>
> Omiti-lo mantém a regra restrita a transações. Toda regra criada antes da existência dos eventos se comporta exatamente como antes, e uma regra nunca passa a corresponder a logins só porque seu escopo estava vazio.

No console, isso corresponde ao seletor **Aplica-se a** na etapa de gatilho da regra. Escolher Eventos exibe uma lista de verificação **Categorias de eventos** que restringe ainda mais a regra; deixe tudo desmarcado para avaliar todas as categorias.

```json theme={null}
{
  "title": "Failed login burst",
  "scope": {
    "record_types": ["event"],
    "event_categories": ["security"]
  },
  "aggregation": [
    {
      "metric": "count",
      "operator": "gte",
      "value": 3,
      "window": "30m",
      "filters": {
        "subject_vendor_data": "__current__",
        "event.action_type": "login_failed"
      }
    }
  ],
  "actions": [
    { "type": "add_score", "value": 40 },
    { "type": "change_status", "value": "IN_REVIEW" }
  ]
}
```

`"__current__"` significa "o mesmo valor do evento que está sendo avaliado". É assim que uma regra expressa *por titular*, *por dispositivo* ou *por rodada* sem nomear nenhum deles.

## Campos de eventos

As condições leem caminhos com namespace. O vocabulário de transações que você já conhece (`action_type`, `subject_vendor_data`, `subject_ip_country`, `custom_values.<key>`) também pode ser usado em um evento.

| Grupo | Caminhos |
| - | - |
| Evento | `event.category`, `event.action_type`, `event.occurred_at`, `event.amount`, `event.currency`, `event.direction`, `event.session_id`, `event.session_sequence`, `event.score`, `event.status`, `event.ingest_source`, `event.retention_class`, `event.subject_vendor_data`, `event.business_vendor_data` |
| Dispositivo e rede | `event.device.fingerprint`, `event.device.persistent_device_id`, `event.device.bot_score`, `event.ip.address`, `event.ip.country`, `event.ip.asn_number`, `event.ip.asn_organization`, `event.ip.is_vpn_or_tor`, `event.ip.is_data_center`, `event.ip.proxy_type`, `event.ip.country_name`, `event.ip.city`, `event.ip.connection_type`, `event.ip.travel_distance_km`, `event.ip.travel_speed_kmh` |
| Jogo | `event.gameplay.game_id`, `event.gameplay.table_id`, `event.gameplay.round_id`, `event.gameplay.hand_id`, `event.gameplay.match_id`, `event.gameplay.market_id`, `event.gameplay.side`, `event.gameplay.role`, `event.gameplay.counterparty_vendor_data`, `event.gameplay.net_result_amount`, `event.bonus.bonus_id`, `event.affiliate.affiliate_code` |
| Pagamento e disputa | `event.payment.reference_id`, `event.payment.payment_fingerprint`, `event.payment.instrument_reference_hash`, `event.payment.withdrawal_address_hash`, `event.dispute.dispute_id`, `event.dispute.chargeback_id` |
| Segurança e jogo responsável | `event.security.changed_field`, `event.responsible_gambling.identity_match_ref` |
| Telemetria de bots e assistência | `event.bot.timing_variance_ms`, `event.bot.actions_per_minute`, `event.bot.pointer_entropy`, `event.bot.reaction_time_ms_p50`, `event.bot.assistance_indicator` |
| Sinais do titular | `subject.email.risk_score`, `subject.email.social_count`, `subject.email.is_disposable`, `subject.email.deliverability`, `subject.email.domain_reputation`, `subject.email.first_seen_days`, `subject.email.is_breached`, `subject.phone.risk_score`, `subject.phone.line_type`, `subject.phone.social_count`, `subject.phone.carrier`, `subject.phone.country`, `subject.phone.is_disposable` |
| Qualquer outro | `event.payload.<key>`, `custom_values.<key>` |

Os sinais do titular ficam em cache no usuário monitorado e não são recalculados a cada evento, então uma regra pode lê-los durante a ingestão.

## Agregações

### Velocidade

Os redutores que você já usa em transações (`count`, `sum`, `avg`, `min`, `max`, `distinct_count`) aplicados a uma janela móvel `window` (`30m`, `24h`, `7d`, `30d`).

### Razão

Dois redutores sobre a mesma janela. É assim que se expressam as razões entre apostas e depósitos, saques e depósitos, bônus e depósitos e as taxas de chargeback.

```json theme={null}
{
  "metric": "ratio",
  "window": "24h",
  "filters": { "subject_vendor_data": "__current__" },
  "numerator":   { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "bet_placed" } },
  "denominator": { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "deposit_completed" } },
  "operator": "lte",
  "value": 0.1
}
```

Deposite 1.000, aposte 20, solicite um saque, e a razão será 0,02: o clássico caso de lavagem com jogo mínimo.

> [!NOTE]
>
> Uma razão **sem denominador nunca corresponde**. Nenhum depósito não é uma razão igual a zero, é ausência de evidência, e disparar nesse caso sinalizaria todo usuário recém-criado.

### Sequência

Predicados ordenados dentro de uma janela. Cada etapa é correspondida com base em `action_type`, `event_category` ou por um filtro `match` arbitrário, e pode exigir `min_count` ocorrências antes que a sequência avance.

```json theme={null}
{
  "metric": "sequence",
  "key": "ato_drain",
  "window": "24h",
  "steps": [
    { "event_category": "security", "action_type": "login_failed", "min_count": 3 },
    { "event_category": "security", "action_type": "mfa_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_address_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_requested" }
  ]
}
```

Credential stuffing, depois a tomada de controle do MFA, depois o redirecionamento do pagamento e, por fim, o esvaziamento da conta. A regra é disparada no evento que completa a cadeia, e a evidência correspondente lista os ids de evento de cada etapa.

O estado da sequência é mantido por regra e por titular, então ele avança à medida que os eventos chegam, sem reprocessar toda a linha do tempo. O progresso anterior à janela é descartado em vez de contabilizado.

### Correlação

Uma junção entre titulares: aplica um redutor a todos os eventos que compartilham o grupo deste evento.

```json theme={null}
{
  "metric": "correlation",
  "window": "7d",
  "pair": true,
  "group_by": ["subject_vendor_data", "event.gameplay.counterparty_vendor_data"],
  "filters": { "event.action_type": "p2p_settlement" },
  "correlate": {
    "metric": "sum",
    "field": "event.gameplay.net_result_amount",
    "filters": { "event.gameplay.role": "winner" }
  },
  "operator": "gte",
  "value": 500
}
```

`"pair": true` corresponde às duas pontas como um conjunto não ordenado, de modo que A→B e B→A caem no mesmo grupo. É isso que permite que uma única regra enxergue as duas metades de um conluio. Chip dumping, apostas opostas e autoindicação de afiliados têm todos esse formato.

Sempre defina `filters` restritivos para uma regra de correlação. Sem eles, ela considera todos os eventos da janela.

## Regras em tempo real e assíncronas

Algumas regras podem retornar um resultado na própria requisição de ingestão, enquanto outras não.

| Executa | Quais regras |
| - | - |
| **Na requisição** | Velocidade, razão e sequências limitadas (janela de até 24 horas) |
| **Em poucos minutos, de forma assíncrona** | Regras de correlação e sequências com janela superior a 24 horas |

Um evento cujas regras ainda estão pendentes retorna com `"correlation_pending": true`. Seu status e sua pontuação são atualizados no próprio evento quando a etapa assíncrona é concluída; a reexecução é idempotente, então uma regra nunca aplica sua pontuação duas vezes.

Essa divisão é intencional: uma consulta de rede entre titulares não deve fazer um login esperar.

## Ações

O vocabulário de ações é o mesmo das regras de transação: `add_score`, `change_status`, `add_tags`, `add_note`, `add_to_list`, `open_case`.

Há duas diferenças nos eventos:

* `change_status` para `AWAITING_USER` é um resultado exclusivo de transações (não existe fluxo de remediação para eventos) e é aplicado como `IN_REVIEW`.
* `open_case` vincula o caso ao **sujeito** em vez de a uma transação e registra no caso o ID do evento correspondente.

## Evidências

Cada correspondência armazena o que foi observado: a janela de agregação, o valor calculado, o valor esperado, IDs de eventos amostrados e a **origem de cada campo correspondente**.

| Origem | Significado |
| - | - |
| `server` | A Didit o derivou (IP, user agent, origem). É a fonte de referência. |
| `sdk` | Informado pelo SDK da Didit a partir do dispositivo. |
| `customer` | Fornecido pelos seus sistemas. |

Assim, um analista consegue distinguir um IP registrado pelo servidor de uma indicação fornecida pelo cliente antes de agir sobre uma correspondência. O console mostra a origem ao lado de cada campo correspondente no painel lateral do evento.

## Exemplos práticos

> [accordion] Lavagem com jogo mínimo
>
> Depósito, jogo simbólico, saque rápido. Condição `event.action_type eq withdrawal_requested`, mais a razão entre apostas e depósitos mostrada acima em `lte 0.1` ao longo de `24h`.

> [accordion] Fraude amigável
>
> Razão entre `count(chargeback_opened)` e `count(deposit_completed)` por sujeito ao longo de `30d`, `gte 0.5`. Agrupe por `event.payment.payment_fingerprint` em vez do sujeito para detectar um mesmo meio de pagamento usado em várias contas.

> [accordion] Esvaziamento após tomada de conta
>
> A sequência `ato_drain` mostrada acima, com `add_score 90` e `change_status DECLINED`.

> [accordion] Chip dumping
>
> A correlação entre pares mostrada acima. Aumente `value` para o valor que for relevante para as suas mesas e adicione `event.gameplay.game_id` a `group_by` para manter os jogos separados.

> [accordion] Jogo por bots e assistência em tempo real
>
> Condições sobre `event.action_type eq bot_signal_observed`, `event.bot.timing_variance_ms lte 10` e `event.device.bot_score gte 90`, com `add_tags`. Combine com um `distinct_count` de `event.device.fingerprint` por IP para encontrar uma fazenda de bots, e não apenas um script.

> [accordion] Evasão de autoexclusão
>
> Condição sobre `event.action_type eq self_exclusion_match` e `event.payload.re_registration_attempt eq true`, escalando com `open_case`.

## Próximos passos

> [card] [Ingestão de eventos](https://docs.didit.me/pt-br/transaction-monitoring/events.md)
>
> O envelope, as dez categorias e o contrato de lote.

> [card] [API de regras](https://docs.didit.me/pt-br/transaction-monitoring/rules-api.md)
>
> Crie, atualize e faça testes retrospectivos de regras de forma programática.


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