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

# 이벤트 수집 API - 비금전 이벤트 모니터링

> Didit으로 로그인, 게임 플레이, 보너스, 결제, 분쟁, 계정 보안 등 비금전 활동을 거래를 점수화하는 동일한 엔진에 전송하세요.

거래는 돈입니다. 이벤트는 플랫폼이 알고 있는 그 밖의 모든 것입니다. 출금 직전의 로그인, 두 계정 사이에서 칩을 옮긴 핸드, 두 번 수령된 보너스, 일주일 뒤에 들어온 차지백 등이 여기에 해당합니다.

이벤트는 모든 카테고리에서 하나의 엔벨로프를 사용하고, 설계상 멱등성을 가지며, 귀사의 [거래](https://docs.didit.me/ko/transaction-monitoring/transactions.md)를 점수화하는 [동일한 규칙 엔진](https://docs.didit.me/ko/transaction-monitoring/event-rules.md)에 의해 평가됩니다.

> [!NOTE]
>
> 이벤트 수집은 **옵트인**입니다. **Transactions → Settings → Event monitoring**에서 켜야 합니다.
> 켜기 전까지는 아무것도 바뀌지 않습니다. 기존 거래 규칙은 계속해서 거래에만 적용되며, 규칙은 이벤트를 명시적으로 포함하지 않는 한 거래에만 적용되므로 실수로 이벤트에 적용되는 규칙이 만들어지는 일은 없습니다.
>
> 이 기능을 켜기 전까지 모든 쓰기 경로(`POST /v3/events/`, `POST /v3/events/batch/`, `POST /v3/events/sdk-token/`, 그리고 `/v1/events/` 기기 경로)는 `{"code": "event_monitoring_disabled"}`와 함께 `403`을 반환하며, 아무것도 저장, 보강 또는 평가되지 않습니다. 조회에는 영향이 없습니다.

## 엔드포인트

| 엔드포인트 | 인증 | 용도 |
| - | - | - |
| `POST /v3/events/` | API 키 | 백엔드에서 이벤트 하나 전송 |
| `POST /v3/events/batch/` | API 키 | 한 요청에 최대 500개 이벤트 전송 |
| `POST /v3/events/sdk-token/` | API 키 | 범위가 제한된 기기 자격 증명 발급 |
| `POST /v1/events/` | `X-Monitoring-Token` | 기기 SDK에서 이벤트 하나 전송 |
| `POST /v1/events/batch/` | `X-Monitoring-Token` | 플러시된 SDK 버퍼의 이벤트 묶음 전송 |
| `GET /v3/events/` | API 키 | 이벤트 목록 조회 및 필터링 |
| `GET /v3/events/{event_uuid}/` | API 키 | 규칙 근거를 포함한 이벤트 하나 조회 |
| `GET /v3/events/subjects/{vendor_data}/` | API 키 | 한 대상의 타임라인 조회 (아래 `entity_type` 참조) |
| `GET /v3/events/enrichment-metrics/` | API 키 | IP 보강 캐시 상태 |

`/v3/` 경로는 서버 경로이며, 거래 API의 나머지 부분과 동일한 `x-api-key` 인증을 사용합니다. `/v1/events/` 경로는 기기 경로이며, 자세한 내용은 [SDK 이벤트 전송](https://docs.didit.me/ko/transaction-monitoring/sdk-event-submission.md)을 참조하세요.

## 엔벨로프

```bash theme={null}
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-08-31-000001",
    "event_category": "auth",
    "action_type": "login",
    "occurred_at": "2026-08-31T20:40:31.123Z",
    "time_zone": "UTC",
    "subject": {
      "entity_type": "individual",
      "vendor_data": "user_391"
    },
    "session": { "session_id": "web-session-abc", "sequence": 142 },
    "device_context": {
      "fingerprint": "didit-fp-v2:a8c1",
      "network_context": { "ip_address": "203.0.113.42" }
    },
    "payload": { "method": "password" }
  }'
```

```json theme={null}
{
  "event_uuid": "0f2b...",
  "event_id": "login-2026-08-31-000001",
  "status": "ACCEPTED",
  "score": 0,
  "rules_evaluated_count": 6,
  "rules_matched_count": 0,
  "correlation_pending": false,
  "retention_class": "standard",
  "expires_at": "2026-09-30T20:40:31.123Z",
  "idempotent_replay": false,
  "rule_matches": []
}
```

| 필드 | 필수 | 비고 |
| - | - | - |
| `event_id` | 예 | 귀사의 고유 식별자이며, 애플리케이션 내에서 고유해야 합니다. 멱등성 키입니다. |
| `event_category` | 예 | 아래 열 가지 카테고리 중 하나입니다. |
| `action_type` | 예 | 자유 형식 문자열이며, 최대 128자입니다. |
| `occurred_at` | 예 | 귀사 시스템에서 이벤트가 발생한 시각입니다. 과거로 최대 7일, 미래로 최대 5분까지 허용됩니다. |
| `subject.vendor_data` | 예 | 귀사의 사용자 ID입니다. 거래가 매핑되는 것과 동일한 사용자로 매핑됩니다. |
| `subject.entity_type` | 아니요 | `individual`(기본값) 또는 `company`입니다. |
| `business.vendor_data` | 아니요 | 이벤트가 속한 기업입니다. |
| `session` | 아니요 | `session_id`, `sequence`, `page_url`, `referrer`입니다. |
| `device_context` | 아니요 | `fingerprint`, `persistent_device_id`, `bot_score`, `network_context.ip_address`입니다. |
| `transaction_context` | 아니요 | `amount`, `currency`, `direction`, `payment_reference_id`입니다. |
| `payload` | 아니요 | 카테고리의 도메인 필드입니다. 최대 16KB입니다. |
| `custom_values` | 아니요 | 최대 100개의 스칼라 키를 사용할 수 있으며, 규칙에서 `custom_values.<key>`로 참조할 수 있습니다. |

## 카테고리

최상위 카테고리는 10개이며, 각 카테고리에는 타입이 지정된 유효성 검사와 [관리형 규칙 필드](https://docs.didit.me/ko/transaction-monitoring/event-rules.md#이벤트-필드)가 있습니다.

| 카테고리 | 일반적인 작업 |
| - | - |
| `auth` | `signup`, `login`, `login_failed`, `logout`, `password_forgot`, `password_reset`, `mfa_reset`, `mfa_challenge` |
| `session` | `session_started`, `session_ended`, `page_view`, `sdk_loaded`, `device_seen`, `bot_signal_observed`, `sdk_heartbeat` |
| `gameplay` | `round_started`, `round_completed`, `bet_placed`, `bet_settled`, `cashout`, `limit_change`, `p2p_settlement` |
| `bonus` | `bonus_claimed`, `bonus_wagered`, `bonus_released`, `promotion_viewed` |
| `affiliate` | `affiliate_attributed`, `referral_clicked`, `campaign_joined`, `commission_event` |
| `payment` | `deposit_initiated`, `deposit_completed`, `withdrawal_requested`, `withdrawal_completed`, `withdrawal_address_changed`, `payment_instrument_seen` |
| `dispute` | `chargeback_opened`, `chargeback_won`, `chargeback_lost`, `refund_issued`, `payment_dispute_updated` |
| `security` | `login_attempt`, `login_succeeded`, `login_failed`, `password_changed`, `mfa_changed`, `credential_reset`, `country_changed`, `device_changed`, `account_locked` |
| `responsible_gambling` | `self_exclusion_checked`, `self_exclusion_match`, `re_registration_attempt`, `limit_breach_attempt`, `registry_status_changed` |
| `custom` | 직접 정의한 모든 작업 |

`auth`는 제품 전반을 아우르는 넓은 카테고리입니다. `security`는 계정 탈취 규칙이 읽는 순서가 정해진 수명 주기를 가진 위험 등급 하위 집합입니다.

### 필수 페이로드 키

일부 작업은 특정 키 없이는 상관 분석할 수 없습니다. 따라서 검증 단계에서 아무도 연결할 수 없는 증거를 저장하는 대신 해당 이벤트를 거부합니다.

| 작업 | 필수 항목 |
| - | - |
| `gameplay.p2p_settlement` | `game_id`, `counterparty_vendor_data`, `stake_amount`, `net_result_amount`, `role`, 그리고 `hand_id` / `round_id` / `match_id` 중 하나 |
| `gameplay.bet_placed`, `gameplay.bet_settled` | `game_id` |
| `payment.deposit_*`, `payment.withdrawal_completed`, `payment.withdrawal_requested`, `payment.deposit_initiated` | `payment_reference_id`, `amount`, `currency`, `payment_method`, `status` |
| `payment.withdrawal_address_changed` | `withdrawal_address_hash` |
| `dispute.chargeback_*` | `payment_reference_id`, 그리고 `dispute_id` / `chargeback_id` 중 하나 |
| `security.*_changed` | `changed_field`. 계정 또는 지급 통제 변경에는 `previous_reference_hash` 또는 `new_reference_hash`도 필요합니다. |
| `session.bot_signal_observed` | `telemetry_schema_version`, 그리고 `bot_score` 또는 최소 하나의 텔레메트리 지표 |
| `responsible_gambling.self_exclusion_match` | `registry_source`, `exclusion_status`, `identity_match_ref` |

> [!WARNING]
>
> **참조값과 해시**만 보내고, 원본 비밀 정보는 절대 보내지 마십시오. 결제 수단, 출금 대상, 계정 통제 변경은 전송한 해시 참조값으로 저장됩니다. 카드 번호, 전체 출금 주소, 비밀번호 해시, MFA 비밀 값은 절대 보내지 마십시오.

### 예시: P2P 정산

```json theme={null}
{
  "event_id": "p2p-hand-8842-user-391",
  "event_category": "gameplay",
  "action_type": "p2p_settlement",
  "occurred_at": "2026-08-31T12:34:17.392Z",
  "subject": { "vendor_data": "user_391" },
  "payload": {
    "game_id": "poker_holdem",
    "table_id": "table_17",
    "hand_id": "hand_8842",
    "role": "winner",
    "counterparty_vendor_data": "user_812",
    "stake_amount": "250.00",
    "net_result_amount": "240.50",
    "effective_margin": "0.038",
    "operator_ledger_ref": "ledger_998123"
  }
}
```

### 예시: 차지백

```json theme={null}
{
  "event_id": "chargeback-cb_921-opened",
  "event_category": "dispute",
  "action_type": "chargeback_opened",
  "occurred_at": "2026-08-31T09:22:05.000Z",
  "subject": { "vendor_data": "user_391" },
  "transaction_context": {
    "amount": "1000.00",
    "currency": "EUR",
    "payment_reference_id": "dep_735"
  },
  "payload": {
    "dispute_id": "disp_498",
    "chargeback_id": "cb_921",
    "reason_code": "fraudulent",
    "liability_shift": false
  }
}
```

분쟁 수명 주기는 추가만 가능합니다. 정정은 첫 번째 이벤트를 수정하는 것이 아니라, 새로운 `dispute` 이벤트로 기록합니다.

## 멱등성

`event_id`는 애플리케이션마다 고유하며, 멱등성 계약 그 자체입니다.

* **같은 `event_id`, 같은 내용**이면 `"idempotent_replay": true`와 함께 `200`을 반환하며, 처음 저장된 이벤트를 돌려줍니다. 원하는 만큼 다시 시도할 수 있습니다.
* **같은 `event_id`, 다른 내용**이면 `409`를 반환합니다. ID를 실수로 재사용한 경우입니다.

## 배치

`POST /v3/events/batch/`는 최대 **500개의 이벤트**를 받습니다. 배치는 설계상 부분 성공을 허용합니다. 형식이 잘못된 페이지 조회 하나 때문에 바로 옆의 차지백 이벤트까지 실패해서는 안 됩니다.

```json theme={null}
{
  "accepted_count": 2,
  "replayed_count": 0,
  "rejected_count": 1,
  "results": [
    { "index": 0, "outcome": "rejected", "errors": { "occurred_at": ["This field is required."] } },
    { "index": 1, "outcome": "accepted", "event_uuid": "…", "status": "ACCEPTED" },
    { "index": 2, "outcome": "accepted", "event_uuid": "…", "status": "IN_REVIEW" }
  ]
}
```

거부된 항목이 하나라도 있으면 응답은 `207 Multi-Status`이고, 모든 이벤트가 저장되면 `201 Created`입니다.

## 상태

| 상태 | 의미 |
| - | - |
| `ACCEPTED` | 저장됨. 어떤 규칙도 상태를 바꾸지 않았습니다. 대부분의 이벤트에 대한 일반적인 응답입니다. |
| `APPROVED` | 규칙이 실행되었고 점수가 검토 임계값 아래에 머물렀습니다. |
| `IN_REVIEW` | 규칙이 점수를 검토 임계값을 초과하도록 올렸거나 상태를 직접 설정했습니다. |
| `DECLINED` | 규칙에 의해 거부되었습니다. |

`correlation_pending: true`는 여러 주체를 대상으로 하는 규칙이 아직 실행되어야 함을 뜻합니다. 상관 분석은 몇 분 안에 완료되며, 이벤트의 상태와 점수는 그 자리에서 갱신됩니다. [비동기 규칙](https://docs.didit.me/ko/transaction-monitoring/event-rules.md#실시간-및-비동기-규칙)을 참고하십시오.

## 보존

이벤트는 거래보다 훨씬 많으므로, 각 이벤트는 도착할 때 보존 클래스에 분류됩니다.

| 클래스 | 기본 핫 보존 기간 | 해당 이벤트 |
| - | - | - |
| `low_value` | 14일 | 페이지 조회, 하트비트, 기기 확인 핑, 봇 텔레메트리, 프로모션 조회 |
| `standard` | 30일 | 인증, 세션, 게임플레이, 보너스, 제휴, 사용자 정의 |
| `risk_relevant` | 90일 | 보안 및 책임 있는 도박 이벤트, 그리고 **규칙에 일치한 모든 이벤트** |
| `monetary_or_compliance` | 거래 보존 기간 | 결제 및 분쟁 이벤트 |

이 표에서 다음 두 가지 규칙이 도출됩니다.

* 규칙에 일치하는 이벤트는 증거이므로 자동으로 `risk_relevant`로 승격됩니다.
* 결제 및 분쟁 이벤트는 거래 보존 기간을 유지합니다. 이벤트 일정에 따라 만료되지 않으며, 클래스별 재정의로 기간을 단축할 수 없습니다.

만료 가능한 세 클래스는 애플리케이션별로 **Transactions → Settings → Event monitoring**에서 재정의할 수 있습니다(각각 1\~730일).

## IP 보강

이벤트에도 거래와 동일한 [IP 보강 정보](https://docs.didit.me/ko/transaction-monitoring/ip-enrichment.md)가 포함됩니다. 국가, ASN, VPN/프록시 및 데이터 센터 플래그가 여기에 해당합니다. 보강 정보는 이벤트마다 조회되지 않고 **고유 IP 주소마다** 조회됩니다. 한 주소에서 200번의 페이지 조회가 발생하는 세션이라도 해당 주소는 한 번만 조회됩니다.

낮은 가치의 텔레메트리는 한 걸음 더 나아갑니다. 다른 이벤트가 이미 해당 주소를 조회한 경우에만 보강 정보를 읽습니다. 자체적으로 조회를 트리거하는 일은 결코 없습니다.

`GET /v3/events/enrichment-metrics/`는 그 결과를 보고하며, 콘솔은 이벤트 목록 위에 같은 수치를 다음과 같이 표시합니다:

```json theme={null}
{
  "events_ingested": 128450,
  "enrichment_lookups": 41230,
  "enrichment_cache_hits": 40118,
  "enrichment_provider_calls": 1112,
  "enrichment_skipped_low_value": 74320,
  "unique_ips_seen": 1112,
  "cache_hit_rate": 0.973,
  "unique_ip_ratio": 0.0087,
  "provider_calls_per_1k_events": 8.65,
  "period_days": 30
}
```

## 이벤트 조회

```bash theme={null}
curl "https://verification.didit.me/v3/events/?event_category=payment&event_category=dispute&matched_only=true" \
  -H "x-api-key: YOUR_API_KEY"
```

필터: `event_category`, `action_type`, `status`, `retention_class`, `subject_vendor_data`, `business_vendor_data`, `session_id`, `device_fingerprint`, `ip_address`, `game_id`, `round_id`, `affiliate_code`, `payment_reference_id`, `counterparty_vendor_data`, `matched_only`, `occurred_from`, `occurred_to`, `search`. 여러 값을 지정하는 필터는 매개변수를 반복해서 사용합니다(`?status=A&status=B`).

### 한 주체의 타임라인

```bash theme={null}
curl "https://verification.didit.me/v3/events/subjects/acct_9931/?entity_type=company" \
  -H "x-api-key: YOUR_API_KEY"
```

`vendor_data`는 **엔티티 유형 안에서만** 고유합니다. 같은 ID가 사용자와 기업을 가리킬 수 있으며, Didit은 이를 서로 다른 두 주체로 처리합니다. `entity_type`은 조회하려는 대상을 지정합니다. `individual`(기본값) 또는 `company`를 사용할 수 있습니다. 기업 ID에 이 값을 생략하면 두 타임라인이 모두 반환되지 않고 개인의 타임라인이 반환됩니다. 동일한 목록 필터를 사용할 수 있습니다.

`GET /v3/events/{event_uuid}/`는 페이로드, 기기 컨텍스트, IP 정보 보강, 주체의 캐시된 위험 신호, 그리고 모든 규칙 일치 항목과 근거를 추가로 반환합니다. 각 일치 필드가 서버에서 도출되었는지, SDK에서 도출되었는지, 고객이 제공했는지도 함께 표시됩니다.

`DELETE /v3/events/{event_uuid}/delete/`는 이벤트 하나를 삭제합니다. 삭제된 이벤트는 모든 조회에서 더 이상 반환되지 않으며, 삭제는 되돌릴 수 없습니다.

## 다음

> [card] [이벤트 규칙](https://docs.didit.me/ko/transaction-monitoring/event-rules.md)
>
> 이벤트 데이터에 대한 속도, 비율, 순서 및 상관관계 규칙입니다.

> [card] [SDK 이벤트 제출](https://docs.didit.me/ko/transaction-monitoring/sdk-event-submission.md)
>
> 범위가 제한된 자격 증명을 사용하여 기기에서 직접 이벤트를 캡처합니다.


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