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

# Créer un événement de surveillance (API)

> Envoyez un événement de connexion, jeu, bonus, paiement, litige ou sécurité depuis votre backend ; Didit le stocke, l'enrichit et le score.



Prompt de l'API de création d'événement de surveillance
        Copier le prompt dans le presse-papiers



      
      

\<pre>

\`Send one non-monetary monitoring event (login, session, gameplay, bonus, affiliate, payment, dispute, security, responsible gambling or custom) from my backend to Didit.

Endpoint:
POST https://verification.didit.me/v3/events/

Authentication:
Use the x-api-key header with my Didit API key, from my backend only. A scoped key needs transactions: write.

Goal:
\- Record what happened on my platform so Didit's event rules can score it alongside my transactions, and read the verdict from the response.

Request body (application/json):
\{
"event_id": "login-2026-10-17-000001",   // required - my id, unique per application, the idempotency key (max 128)
"event_category": "auth",                // required - auth, session, gameplay, bonus, affiliate, payment, dispute, security, responsible_gambling, custom
"action_type": "login",                  // required - what happened inside the category (max 128)
"occurred_at": "2026-10-17T09:15:02.481Z", // required - at most 7 days in the past, 5 minutes in the future
"subject": { "vendor_data": "user-42", "entity_type": "individual" }, // required - entity_type individual (default) or company
"session": { "session_id": "web-session-abc", "sequence": 142 },
"device_context": { "fingerprint": "didit-fp-v2:a8c1", "network_context": { "ip_address": "203.0.113.42" } },
"transaction_context": { "amount": "1000.00", "currency": "EUR", "payment_reference_id": "dep_735" },
"payload": { "method": "password" },     // category fields, max 16 KB
"custom_values": { "vip_tier": "gold" }  // max 100 scalar keys
}

Behavior:
\- Validated, stored, IP-enriched and evaluated by the real-time event rules before the response returns. Cross-subject and long-window rules run asynchronously within minutes (correlation_pending: true).
\- Some actions require payload keys, for example gameplay.p2p_settlement (game_id, counterparty_vendor_data, stake_amount, net_result_amount, role, and one of hand_id, round_id, match_id), payment.deposit_completed (payment_reference_id, amount, currency, payment_method, status) and dispute.chargeback_opened (payment_reference_id and one of dispute_id, chargeback_id). transaction_context keys count towards these requirements.
\- Send hashes and references, never a card number, a full withdrawal address, a password hash or an MFA secret.
\- Idempotency: the same event_id with the same event_category, action_type, occurred_at, subject.vendor_data and payload returns 200 with idempotent_replay true and the stored event's result. Different values in those fields return 409; the other fields are not compared. Retry safely on timeouts.
\- The IP address used for enrichment and rules is device_context.network_context.ip_address as you send it.
\- In a sandbox application no rules run: status is ACCEPTED and rules_evaluated_count is 0.
\- The subject resolves to the user (or company) with that vendor_data; one is created when none exists.
\- Event ingestion is opt-in: until it is switched on in Transactions > Settings > Event monitoring, this call returns 403 with code event_monitoring_disabled and stores nothing.

Example call:
curl -X POST "https://verification.didit.me/v3/events/" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"event_id":"login-2026-10-17-000001","event_category":"auth","action_type":"login","occurred_at":"2026-10-17T09:15:02.481Z","subject":{"vendor_data":"user-42"},"device_context":{"network_context":{"ip_address":"203.0.113.42"}},"payload":{"method":"password"}}'

What to read from the response:
\- event_uuid - Didit id of the stored event.
\- status - ACCEPTED (stored, no rule changed it), APPROVED, IN_REVIEW or DECLINED.
\- score, rules_evaluated_count, rules_matched_count, rule_matches[] (rule_id, library_key, mode, is_async).
\- correlation_pending - when true, read GET /v3/events/{event_uuid}/ later for the final status.
\- retention_class and expires_at (null for payment and dispute events).
\- idempotent_replay - true when the event was already stored.

Failure modes:
\- 400 - validation error keyed by field (missing field, occurred_at outside the window, payload over 16 KB, nested custom_values, missing required payload keys).
\- 401 - the API key has expired.
\- 403 - missing API key (a wrong, revoked or expired key gets 401), a scoped key without transactions: write, or code event_monitoring_disabled.
\- 409 - event_id reused with different content; use a new event_id.
\- 429 - more than 600 ingestion requests per minute for this API key (event and transaction ingestion share this budget, apart from the 300 of every other write); honor Retry-After.

Side effects: stores the event, may create the subject's user or company, and applies the actions of matched active rules (score, status, tags, notes, list entries, cases).

For the full integration shape, see /integration/integration-prompt.`

\</pre>



      
      

Coller dans

> [!NOTE]
>
> L'ingestion d'événements est facultative. Activez-la dans **Transactions > Settings > Event monitoring** avant d'envoyer des événements ; tant qu'elle ne l'est pas, cet endpoint répond `403` avec `"code": "event_monitoring_disabled"`.[Ingestion des événements](https://docs.didit.me/fr/transaction-monitoring/events.md) présente l'enveloppe, les dix catégories, les clés de payload obligatoires et les classes de conservation. [Règles applicables aux événements](https://docs.didit.me/fr/transaction-monitoring/event-rules.md) explique quelles règles s'exécutent dans la requête et lesquelles s'exécutent de manière asynchrone. Pour envoyer des événements depuis un navigateur ou une application plutôt que depuis votre back-end, utilisez [l'envoi d'événements via le SDK](https://docs.didit.me/fr/transaction-monitoring/sdk-event-submission.md).


## OpenAPI

````yaml fr/openapi-25.json POST /v3/events/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de vérification d'identité. Authentifiez-vous avec l'en-tête x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/events/:
    post:
      tags:
        - Monitoring Events
      summary: Créer un événement de surveillance
      description: >-
        Envoyez un événement non monétaire (connexion, session, jeu, bonus,
        affiliation, paiement, litige, sécurité, jeu responsable ou
        personnalisé) depuis votre backend. L'événement est validé par rapport
        au contrat de sa catégorie, stocké, enrichi par IP une fois par adresse
        publique unique, et évalué par vos règles d'événements en temps réel
        avant le renvoi de la réponse ; les règles multi-sujets et à fenêtre
        longue s'exécutent de manière asynchrone (`correlation_pending: true`),
        et dans une application sandbox, aucune règle ne s'exécute. `event_id`
        est la clé d'idempotence : le même `event_id` avec les mêmes
        `event_category`, `action_type`, `occurred_at`, `subject.vendor_data` et
        `payload` renvoie `200` avec `idempotent_replay: true` et le résultat
        stocké (les autres champs de l'enveloppe ne sont pas comparés), tandis
        que des valeurs différentes renvoient `409`. L'ingestion d'événements
        est activable par application : tant qu'elle n'est pas activée, cet
        endpoint renvoie `403` avec `code: event_monitoring_disabled` et
        n'enregistre rien. Une clé API restreinte nécessite `transactions:
        write`. Consultez [Ingestion
        d'événements](https://docs.didit.me/fr/transaction-monitoring/events) et
        [Règles sur les
        événements](https://docs.didit.me/fr/transaction-monitoring/event-rules)
        ; pour envoyer des événements depuis un navigateur ou une application,
        utilisez la [Soumission d'événements par
        SDK](https://docs.didit.me/fr/transaction-monitoring/sdk-event-submission).
      operationId: create_monitoring_event
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MonitoringEventCreateRequest'
            examples:
              Login:
                value:
                  event_id: login-2026-10-17-000001
                  event_category: auth
                  action_type: login
                  occurred_at: '2026-10-17T09:15:02.481Z'
                  time_zone: Europe/Madrid
                  subject:
                    vendor_data: user-42
                    entity_type: individual
                  session:
                    session_id: web-session-abc
                    sequence: 142
                  device_context:
                    fingerprint: fp-a8c1
                    network_context:
                      ip_address: 203.0.113.42
                  payload:
                    method: password
                  custom_values:
                    vip_tier: gold
              Deposit completed:
                value:
                  event_id: deposit-2026-10-17-000002
                  event_category: payment
                  action_type: deposit_completed
                  occurred_at: '2026-10-17T09:16:40Z'
                  subject:
                    vendor_data: user-42
                  transaction_context:
                    amount: '100.00'
                    currency: EUR
                    direction: inbound
                    payment_reference_id: dep_736
                  payload:
                    payment_method: card
                    status: completed
              Chargeback opened:
                value:
                  event_id: chargeback-2026-10-16-000318
                  event_category: dispute
                  action_type: chargeback_opened
                  occurred_at: '2026-10-16T14:02:11Z'
                  subject:
                    vendor_data: user-42
                  payload:
                    payment_reference_id: dep_735
                    chargeback_id: cb_5521
                    amount: '250.00'
                    currency: EUR
                    reason_code: fraud
      responses:
        '200':
          description: >-
            Rejeu idempotent : un événement avec cet `event_id` et le même
            contenu est déjà stocké. Rien n'a été stocké ni évalué à nouveau ;
            le corps décrit l'événement stocké.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitoringEventIngestResult'
              examples:
                Replay:
                  value:
                    event_uuid: 33333333-4444-5555-6666-777777777777
                    event_id: login-2026-10-17-000001
                    status: ACCEPTED
                    score: 0
                    rules_evaluated_count: 6
                    rules_matched_count: 0
                    correlation_pending: false
                    retention_class: standard
                    expires_at: '2026-11-16T09:15:02.481000Z'
                    idempotent_replay: true
                    rule_matches: []
        '201':
          description: L'événement a été stocké et évalué.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitoringEventIngestResult'
              examples:
                Stored, no rule matched:
                  value:
                    event_uuid: 33333333-4444-5555-6666-777777777777
                    event_id: login-2026-10-17-000001
                    status: ACCEPTED
                    score: 0
                    rules_evaluated_count: 6
                    rules_matched_count: 0
                    correlation_pending: false
                    retention_class: standard
                    expires_at: '2026-11-16T09:15:02.481000Z'
                    idempotent_replay: false
                    rule_matches: []
                Rule matched, async rule pending:
                  value:
                    event_uuid: 33333333-4444-5555-6666-777777777777
                    event_id: login-2026-10-17-000001
                    status: IN_REVIEW
                    score: 40
                    rules_evaluated_count: 6
                    rules_matched_count: 1
                    correlation_pending: true
                    retention_class: risk_relevant
                    expires_at: '2027-01-15T09:15:02.481000Z'
                    idempotent_replay: false
                    rule_matches:
                      - rule_id: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
                        library_key: null
                        mode: ACTIVE
                        is_async: false
        '400':
          description: >-
            Échec de la validation. Le corps est indexé par champ ; les champs
            imbriqués sont des objets imbriqués. Rien n'est enregistré.
          content:
            application/json:
              examples:
                Missing fields:
                  value:
                    event_id:
                      - This field is required.
                    subject:
                      - This field is required.
                Unknown category:
                  value:
                    event_category:
                      - '"login" is not a valid choice.'
                occurred_at too old:
                  value:
                    occurred_at:
                      - >-
                        occurred_at is more than 7 days in the past. Use the
                        batch import lane for backfills.
                occurred_at in the future:
                  value:
                    occurred_at:
                      - occurred_at is more than 5 minutes in the future.
                Missing subject vendor_data:
                  value:
                    subject:
                      vendor_data:
                        - This field is required.
                Missing required payload keys:
                  value:
                    payload:
                      - >-
                        payment.deposit_completed requires: payment_method,
                        status.
                Missing one-of payload key:
                  value:
                    payload:
                      - >-
                        dispute.chargeback_opened requires one of: dispute_id,
                        chargeback_id.
                Security change without changed_field:
                  value:
                    payload:
                      - security.*_changed requires 'changed_field'.
                Payload too large:
                  value:
                    payload:
                      - >-
                        payload exceeds 16384 bytes. Summarise telemetry
                        client-side.
                Too many custom_values:
                  value:
                    custom_values:
                      - custom_values accepts at most 100 keys.
                Nested custom value:
                  value:
                    custom_values:
                      - >-
                        custom_values['limits'] must be a scalar - rule
                        conditions cannot address nested values.
        '401':
          description: >-
            La clé API restreinte a expiré. Seule une clé expirée renvoie `401`
            ; une clé manquante ou invalide renvoie `403`.
          content:
            application/json:
              examples:
                Expired key:
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            Un en-tête `x-api-key` manquant (une clé erronée, révoquée ou
            expirée renvoie `401`), une clé restreinte sans `transactions:
            write`, une clé limitée à certains workflows ou à des sessions
            approuvées (une telle clé n'accède jamais aux données de
            surveillance des transactions), ou une requête provenant de
            l'extérieur de la liste d'autorisation IP de la clé. Également
            renvoyé avec `code: event_monitoring_disabled` lorsque l'ingestion
            d'événements est désactivée pour l'application ; rien n'est stocké
            dans ce cas, et la vérification s'exécute avant que le corps ne soit
            validé.
          content:
            application/json:
              examples:
                Event monitoring disabled:
                  value:
                    detail: >-
                      Event monitoring is not enabled for this application. Turn
                      on event ingestion in the transaction monitoring settings
                      before submitting events.
                    code: event_monitoring_disabled
                Missing or invalid API key:
                  value:
                    detail: You do not have permission to perform this action.
                Scoped key without access:
                  value:
                    detail: This API key has no write access to transactions.
                Key limited to workflows or approved sessions:
                  value:
                    detail: >-
                      This API key only reaches sessions inside its workflow or
                      status limits, so it can't use this endpoint.
                IP not allowed:
                  value:
                    detail: This API key can't be used from this IP address.
        '409':
          description: >-
            `event_id` a déjà été utilisé pour un événement avec un contenu
            différent (catégorie, type d'action, `occurred_at`, `vendor_data` du
            sujet ou payload). Envoyez l'événement sous un nouvel `event_id`.
          content:
            application/json:
              examples:
                event_id reused:
                  value:
                    event_id: >-
                      event_id 'login-2026-10-17-000001' already exists with a
                      different payload.
        '429':
          description: >-
            Limite de débit dépassée : les créations de transactions et
            l'ingestion d'événements (`POST /v3/transactions/`, `POST
            /v3/events/`, `POST /v3/events/batch/`) partagent un quota de 600
            requêtes par minute par clé API, distinct des 300 requêtes partagées
            par toutes les autres requêtes d'écriture. Attendez `Retry-After`
            secondes, puis réessayez.
          headers:
            Retry-After:
              description: >-
                Secondes à attendre avant de réessayer, arrondies à l'unité
                supérieure pour que la tentative se fasse dans la fenêtre
                suivante.
              schema:
                type: integer
                minimum: 1
                example: 30
          content:
            application/json:
              examples:
                Throttled:
                  value:
                    detail: >-
                      Ingestion rate limit exceeded. You can make up to 600
                      requests per minute.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST 'https://verification.didit.me/v3/events/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "event_id": "login-2026-10-17-000001",
                "event_category": "auth",
                "action_type": "login",
                "occurred_at": "2026-10-17T09:15:02.481Z",
                "subject": {"vendor_data": "user-42", "entity_type": "individual"},
                "session": {"session_id": "web-session-abc", "sequence": 142},
                "device_context": {
                  "fingerprint": "fp-a8c1",
                  "network_context": {"ip_address": "203.0.113.42"}
                },
                "payload": {"method": "password"}
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.monitoring_events.create(
                event_id="login-2026-10-17-000001",
                event_category="auth",
                action_type="login",
                occurred_at="2026-10-17T09:15:02.481Z",
                time_zone="Europe/Madrid",
                subject={
                    "vendor_data": "user-42",
                    "entity_type": "individual",
                },
                session={
                    "session_id": "web-session-abc",
                    "sequence": 142,
                },
                device_context={
                    "fingerprint": "fp-a8c1",
                    "network_context": {
                        "ip_address": "203.0.113.42",
                    },
                },
                payload={"method": "password"},
                custom_values={"vip_tier": "gold"},
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.monitoringEvents.create({
              event_id: "login-2026-10-17-000001",
              event_category: "auth",
              action_type: "login",
              occurred_at: "2026-10-17T09:15:02.481Z",
              time_zone: "Europe/Madrid",
              subject: {
                vendor_data: "user-42",
                entity_type: "individual",
              },
              session: {
                session_id: "web-session-abc",
                sequence: 142,
              },
              device_context: {
                fingerprint: "fp-a8c1",
                network_context: {
                  ip_address: "203.0.113.42",
                },
              },
              payload: { method: "password" },
              custom_values: { vip_tier: "gold" },
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.Create(ctx, didit.MonitoringEventCreateRequest{\n\tEventID:       \"login-2026-10-17-000001\",\n\tEventCategory: \"auth\",\n\tActionType:    \"login\",\n\tOccurredAt:    time.Date(2026, 10, 17, 9, 15, 2, 0, time.UTC),\n\tTimeZone:      didit.String(\"Europe/Madrid\"),\n\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\tVendorData: \"user-42\",\n\t\tEntityType: didit.String(\"individual\"),\n\t},\n\tSession: didit.Some(didit.MonitoringEventCreateRequestSession{\n\t\tSessionID: didit.String(\"web-session-abc\"),\n\t\tSequence:  didit.Int(142),\n\t}),\n\tDeviceContext: didit.Some(didit.MonitoringEventCreateRequestDeviceContext{\n\t\tFingerprint: didit.String(\"fp-a8c1\"),\n\t\tNetworkContext: didit.Some(didit.MonitoringEventCreateRequestDeviceContextNetworkContext{\n\t\t\tIPAddress: didit.String(\"203.0.113.42\"),\n\t\t}),\n\t}),\n\tPayload:      didit.Some(map[string]any{\"method\": \"password\"}),\n\tCustomValues: didit.Some(map[string]any{\"vip_tier\": \"gold\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.time.OffsetDateTime;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.MonitoringEventCreateRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.monitoringEvents().create(MonitoringEventCreateRequest.builder()
                    .eventId("login-2026-10-17-000001")
                    .eventCategory(MonitoringEventCreateRequest.EventCategory.of("auth"))
                    .actionType("login")
                    .occurredAt(OffsetDateTime.parse("2026-10-17T09:15:02.481Z"))
                    .timeZone("Europe/Madrid")
                    .subject(MonitoringEventCreateRequest.Subject.builder()
                            .vendorData("user-42")
                            .entityType("individual")
                            .build())
                    .session(MonitoringEventCreateRequest.Session.builder()
                            .sessionId("web-session-abc")
                            .sequence(142L)
                            .build())
                    .deviceContext(MonitoringEventCreateRequest.DeviceContext.builder()
                            .fingerprint("fp-a8c1")
                            .networkContext(MonitoringEventCreateRequest.DeviceContext.NetworkContext.builder()
                                    .ipAddress("203.0.113.42")
                                    .build())
                            .build())
                    .payload(Map.of("method", "password"))
                    .customValues(Map.of("vip_tier", MonitoringEventCreateRequest.CustomValuesValue.ofString("gold")))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->monitoringEvents->create([
                'event_id' => 'login-2026-10-17-000001',
                'event_category' => 'auth',
                'action_type' => 'login',
                'occurred_at' => '2026-10-17T09:15:02.481Z',
                'time_zone' => 'Europe/Madrid',
                'subject' => [
                    'vendor_data' => 'user-42',
                    'entity_type' => 'individual',
                ],
                'session' => [
                    'session_id' => 'web-session-abc',
                    'sequence' => 142,
                ],
                'device_context' => [
                    'fingerprint' => 'fp-a8c1',
                    'network_context' => [
                        'ip_address' => '203.0.113.42',
                    ],
                ],
                'payload' => ['method' => 'password'],
                'custom_values' => ['vip_tier' => 'gold'],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.monitoring_events.create(
              event_id: "login-2026-10-17-000001",
              event_category: "auth",
              action_type: "login",
              occurred_at: "2026-10-17T09:15:02.481Z",
              time_zone: "Europe/Madrid",
              subject: {
                vendor_data: "user-42",
                entity_type: "individual",
              },
              session: {
                session_id: "web-session-abc",
                sequence: 142,
              },
              device_context: {
                fingerprint: "fp-a8c1",
                network_context: {
                  ip_address: "203.0.113.42",
                },
              },
              payload: { method: "password" },
              custom_values: { vip_tier: "gold" }
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.MonitoringEvents.CreateAsync(new
            MonitoringEventCreateRequest

            {
                EventId = "login-2026-10-17-000001",
                EventCategory = "auth",
                ActionType = "login",
                OccurredAt = DateTimeOffset.Parse("2026-10-17T09:15:02.481Z"),
                TimeZone = "Europe/Madrid",
                Subject = new()
                {
                    VendorData = "user-42",
                    EntityType = "individual",
                },
                Session = new MonitoringEventCreateRequestSession
                {
                    SessionId = "web-session-abc",
                    Sequence = 142,
                },
                DeviceContext = new MonitoringEventCreateRequestDeviceContext
                {
                    Fingerprint = "fp-a8c1",
                    NetworkContext = new MonitoringEventCreateRequestDeviceContextNetworkContext
                    {
                        IpAddress = "203.0.113.42",
                    },
                },
                Payload = new Dictionary<string, object> { ["method"] = "password" },
                CustomValues = new Dictionary<string, object> { ["vip_tier"] = "gold" },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    MonitoringEventCreateRequest:
      type: object
      description: >-
        L'enveloppe de l'événement, identique pour chaque catégorie. Les alias
        en camelCase sont acceptés : `eventId`, `eventCategory` (ou `category`),
        `actionType`, `occurredAt`, `timeZone` (ou `zoneId`), `deviceContext`
        (ou `device`), `transactionContext`, `customValues` (ou `props`) ; dans
        `subject` : `vendorData`, `entityType`, `fullName` ; dans `session` :
        `sessionId`, `pageUrl` ; dans `transaction_context` :
        `paymentReferenceId`.
      required:
        - event_id
        - event_category
        - action_type
        - occurred_at
        - subject
      properties:
        event_id:
          type: string
          maxLength: 128
          description: >-
            Votre identifiant pour l'événement, unique par application. Il
            s'agit de la clé d'idempotence : renvoyer les mêmes
            `event_category`, `action_type`, `occurred_at`,
            `subject.vendor_data` et `payload` sous cet identifiant constitue un
            rejeu, toute modification constitue un conflit.
          example: login-2026-10-17-000001
        event_category:
          type: string
          enum:
            - auth
            - session
            - gameplay
            - bonus
            - affiliate
            - payment
            - dispute
            - security
            - responsible_gambling
            - custom
          description: Catégorie d'événement.
          example: auth
        action_type:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Ce qui s'est passé au sein de la catégorie. Vocabulaire ouvert ; les
            actions gérées listées dans [Event
            ingestion](https://docs.didit.me/fr/transaction-monitoring/events)
            (par exemple `login`, `deposit_completed`, `chargeback_opened`)
            débloquent la validation typée et les champs de règles gérées. Les
            espaces de début et de fin sont supprimés.
          example: login
        occurred_at:
          type: string
          format: date-time
          description: >-
            Date et heure de l'événement de votre côté, ISO 8601 (une valeur
            sans fuseau horaire est lue comme UTC). Ne doit pas dater de plus de
            7 jours dans le passé ni dépasser 5 minutes dans le futur.
          example: '2026-10-17T09:15:02.481Z'
        time_zone:
          type: string
          nullable: true
          maxLength: 64
          description: >-
            Fuseau horaire de l'occurrence de votre côté, par exemple
            `Europe/Madrid`. Enregistré avec l'événement ; non renvoyé par les
            endpoints de lecture.
        subject:
          type: object
          description: >-
            L'utilisateur ou l'entreprise auquel appartient l'événement. Il
            correspond à l'utilisateur (ou l'entreprise) ayant ce `vendor_data`
            dans votre application ; un utilisateur ou une entreprise est
            créé(e) lorsqu'il n'en existe aucun(e).
          required:
            - vendor_data
          properties:
            vendor_data:
              type: string
              minLength: 1
              maxLength: 255
              description: Votre identifiant pour le sujet.
              example: user-42
            entity_type:
              type: string
              maxLength: 32
              default: individual
              description: >-
                `company` associe le sujet à une entreprise ; toute autre valeur
                (`individual` par défaut) l'associe à un individu. Un même
                `vendor_data` peut désigner une entreprise et un individu.
              example: individual
            full_name:
              type: string
              nullable: true
              maxLength: 512
              description: >-
                Nom d'affichage, utilisé uniquement lorsque cet événement crée
                l'utilisateur ou l'entreprise.
            email:
              type: string
              format: email
              nullable: true
              description: Validé comme adresse e-mail ; non stocké sur l'événement.
            phone:
              type: string
              nullable: true
              maxLength: 32
              description: Validé ; non stocké sur l'événement.
            country:
              type: string
              nullable: true
              maxLength: 3
              description: Validé ; non stocké sur l'événement.
        business:
          type: object
          description: >-
            L'entreprise à laquelle appartient l'événement, lorsqu'elle diffère
            du sujet. Seul `vendor_data` est lu.
          additionalProperties: true
          properties:
            vendor_data:
              type: string
              maxLength: 255
              description: >-
                Votre identifiant pour l'entreprise. Filtrable via
                `business_vendor_data`.
              example: merchant-7
        session:
          type: object
          description: Le contexte de votre session pour l'événement.
          properties:
            session_id:
              type: string
              nullable: true
              maxLength: 255
              description: >-
                Votre identifiant de session. Filtrable et renvoyé sous la forme
                `session_id`.
            sequence:
              type: integer
              nullable: true
              description: >-
                Position de l'événement au sein de la session. Renvoyée sous
                `session_sequence`.
            page_url:
              type: string
              nullable: true
              maxLength: 2048
              description: Validé ; non stocké sur l'événement.
            referrer:
              type: string
              nullable: true
              maxLength: 2048
              description: Validé ; non stocké sur l'événement.
        device_context:
          type: object
          additionalProperties: true
          description: >-
            Contexte de l'appareil et du réseau, stocké tel quel et renvoyé par
            `GET /v3/events/{event_uuid}/`. Sur cette voie serveur, Didit ne
            voit pas la connexion de l'utilisateur final ; l'IP enrichie et
            utilisée par les règles est donc `network_context.ip_address` telle
            que vous l'envoyez.
          properties:
            fingerprint:
              type: string
              maxLength: 255
              description: Empreinte de l'appareil. Filtrable via `device_fingerprint`.
            persistent_device_id:
              type: string
              maxLength: 255
              description: Votre identifiant d'appareil persistant.
            bot_score:
              type: integer
              description: >-
                Score de bot issu de votre propre détection, sous forme
                d'entier.
            network_context:
              type: object
              additionalProperties: true
              properties:
                ip_address:
                  type: string
                  maxLength: 64
                  description: >-
                    Adresse IP de l'utilisateur final. Les adresses publiques
                    sont enrichies une fois par adresse unique.
                  example: 203.0.113.42
        transaction_context:
          type: object
          description: >-
            Contexte monétaire. Les valeurs non vides ici satisfont également
            les clés de payload requises de l'action.
          properties:
            amount:
              type: string
              nullable: true
              description: >-
                Montant sous forme de chaîne décimale (un nombre est également
                accepté).
              example: '1000.00'
            currency:
              type: string
              nullable: true
              maxLength: 10
              description: Code devise.
            direction:
              type: string
              nullable: true
              maxLength: 16
              description: >-
                Direction du mouvement de fonds, par exemple `inbound` ou
                `outbound`.
            payment_reference_id:
              type: string
              nullable: true
              maxLength: 255
              description: >-
                Votre référence de paiement. Filtrable via
                `payment_reference_id`.
        payload:
          type: object
          additionalProperties: true
          description: >-
            Les champs de domaine de la catégorie, au maximum 16384 octets une
            fois encodés en JSON. Certaines actions requièrent des clés (dans
            `payload` ou `transaction_context`) : `gameplay.p2p_settlement`
            nécessite `game_id`, `counterparty_vendor_data`, `stake_amount`,
            `net_result_amount`, `role` et l'un des champs `hand_id`,
            `round_id`, `match_id` ; `gameplay.bet_placed` et
            `gameplay.bet_settled` nécessitent `game_id` ;
            `payment.deposit_initiated`, `payment.deposit_completed`,
            `payment.withdrawal_requested` et `payment.withdrawal_completed`
            nécessitent `payment_reference_id`, `amount`, `currency`,
            `payment_method`, `status` ; `payment.withdrawal_address_changed`
            nécessite `withdrawal_address_hash` ; `dispute.chargeback_opened`,
            `dispute.chargeback_won` et `dispute.chargeback_lost` nécessitent
            `payment_reference_id` et l'un des champs `dispute_id`,
            `chargeback_id` ; `session.bot_signal_observed` nécessite
            `telemetry_schema_version` et l'un des champs `bot_score`,
            `actions_per_minute`, `timing_variance_ms`, `pointer_entropy`,
            `keystroke_entropy`, `reaction_time_ms_p50` ;
            `responsible_gambling.self_exclusion_match` nécessite
            `registry_source`, `exclusion_status`, `identity_match_ref`. Chaque
            action `security` se terminant par `_changed` nécessite
            `changed_field`, ainsi que `previous_reference_hash` ou
            `new_reference_hash` lorsque le champ est `password`, `mfa_method`,
            `mfa`, `email`, `phone`, `withdrawal_address`, `payout_method` ou
            `api_key`. Envoyez des hachages et des références, jamais un numéro
            de carte, une adresse de retrait complète, un hachage de mot de
            passe ou un secret MFA.
        custom_values:
          type: object
          description: >-
            Jusqu'à 100 clés personnalisées, adressables depuis les règles sous
            la forme `custom_values.<key>`. Les valeurs doivent être des
            scalaires (chaîne, nombre, booléen ou null) ; les objets imbriqués
            et les tableaux sont rejetés.
          additionalProperties:
            nullable: true
            oneOf:
              - type: string
              - type: number
              - type: boolean
      example:
        event_id: login-2026-10-17-000001
        event_category: auth
        action_type: login
        occurred_at: '2026-10-17T09:15:02.481Z'
        time_zone: Europe/Madrid
        subject:
          vendor_data: user-42
          entity_type: individual
        session:
          session_id: web-session-abc
          sequence: 142
        device_context:
          fingerprint: fp-a8c1
          network_context:
            ip_address: 203.0.113.42
        payload:
          method: password
        custom_values:
          vip_tier: gold
    MonitoringEventIngestResult:
      type: object
      description: >-
        Résultat de l'ingestion d'un événement. Le même format est renvoyé pour
        un nouvel événement et pour un rejeu idempotent.
      required:
        - event_uuid
        - event_id
        - status
        - score
        - rules_evaluated_count
        - rules_matched_count
        - correlation_pending
        - retention_class
        - expires_at
        - idempotent_replay
        - rule_matches
      properties:
        event_uuid:
          type: string
          format: uuid
          description: Identifiant Didit de l'événement stocké.
        event_id:
          type: string
          description: Votre `event_id`.
        status:
          type: string
          enum:
            - ACCEPTED
            - APPROVED
            - IN_REVIEW
            - DECLINED
          description: >-
            Statut après l'exécution des règles en temps réel. Voir
            `MonitoringEvent.status`.
        score:
          type: integer
          description: Score après l'exécution des règles en temps réel.
        rules_evaluated_count:
          type: integer
          minimum: 0
          description: >-
            Nombre de règles d'événement évaluées dans la requête. 0 dans une
            application sandbox, où aucune règle n'est exécutée.
        rules_matched_count:
          type: integer
          minimum: 0
          description: >-
            Nombre de règles correspondantes, y compris les règles en mode
            `TEST`.
        correlation_pending:
          type: boolean
          description: >-
            `true` lorsqu'une règle asynchrone doit encore s'exécuter. Consultez
            `GET /v3/events/{event_uuid}/` quelques minutes plus tard pour
            obtenir le `status` et le `score` finaux.
        retention_class:
          type: string
          enum:
            - low_value
            - standard
            - risk_relevant
            - monetary_or_compliance
          description: >-
            Classe de conservation, après toute promotion par une règle
            correspondante.
        expires_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Date et heure auxquelles l'événement expire selon sa classe de
            conservation et est supprimé. Null pour les événements
            `monetary_or_compliance` (paiement et litige).
        idempotent_replay:
          type: boolean
          description: >-
            `true` lorsqu'un événement avec cet `event_id` et le même contenu a
            déjà été enregistré ; les valeurs sont celles de l'événement stocké
            et aucune règle n'a été réexécutée.
        rule_matches:
          type: array
          description: Règles ayant correspondu à l'événement.
          items:
            type: object
            required:
              - rule_id
              - library_key
              - mode
              - is_async
            properties:
              rule_id:
                type: string
                format: uuid
                description: UUID de la règle.
              library_key:
                type: string
                nullable: true
                description: >-
                  Clé de bibliothèque lorsque la règle a été installée depuis la
                  bibliothèque de règles, sinon null.
              mode:
                type: string
                enum:
                  - ACTIVE
                  - TEST
                description: >-
                  Les règles `TEST` enregistrent la correspondance mais
                  n'appliquent aucune action.
              is_async:
                type: boolean
                description: >-
                  `true` lorsque la correspondance provient de la passe
                  asynchrone.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clé API de votre application, issue de Développeurs -> Clés API dans
        la Business Console. La clé principale dispose d'un accès complet. Une
        clé nommée peut être restreinte : aucun, lecture ou écriture par
        ressource, limitée à certains workflows ou aux sessions approuvées, à
        une liste d'adresses IP et à une date d'expiration. 401 signifie que la
        clé est incorrecte, révoquée ou expirée ; 403 signifie qu'aucune clé n'a
        été envoyée, que la clé n'a pas accès à cette ressource ou action, ou
        que la requête provient d'une adresse hors de sa liste d'IP ; 404 sur
        une route de session signifie que la session est hors des workflows ou
        des statuts de la clé. Une clé sans accès aux médias reçoit les URL
        d'images, de vidéos et de PDF à null, et une clé sans accès en écriture
        aux sessions reçoit les liens et tokens de session à null. Voir
        https://docs.didit.me/console/api-keys.

````

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