> ## 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.

# Règles d'événements : vélocité, ratio, séquence

> Règles de vélocité, ratio, séquence et corrélation sur les événements, dans le même éditeur que vos règles de transaction Didit.

[Les événements](https://docs.didit.me/fr/transaction-monitoring/events.md) sont évalués par le même moteur que les transactions. Il n'existe qu'un seul modèle de règle, un seul vocabulaire de conditions et un seul jeu d'actions : une règle indique simplement les types d'enregistrements auxquels elle s'applique.

## S'applique à

`scope.record_types` détermine sur quoi une règle se déclenche.

| `record_types` | Déclenchée sur |
| - | - |
| omis ou `["transaction"]` | Transactions uniquement : **la valeur par défaut** |
| `["event"]` | Événements uniquement |
| `["transaction", "event"]` | Les deux |

> [!NOTE]
>
> Laisser ce champ absent maintient une règle limitée aux transactions. Toutes les règles écrites avant l'existence des événements se comportent exactement comme auparavant, et une règle ne commence jamais à correspondre aux connexions parce que son périmètre était vide.

Dans la console, ceci correspond au sélecteur **S'applique à** de l'étape Déclencheur d'une règle. Choisir Événements affiche une liste de contrôle **Catégories d'événements** qui restreint davantage la règle ; laissez-la entièrement décochée pour évaluer toutes les catégories.

```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__"` signifie « la même valeur que l'événement évalué ». C'est ainsi qu'une règle exprime *par sujet*, *par appareil* ou *par manche* sans en nommer un.

Les enregistrements sans la valeur de regroupement ne sont jamais regroupés ensemble. Un événement sans empreinte d'appareil n'est pas « le même appareil » que d'autres événements qui n'en ont pas, et un événement qui n'indique aucun sujet n'est pas « le même sujet » que d'autres événements anonymes : lorsque l'événement évalué n'a pas de valeur pour un champ `"__current__"`, cette agrégation ne correspond pas, quel que soit son opérateur.

## Champs d'événement

Les conditions lisent des chemins avec espaces de noms. Le vocabulaire des transactions que vous connaissez déjà (`action_type`, `subject_vendor_data`, `subject_ip_country`, `custom_values.<key>`) se résout aussi sur un événement.

| Groupe | Chemins |
| - | - |
| Événement | `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` |
| Appareil et réseau | `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` |
| Jeu | `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` |
| Paiement et litige | `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` |
| Sécurité et jeu responsable | `event.security.changed_field`, `event.responsible_gambling.identity_match_ref` |
| Télémétrie de bot et d'assistance | `event.bot.timing_variance_ms`, `event.bot.actions_per_minute`, `event.bot.pointer_entropy`, `event.bot.reaction_time_ms_p50`, `event.bot.assistance_indicator` |
| Signaux du sujet | `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` |
| Autre | `event.payload.<key>`, `custom_values.<key>` |

Les signaux du sujet sont mis en cache sur l'utilisateur surveillé, et non recalculés à chaque événement, si bien qu'une règle peut les lire à la vitesse de l'ingestion.

## Agrégations

### Vélocité

Les réducteurs que vous utilisez déjà sur les transactions (`count`, `sum`, `avg`, `min`, `max`, `distinct_count`) s'appliquent sur une `window` glissante (`30m`, `24h`, `7d`, `30d`).

### Ratio

Deux réducteurs sur la même fenêtre. C'est ainsi qu'on exprime les taux de mise sur dépôt, de retrait sur dépôt, de bonus sur dépôt et de rétrofacturation.

```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
}
```

Dépôt de 1 000, mise de 20, demande de retrait : le ratio vaut 0,02. C'est un blanchiment classique par jeu minimal.

> [!NOTE]
>
> Un ratio **sans dénominateur ne correspond jamais**. L'absence de dépôt n'est pas un ratio de zéro : c'est une absence de preuve, et déclencher la règle dans ce cas signalerait chaque nouvel utilisateur.

### Séquence

Prédicats ordonnés à l'intérieur d'une fenêtre. Chaque étape correspond à un `action_type`, à une `event_category` ou à un filtre `match` arbitraire, et peut exiger des occurrences `min_count` avant que la séquence n'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" }
  ]
}
```

Bourrage d'identifiants, puis prise de contrôle MFA, puis redirection du versement, puis vidage du compte. La règle se déclenche sur l'événement qui complète la chaîne, et les preuves correspondantes listent les identifiants d'événement de chaque étape.

L'état de séquence est conservé par règle et par sujet : il progresse à mesure que les événements arrivent, au lieu de réanalyser la chronologie. La progression antérieure à la fenêtre est écartée plutôt que comptée.

### Corrélation

Une jointure inter-sujets : effectuer une réduction sur tous les événements qui partagent le groupe de cet événement.

```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` fait correspondre les deux extrémités comme un ensemble non ordonné, de sorte que A→B et B→A tombent dans le même groupe. Cela permet à une seule règle de voir les deux moitiés d'une collusion. Le dumping de jetons, les paris opposés et l'auto-parrainage d'affilié ont tous cette forme.

Donnez toujours à une règle de corrélation des `filters` qui la restreignent. Sans eux, elle considère chaque événement de la fenêtre.

## Temps réel et règles asynchrones

Certaines règles peuvent répondre dans la requête d'ingestion, d'autres non.

| Exécution | Règles concernées |
| - | - |
| **Dans la requête** | Vélocité, ratio et séquences bornées (fenêtre de 24 heures maximum) |
| **En quelques minutes, de façon asynchrone** | Règles de corrélation, et séquences dont la fenêtre dépasse 24 heures |

Un événement dont les règles sont encore en attente est renvoyé avec `"correlation_pending": true`. Son statut et son score sont mis à jour sur place dès que la passe asynchrone se termine. La relance est idempotente : une règle n'applique jamais son score deux fois.

Cette séparation est volontaire : une requête visant un réseau de fraude portant sur plusieurs sujets ne doit pas faire attendre une connexion.

## Actions

Le même vocabulaire d'actions que pour les règles de transaction : `add_score`, `change_status`, `add_tags`, `add_note`, `add_to_list`, `open_case`.

Deux différences s'appliquent aux événements :

* `change_status` vers `AWAITING_USER` est un résultat propre aux transactions (il n'existe pas de flux de remédiation pour les événements) et il est appliqué sous la forme `IN_REVIEW`.
* `open_case` rattache le dossier au **sujet** plutôt qu'à une transaction, et enregistre l'identifiant de l'événement correspondant sur le dossier.

## Preuves

Chaque correspondance conserve ce qu'elle a observé : la fenêtre d'agrégation, la valeur calculée, la valeur attendue, les identifiants d'événements échantillonnés et la **source de chaque champ concerné**.

| Source | Signification |
| - | - |
| `server` | Didit l'a déterminée (IP, agent utilisateur, origine). Référence faisant foi. |
| `sdk` | Le SDK Didit l'a transmise depuis l'appareil. |
| `customer` | Vos systèmes l'ont fournie. |

Un analyste peut ainsi distinguer une IP fournie par le serveur d'une indication fournie par le client avant d'agir sur une correspondance. La console affiche la source à côté de chaque champ concerné, dans le panneau de détail de l'événement.

## Exemples détaillés

> [accordion] Blanchiment par jeu minimal
>
> Dépôt, jeu avec des jetons, retrait rapide. Condition `event.action_type eq withdrawal_requested`, plus un ratio mise/dépôt avec `lte 0.1` sur `24h`.

> [accordion] Fraude amicale
>
> Ratio de `count(chargeback_opened)` sur `count(deposit_completed)` par sujet sur `30d`, `gte 0.5`. Regroupez par `event.payment.payment_fingerprint` au lieu du sujet pour repérer un même moyen de paiement utilisé sur plusieurs comptes.

> [accordion] Siphonnage de compte par prise de contrôle
>
> La séquence `ato_drain` décrite ci-dessus, avec `add_score 90` et `change_status DECLINED`.

> [accordion] Dumping de jetons
>
> La corrélation de paires décrite ci-dessus. Augmentez `value` jusqu'au montant significatif pour vos tables, et ajoutez `event.gameplay.game_id` à `group_by` pour séparer les parties.

> [accordion] Jeu par bot et assistance en temps réel
>
> Conditions sur `event.action_type eq bot_signal_observed`, `event.bot.timing_variance_ms lte 10` et `event.device.bot_score gte 90`, avec `add_tags`. Combinez avec un `distinct_count` de `event.device.fingerprint` par IP pour repérer une ferme plutôt qu'un seul script.

> [accordion] Contournement de l'auto-exclusion
>
> Condition sur `event.action_type eq self_exclusion_match` et `event.payload.re_registration_attempt eq true`, avec escalade via `open_case`.

## Suite

> [card] [Ingestion d'événements](https://docs.didit.me/fr/transaction-monitoring/events.md)
>
> L'enveloppe, les dix catégories et le contrat de lot.

> [card] [API des règles](https://docs.didit.me/fr/transaction-monitoring/rules-api.md)
>
> Créez, mettez à jour et effectuez des tests rétrospectifs sur les règles par programmation.


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