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

# Buat Event Pemantauan API

> Kirim event login, gameplay, bonus, pembayaran, sengketa, atau keamanan dari backend ke Didit untuk disimpan dan dinilai oleh aturan event Anda.



Prompt API untuk Membuat Event Pemantauan
        Salin prompt ke papan klip



      
      

\<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>



      
      

Tempel ke

> [!NOTE]
>
> Ingesti event bersifat opt-in. Aktifkan terlebih dahulu di **Transactions > Settings > Event monitoring** sebelum Anda mengirim event. Sampai fitur ini diaktifkan, endpoint ini merespons `403` dengan `"code": "event_monitoring_disabled"`.[Ingesti event](https://docs.didit.me/id/transaction-monitoring/events.md) mencakup envelope, sepuluh kategori, kunci payload yang wajib diisi, dan kelas retensi. [Aturan event](https://docs.didit.me/id/transaction-monitoring/event-rules.md) menjelaskan aturan mana yang dijalankan dalam permintaan dan mana yang dijalankan secara asinkron. Untuk mengirim event dari browser atau aplikasi, alih-alih dari backend Anda, gunakan [pengiriman event melalui SDK](https://docs.didit.me/id/transaction-monitoring/sdk-event-submission.md).


## OpenAPI

````yaml id/openapi-25.json POST /v3/events/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API Verifikasi Identitas. Lakukan autentikasi dengan header x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/events/:
    post:
      tags:
        - Monitoring Events
      summary: Buat event pemantauan
      description: >-
        Kirim satu event nonmoneter (login, sesi, gameplay, bonus, afiliasi,
        pembayaran, sengketa, keamanan, perjudian yang bertanggung jawab, atau
        kustom) dari backend Anda. Event divalidasi terhadap kontrak
        kategorinya, disimpan, diperkaya dengan informasi IP satu kali per
        alamat publik unik, dan dievaluasi oleh aturan event real-time Anda
        sebelum respons dikembalikan; aturan lintas-subjek dan jendela waktu
        yang panjang berjalan secara asinkron (`correlation_pending: true`), dan
        dalam aplikasi sandbox tidak ada aturan yang berjalan. `event_id` adalah
        kunci idempotensi: `event_id` yang sama dengan `event_category`,
        `action_type`, `occurred_at`, `subject.vendor_data`, dan `payload` yang
        sama mengembalikan `200` dengan `idempotent_replay: true` dan hasil yang
        disimpan (kolom lain dalam envelope tidak dibandingkan), sedangkan nilai
        yang berbeda mengembalikan `409`. Penyerapan event bersifat opt-in per
        aplikasi: hingga diaktifkan, endpoint ini mengembalikan `403` dengan
        `code: event_monitoring_disabled` dan tidak menyimpan apa pun. Kunci API
        dengan cakupan memerlukan `transactions: write`. Lihat [Penyerapan
        event](https://docs.didit.me/id/transaction-monitoring/events) dan
        [Aturan pada
        event](https://docs.didit.me/id/transaction-monitoring/event-rules);
        untuk mengirim event dari browser atau aplikasi, gunakan [Pengiriman
        event
        SDK](https://docs.didit.me/id/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: >-
            Pemutaran ulang idempoten: event dengan `event_id` ini dan konten
            yang sama sudah tersimpan. Tidak ada yang disimpan atau dievaluasi
            ulang; body menjelaskan event yang tersimpan.
          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: Event telah disimpan dan dievaluasi.
          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: >-
            Validasi gagal. Body diindeks berdasarkan kolom; kolom bersarang
            berupa objek bersarang. Tidak ada yang disimpan.
          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: >-
            Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci
            yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak
            valid menerima `403`.
          content:
            application/json:
              examples:
                Expired key:
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa
            menghasilkan `401`), kunci dengan pembatasan cakupan tanpa
            `transactions: write`, kunci yang dibatasi pada alur kerja tertentu
            atau pada sesi yang disetujui (kunci semacam itu tidak pernah
            mengakses data pemantauan transaksi), atau permintaan dari luar
            allowlist IP milik kunci tersebut. Juga dikembalikan dengan `code:
            event_monitoring_disabled` saat penyerapan event dinonaktifkan untuk
            aplikasi; tidak ada yang disimpan dalam kasus tersebut, dan
            pemeriksaan berjalan sebelum body divalidasi.
          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` sudah digunakan untuk event dengan konten berbeda
            (kategori, jenis tindakan, `occurred_at`, `vendor_data` subjek, atau
            payload). Kirim event dengan `event_id` baru.
          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: >-
            Batas laju terlampaui: pembuatan transaksi dan penyerapan event
            (`POST /v3/transactions/`, `POST /v3/events/`, `POST
            /v3/events/batch/`) berbagi anggaran sebanyak 600 permintaan per
            menit per kunci API, terpisah dari anggaran 300 permintaan yang
            digunakan bersama oleh semua permintaan tulis lainnya. Tunggu
            `Retry-After` detik, lalu coba lagi.
          headers:
            Retry-After:
              description: >-
                Detik yang harus ditunggu sebelum mencoba lagi, dibulatkan ke
                atas agar percobaan berikutnya berada di jendela berikutnya.
              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: >-
        Envelope untuk event, sama untuk setiap kategori. Alias camelCase
        diterima: `eventId`, `eventCategory` (atau `category`), `actionType`,
        `occurredAt`, `timeZone` (atau `zoneId`), `deviceContext` (atau
        `device`), `transactionContext`, `customValues` (atau `props`); di dalam
        `subject`: `vendorData`, `entityType`, `fullName`; di dalam `session`:
        `sessionId`, `pageUrl`; di dalam `transaction_context`:
        `paymentReferenceId`.
      required:
        - event_id
        - event_category
        - action_type
        - occurred_at
        - subject
      properties:
        event_id:
          type: string
          maxLength: 128
          description: >-
            Pengidentifikasi Anda untuk event tersebut, unik per aplikasi. Nilai
            ini merupakan kunci idempotensi: mengirim ulang `event_category`,
            `action_type`, `occurred_at`, `subject.vendor_data`, dan `payload`
            yang sama di bawahnya dianggap sebagai replay, sedangkan perbedaan
            apa pun akan menimbulkan konflik.
          example: login-2026-10-17-000001
        event_category:
          type: string
          enum:
            - auth
            - session
            - gameplay
            - bonus
            - affiliate
            - payment
            - dispute
            - security
            - responsible_gambling
            - custom
          description: Kategori peristiwa.
          example: auth
        action_type:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Hal yang terjadi dalam kategori. Kosakata terbuka; tindakan
            terkelola yang tercantum di [Penyerapan
            peristiwa](https://docs.didit.me/id/transaction-monitoring/events)
            (misalnya `login`, `deposit_completed`, `chargeback_opened`) membuka
            validasi bertipe dan kolom aturan terkelola. Spasi di awal dan akhir
            akan dipangkas.
          example: login
        occurred_at:
          type: string
          format: date-time
          description: >-
            Waktu ketika peristiwa terjadi di pihak Anda, ISO 8601 (nilai tanpa
            offset dibaca sebagai UTC). Tidak boleh lebih dari 7 hari di masa
            lalu dan tidak lebih dari 5 menit di masa depan.
          example: '2026-10-17T09:15:02.481Z'
        time_zone:
          type: string
          nullable: true
          maxLength: 64
          description: >-
            Zona waktu kejadian di pihak Anda, misalnya `Europe/Madrid`.
            Disimpan bersama peristiwa; tidak dikembalikan oleh endpoint baca.
        subject:
          type: object
          description: >-
            Pengguna atau perusahaan yang terkait dengan event tersebut. Nilai
            ini merujuk ke pengguna (atau perusahaan) dengan `vendor_data` ini
            di aplikasi Anda; entitas baru akan dibuat jika belum ada.
          required:
            - vendor_data
          properties:
            vendor_data:
              type: string
              minLength: 1
              maxLength: 255
              description: ID Anda untuk subjek tersebut.
              example: user-42
            entity_type:
              type: string
              maxLength: 32
              default: individual
              description: >-
                `company` menetapkan subjek sebagai perusahaan; nilai lainnya
                (default `individual`) menetapkannya sebagai perorangan.
                `vendor_data` yang sama dapat menamai satu dari masing-masing
                jenis.
              example: individual
            full_name:
              type: string
              nullable: true
              maxLength: 512
              description: >-
                Nama tampilan, hanya digunakan saat event ini membuat pengguna
                atau perusahaan.
            email:
              type: string
              format: email
              nullable: true
              description: Divalidasi sebagai alamat email; tidak disimpan pada event.
            phone:
              type: string
              nullable: true
              maxLength: 32
              description: Divalidasi; tidak disimpan pada event.
            country:
              type: string
              nullable: true
              maxLength: 3
              description: Divalidasi; tidak disimpan pada event.
        business:
          type: object
          description: >-
            Bisnis yang memiliki event tersebut, jika berbeda dari subjek. Hanya
            `vendor_data` yang dibaca.
          additionalProperties: true
          properties:
            vendor_data:
              type: string
              maxLength: 255
              description: >-
                ID Anda untuk bisnis tersebut. Dapat difilter sebagai
                `business_vendor_data`.
              example: merchant-7
        session:
          type: object
          description: Konteks sesi Anda untuk peristiwa tersebut.
          properties:
            session_id:
              type: string
              nullable: true
              maxLength: 255
              description: >-
                Pengenal sesi Anda. Dapat difilter dan dikembalikan sebagai
                `session_id`.
            sequence:
              type: integer
              nullable: true
              description: >-
                Posisi event di dalam sesi. Dikembalikan sebagai
                `session_sequence`.
            page_url:
              type: string
              nullable: true
              maxLength: 2048
              description: Divalidasi; tidak disimpan pada event.
            referrer:
              type: string
              nullable: true
              maxLength: 2048
              description: Divalidasi; tidak disimpan pada event.
        device_context:
          type: object
          additionalProperties: true
          description: >-
            Konteks perangkat dan jaringan, disimpan sebagaimana dikirim dan
            dikembalikan oleh `GET /v3/events/{event_uuid}/`. Pada jalur server
            ini Didit tidak melihat koneksi pengguna akhir, sehingga IP yang
            diperkaya dan digunakan oleh aturan adalah
            `network_context.ip_address` sebagaimana Anda mengirimkannya.
          properties:
            fingerprint:
              type: string
              maxLength: 255
              description: >-
                Sidik jari perangkat. Dapat difilter sebagai
                `device_fingerprint`.
            persistent_device_id:
              type: string
              maxLength: 255
              description: Pengenal perangkat persisten Anda.
            bot_score:
              type: integer
              description: Skor bot dari deteksi Anda sendiri, sebagai bilangan bulat.
            network_context:
              type: object
              additionalProperties: true
              properties:
                ip_address:
                  type: string
                  maxLength: 64
                  description: >-
                    Alamat IP pengguna akhir. Alamat publik diperkaya satu kali
                    per alamat unik.
                  example: 203.0.113.42
        transaction_context:
          type: object
          description: >-
            Konteks uang. Nilai yang tidak kosong di sini juga memenuhi kunci
            payload yang diperlukan untuk tindakan.
          properties:
            amount:
              type: string
              nullable: true
              description: Jumlah sebagai string desimal (angka juga diterima).
              example: '1000.00'
            currency:
              type: string
              nullable: true
              maxLength: 10
              description: Kode mata uang.
            direction:
              type: string
              nullable: true
              maxLength: 16
              description: Arah pergerakan uang, misalnya `inbound` atau `outbound`.
            payment_reference_id:
              type: string
              nullable: true
              maxLength: 255
              description: >-
                Referensi pembayaran Anda. Dapat difilter sebagai
                `payment_reference_id`.
        payload:
          type: object
          additionalProperties: true
          description: >-
            Kolom domain kategori, maksimal 16384 byte setelah di-encode ke
            JSON. Beberapa tindakan memerlukan kunci (dalam `payload` atau
            `transaction_context`): `gameplay.p2p_settlement` membutuhkan
            `game_id`, `counterparty_vendor_data`, `stake_amount`,
            `net_result_amount`, `role`, dan salah satu dari `hand_id`,
            `round_id`, `match_id`; `gameplay.bet_placed` dan
            `gameplay.bet_settled` membutuhkan `game_id`;
            `payment.deposit_initiated`, `payment.deposit_completed`,
            `payment.withdrawal_requested`, dan `payment.withdrawal_completed`
            membutuhkan `payment_reference_id`, `amount`, `currency`,
            `payment_method`, `status`; `payment.withdrawal_address_changed`
            membutuhkan `withdrawal_address_hash`; `dispute.chargeback_opened`,
            `dispute.chargeback_won`, dan `dispute.chargeback_lost` membutuhkan
            `payment_reference_id` dan salah satu dari `dispute_id`,
            `chargeback_id`; `session.bot_signal_observed` membutuhkan
            `telemetry_schema_version` dan salah satu dari `bot_score`,
            `actions_per_minute`, `timing_variance_ms`, `pointer_entropy`,
            `keystroke_entropy`, `reaction_time_ms_p50`;
            `responsible_gambling.self_exclusion_match` membutuhkan
            `registry_source`, `exclusion_status`, `identity_match_ref`. Setiap
            tindakan `security` yang berakhiran `_changed` membutuhkan
            `changed_field`, ditambah `previous_reference_hash` atau
            `new_reference_hash` ketika kolom tersebut berupa `password`,
            `mfa_method`, `mfa`, `email`, `phone`, `withdrawal_address`,
            `payout_method`, atau `api_key`. Kirimkan hash dan referensi, jangan
            pernah nomor kartu, alamat penarikan lengkap, hash kata sandi, atau
            rahasia MFA.
        custom_values:
          type: object
          description: >-
            Hingga 100 kunci milik Anda sendiri, dapat diakses dari aturan
            sebagai `custom_values.<key>`. Nilai harus berupa skalar (string,
            number, boolean, atau null); objek bersarang dan larik akan ditolak.
          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: >-
        Hasil pemrosesan satu event. Struktur yang sama dikembalikan untuk event
        baru dan untuk pemutaran ulang yang idempoten.
      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: Pengidentifikasi Didit untuk event yang disimpan.
        event_id:
          type: string
          description: '`event_id` Anda.'
        status:
          type: string
          enum:
            - ACCEPTED
            - APPROVED
            - IN_REVIEW
            - DECLINED
          description: >-
            Status setelah aturan real-time dijalankan. Lihat
            `MonitoringEvent.status`.
        score:
          type: integer
          description: Skor setelah aturan real-time dijalankan.
        rules_evaluated_count:
          type: integer
          minimum: 0
          description: >-
            Jumlah aturan event yang dievaluasi dalam permintaan. 0 dalam
            aplikasi sandbox, tempat tidak ada aturan yang berjalan.
        rules_matched_count:
          type: integer
          minimum: 0
          description: Jumlah aturan yang cocok, termasuk aturan mode `TEST`.
        correlation_pending:
          type: boolean
          description: >-
            `true` jika aturan asinkron masih harus dijalankan. Baca `GET
            /v3/events/{event_uuid}/` beberapa menit kemudian untuk `status` dan
            `score` akhir.
        retention_class:
          type: string
          enum:
            - low_value
            - standard
            - risk_relevant
            - monetary_or_compliance
          description: Kelas retensi, setelah promosi apa pun oleh aturan yang cocok.
        expires_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Waktu ketika peristiwa kedaluwarsa berdasarkan kelas retensinya dan
            dihapus. Null untuk peristiwa `monetary_or_compliance` (pembayaran
            dan sengketa).
        idempotent_replay:
          type: boolean
          description: >-
            `true` jika event dengan `event_id` ini dan konten yang sama telah
            disimpan sebelumnya; nilainya adalah nilai dari event yang disimpan
            dan tidak ada aturan yang dijalankan ulang.
        rule_matches:
          type: array
          description: Aturan yang cocok dengan event.
          items:
            type: object
            required:
              - rule_id
              - library_key
              - mode
              - is_async
            properties:
              rule_id:
                type: string
                format: uuid
                description: UUID aturan.
              library_key:
                type: string
                nullable: true
                description: >-
                  Kunci pustaka saat aturan dipasang dari pustaka aturan, jika
                  tidak maka null.
              mode:
                type: string
                enum:
                  - ACTIVE
                  - TEST
                description: >-
                  Aturan `TEST` mencatat kecocokan tetapi tidak menerapkan
                  tindakan apa pun.
              is_async:
                type: boolean
                description: '`true` saat kecocokan berasal dari proses asinkron.'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Kunci API aplikasi Anda, dari Developers -> API keys di Business
        Console. Kunci utama memiliki akses penuh. Kunci bernama dapat diberi
        cakupan: none, read, atau write per sumber daya, dibatasi pada beberapa
        alur kerja atau pada sesi yang disetujui, pada daftar alamat IP, dan
        pada tanggal kedaluwarsa. 401 berarti kuncinya salah, dicabut, atau
        kedaluwarsa; 403 berarti tidak ada kunci yang dikirimkan, kunci tidak
        memiliki akses ke sumber daya atau tindakan ini, atau permintaan datang
        dari alamat di luar daftar IP-nya; 404 pada rute sesi berarti sesi
        berada di luar alur kerja atau status kunci tersebut. Kunci tanpa akses
        media menerima URL gambar, video, dan PDF sebagai null, dan kunci tanpa
        izin tulis sesi menerima tautan sesi dan token sebagai null. Lihat
        https://docs.didit.me/console/api-keys.

````

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