> ## 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에서 한 번의 요청으로 모니터링 이벤트를 최대 500개까지 제출하고 항목별 결과를 받아보세요. 잘못된 이벤트 하나가 나머지 배치를 막지 않습니다.



배치 API에서 모니터링 이벤트 생성 프롬프트
        프롬프트를 클립보드에 복사



      
      

\<pre>

\`Send up to 500 monitoring events to Didit in one request from my backend, and handle the per-item outcomes.

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

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

Goal:
\- Flush a queue of events (logins, gameplay rounds, payment steps, chargebacks) in as few requests as possible, without one bad event blocking the others.

Request body (application/json):
\{
"events": [ { ...one event, same envelope as POST /v3/events/... }, ... ]   // 1 to 500 events
}
A bare JSON array of events is also accepted.

Behavior:
\- Each item is validated, stored and evaluated on its own, exactly like POST /v3/events/. A rejected item never rolls back the others.
\- HTTP 201 when no item was rejected, 207 when at least one was. Treat both as success and read results[].
\- results[] has one entry per item in request order, with index pointing into my events array and outcome accepted, replayed or rejected.
\- accepted and replayed items carry the same fields as the single-event response (event_uuid, status, score, rule_matches, correlation_pending, retention_class, expires_at, idempotent_replay).
\- rejected items carry errors keyed by field, in the same shape as the 400 of POST /v3/events/. A reused event_id with different content is reported as a string under errors.event_id. Send event_id in snake_case so a rejected item's results[].event_id is filled.
\- Retry only the rejected items after fixing them. Resending an accepted item is safe: it comes back as replayed.
\- occurred_at must still be within 7 days in the past and 5 minutes in the future for every item.

Example call:
curl -X POST "https://verification.didit.me/v3/events/batch/" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"events":[{"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"}}]}'

What to read from the response:
\- accepted_count, replayed_count, rejected_count.
\- results[].index and results[].outcome.
\- results[].errors for rejected items.
\- results[].event_uuid and results[].status for stored items.

Failure modes:
\- 400 - events missing, not an array, empty, or longer than 500 items ({ "events": "<message>" }). Nothing is stored; split the batch.
\- 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.
\- 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 (event ingestion is not switched on; nothing is stored).

Side effects: stores every valid item, may create subjects, and applies the actions of matched active rules.

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

\</pre>



      
      

붙여넣을 곳

이벤트 수집 가이드의 [배치](https://docs.didit.me/ko/transaction-monitoring/events.md#배치)를 참고하세요. 기기 채널에는 SDK 플러시에 대해서도 동일한 항목별 결과가 있습니다. [SDK 이벤트 제출](https://docs.didit.me/ko/transaction-monitoring/sdk-event-submission.md#배치-처리)을 참고하세요.


## OpenAPI

````yaml ko/openapi-25.json POST /v3/events/batch/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: 신분증 인증 API입니다. x-api-key 헤더로 인증합니다.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/events/batch/:
    post:
      tags:
        - Monitoring Events
      summary: 모니터링 이벤트 일괄 생성
      description: >-
        한 번의 요청으로 1개에서 500개의 이벤트를 전송하며, 각 이벤트는 `POST /v3/events/`와 동일한 envelope
        구조를 갖습니다. 각 항목은 개별적으로 유효성 검사, 저장 및 평가되어 자체 결과(`accepted`, `replayed`,
        `rejected`)를 받으므로, 잘못된 형식의 이벤트가 하나 있더라도 다른 이벤트가 롤백되지 않습니다. 거부된 항목이 없으면
        `201` 응답이, 하나 이상의 항목이 거부되면 `207` 응답이 반환되며, 두 경우 모두 요청이 처리되었음을 의미합니다.
        `{"events": [...]}` 형식으로 전송하며, 이벤트의 순수 JSON 배열도 허용됩니다. 애플리케이션에 대해 이벤트
        수집이 활성화되어 있어야 하며, 그렇지 않으면 전체 요청이 `code: event_monitoring_disabled`와 함께
        `403`을 반환하고 아무것도 저장되지 않습니다. 범위가 지정된 API 키에는 `transactions: write` 권한이
        필요합니다. [배치](https://docs.didit.me/ko/transaction-monitoring/events#배치)를
        참조하세요.
      operationId: create_monitoring_events_batch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - events
              properties:
                events:
                  type: array
                  minItems: 1
                  maxItems: 500
                  description: >-
                    1~500개의 이벤트입니다. 각 항목은 `occurred_at`의 과거 7일 및 미래 5분 기간을 포함하여
                    `MonitoringEventCreateRequest`를 따릅니다.
                  items:
                    $ref: '#/components/schemas/MonitoringEventCreateRequest'
            example:
              events:
                - 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
                - 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
                    payment_reference_id: dep_736
                  payload:
                    payment_method: card
                    status: completed
      responses:
        '201':
          description: 거부된 항목이 없습니다. 모든 항목이 `accepted` 또는 `replayed` 상태입니다.
          content:
            application/json:
              schema:
                type: object
                required:
                  - accepted_count
                  - replayed_count
                  - rejected_count
                  - results
                properties:
                  accepted_count:
                    type: integer
                    minimum: 0
                    description: 저장 및 평가된 항목 수입니다.
                  replayed_count:
                    type: integer
                    minimum: 0
                    description: 동일한 내용으로 이미 저장된 항목 수입니다.
                  rejected_count:
                    type: integer
                    minimum: 0
                    description: 저장되지 않은 항목 수입니다.
                  results:
                    type: array
                    description: 요청된 순서대로 각 항목당 1개 항목입니다.
                    items:
                      type: object
                      description: >-
                        단일 항목의 결과입니다. 승인 및 재생된 항목에는
                        `MonitoringEventIngestResult`의 모든 필드도 포함되며, 거부된 항목에는 대신
                        `event_id` 및 `errors`가 포함됩니다.
                      required:
                        - index
                        - outcome
                      properties:
                        index:
                          type: integer
                          minimum: 0
                          description: '`events` 배열 내 항목의 위치입니다.'
                        outcome:
                          type: string
                          enum:
                            - accepted
                            - replayed
                            - rejected
                          description: >-
                            `accepted`: 저장 및 평가되었습니다. `replayed`: 동일한 내용으로 이미
                            저장되어 있습니다. `rejected`: 저장되지 않았습니다. `errors`를 확인하세요.
                        event_id:
                          type: string
                          nullable: true
                          description: >-
                            귀하의 `event_id`입니다. 검증에서 거부된 항목의 경우 항목의 snake_case
                            `event_id` 키에서 읽어오므로, 항목에서 이를 생략했거나 `eventId` 별칭을 보낸
                            경우 null이 됩니다.
                        errors:
                          type: object
                          additionalProperties: true
                          description: >-
                            거부된 항목만 해당합니다. `POST /v3/events/`의 `400`과 동일한 형태로
                            필드별로 키가 지정된 유효성 검사 오류입니다. 내용이 다른 상태로 재사용된
                            `event_id`는 `errors.event_id` 아래에 문자열로 보고됩니다.
                        event_uuid:
                          type: string
                          format: uuid
                          description: 수락 및 재생된 항목만 해당합니다.
                        status:
                          type: string
                          enum:
                            - ACCEPTED
                            - APPROVED
                            - IN_REVIEW
                            - DECLINED
                          description: 수락 및 재생된 항목만 해당합니다.
                        score:
                          type: integer
                          description: 수락 및 재생된 항목만 해당합니다.
                        rules_evaluated_count:
                          type: integer
                          description: 수락 및 재생된 항목만 해당합니다.
                        rules_matched_count:
                          type: integer
                          description: 수락 및 재생된 항목만 해당합니다.
                        correlation_pending:
                          type: boolean
                          description: 수락 및 재생된 항목만 해당합니다.
                        retention_class:
                          type: string
                          enum:
                            - low_value
                            - standard
                            - risk_relevant
                            - monetary_or_compliance
                          description: 수락 및 재생된 항목만 해당합니다.
                        expires_at:
                          type: string
                          format: date-time
                          nullable: true
                          description: 수락 및 재생된 항목만 해당합니다.
                        idempotent_replay:
                          type: boolean
                          description: 수락 및 재생된 항목만 해당합니다.
                        rule_matches:
                          type: array
                          description: 수락 및 재생된 항목만 해당합니다.
                          items:
                            type: object
                            required:
                              - rule_id
                              - library_key
                              - mode
                              - is_async
                            properties:
                              rule_id:
                                type: string
                                format: uuid
                                description: 규칙의 UUID입니다.
                              library_key:
                                type: string
                                nullable: true
                                description: >-
                                  규칙 라이브러리에서 설치된 규칙인 경우의 라이브러리 키이며, 그렇지 않은 경우
                                  null입니다.
                              mode:
                                type: string
                                enum:
                                  - ACTIVE
                                  - TEST
                                description: '`TEST` 규칙은 일치 항목을 기록하지만 작업을 적용하지는 않습니다.'
                              is_async:
                                type: boolean
                                description: 일치 항목이 비동기 패스에서 도출된 경우 `true`입니다.
              examples:
                All landed:
                  value:
                    accepted_count: 1
                    replayed_count: 1
                    rejected_count: 0
                    results:
                      - index: 0
                        outcome: accepted
                        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: []
                      - index: 1
                        outcome: replayed
                        event_uuid: 11111111-2222-3333-4444-555555555555
                        event_id: deposit-2026-10-17-000002
                        status: ACCEPTED
                        score: 0
                        rules_evaluated_count: 6
                        rules_matched_count: 0
                        correlation_pending: false
                        retention_class: monetary_or_compliance
                        expires_at: null
                        idempotent_replay: true
                        rule_matches: []
        '207':
          description: >-
            최소 하나의 항목이 거부되었습니다. 다른 항목들은 저장되었으므로 거부된 항목만 수정하여 다시 전송하십시오(이미 수락된
            항목을 다시 전송해도 안전하며, `replayed` 상태로 반환됩니다).
          content:
            application/json:
              schema:
                type: object
                required:
                  - accepted_count
                  - replayed_count
                  - rejected_count
                  - results
                properties:
                  accepted_count:
                    type: integer
                    minimum: 0
                    description: 저장 및 평가된 항목 수입니다.
                  replayed_count:
                    type: integer
                    minimum: 0
                    description: 동일한 내용으로 이미 저장된 항목 수입니다.
                  rejected_count:
                    type: integer
                    minimum: 0
                    description: 저장되지 않은 항목 수입니다.
                  results:
                    type: array
                    description: 요청된 순서대로 각 항목당 1개 항목입니다.
                    items:
                      type: object
                      description: >-
                        단일 항목의 결과입니다. 승인 및 재생된 항목에는
                        `MonitoringEventIngestResult`의 모든 필드도 포함되며, 거부된 항목에는 대신
                        `event_id` 및 `errors`가 포함됩니다.
                      required:
                        - index
                        - outcome
                      properties:
                        index:
                          type: integer
                          minimum: 0
                          description: '`events` 배열 내 항목의 위치입니다.'
                        outcome:
                          type: string
                          enum:
                            - accepted
                            - replayed
                            - rejected
                          description: >-
                            `accepted`: 저장 및 평가되었습니다. `replayed`: 동일한 내용으로 이미
                            저장되어 있습니다. `rejected`: 저장되지 않았습니다. `errors`를 확인하세요.
                        event_id:
                          type: string
                          nullable: true
                          description: >-
                            귀하의 `event_id`입니다. 검증에서 거부된 항목의 경우 항목의 snake_case
                            `event_id` 키에서 읽어오므로, 항목에서 이를 생략했거나 `eventId` 별칭을 보낸
                            경우 null이 됩니다.
                        errors:
                          type: object
                          additionalProperties: true
                          description: >-
                            거부된 항목만 해당합니다. `POST /v3/events/`의 `400`과 동일한 형태로
                            필드별로 키가 지정된 유효성 검사 오류입니다. 내용이 다른 상태로 재사용된
                            `event_id`는 `errors.event_id` 아래에 문자열로 보고됩니다.
                        event_uuid:
                          type: string
                          format: uuid
                          description: 수락 및 재생된 항목만 해당합니다.
                        status:
                          type: string
                          enum:
                            - ACCEPTED
                            - APPROVED
                            - IN_REVIEW
                            - DECLINED
                          description: 수락 및 재생된 항목만 해당합니다.
                        score:
                          type: integer
                          description: 수락 및 재생된 항목만 해당합니다.
                        rules_evaluated_count:
                          type: integer
                          description: 수락 및 재생된 항목만 해당합니다.
                        rules_matched_count:
                          type: integer
                          description: 수락 및 재생된 항목만 해당합니다.
                        correlation_pending:
                          type: boolean
                          description: 수락 및 재생된 항목만 해당합니다.
                        retention_class:
                          type: string
                          enum:
                            - low_value
                            - standard
                            - risk_relevant
                            - monetary_or_compliance
                          description: 수락 및 재생된 항목만 해당합니다.
                        expires_at:
                          type: string
                          format: date-time
                          nullable: true
                          description: 수락 및 재생된 항목만 해당합니다.
                        idempotent_replay:
                          type: boolean
                          description: 수락 및 재생된 항목만 해당합니다.
                        rule_matches:
                          type: array
                          description: 수락 및 재생된 항목만 해당합니다.
                          items:
                            type: object
                            required:
                              - rule_id
                              - library_key
                              - mode
                              - is_async
                            properties:
                              rule_id:
                                type: string
                                format: uuid
                                description: 규칙의 UUID입니다.
                              library_key:
                                type: string
                                nullable: true
                                description: >-
                                  규칙 라이브러리에서 설치된 규칙인 경우의 라이브러리 키이며, 그렇지 않은 경우
                                  null입니다.
                              mode:
                                type: string
                                enum:
                                  - ACTIVE
                                  - TEST
                                description: '`TEST` 규칙은 일치 항목을 기록하지만 작업을 적용하지는 않습니다.'
                              is_async:
                                type: boolean
                                description: 일치 항목이 비동기 패스에서 도출된 경우 `true`입니다.
              examples:
                Partial success:
                  value:
                    accepted_count: 1
                    replayed_count: 0
                    rejected_count: 2
                    results:
                      - index: 0
                        outcome: accepted
                        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: []
                      - index: 1
                        event_id: deposit-2026-10-17-000002
                        outcome: rejected
                        errors:
                          payload:
                            - >-
                              payment.deposit_completed requires:
                              payment_method, status.
                      - index: 2
                        event_id: login-2026-10-16-000777
                        outcome: rejected
                        errors:
                          event_id: >-
                            event_id 'login-2026-10-16-000777' already exists
                            with a different payload.
        '400':
          description: >-
            배치 자체가 올바르지 않습니다. `events`가 누락되었거나 배열이 아니거나 비어 있거나 500개를 초과하는 항목이
            포함되어 있습니다. 아무것도 저장되지 않았으므로 대용량 배치를 분할하십시오.
          content:
            application/json:
              examples:
                Not a list:
                  value:
                    events: Expected a list of events.
                Empty:
                  value:
                    events: At least one event is required.
                Too many:
                  value:
                    events: A batch accepts at most 500 events; received 612.
        '401':
          description: >-
            스코프가 지정된 API 키가 만료되었습니다. 만료된 키에 대해서만 `401`이 반환되며, 누락되었거나 유효하지 않은 키에는
            `403`이 반환됩니다.
          content:
            application/json:
              examples:
                Expired key:
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            `x-api-key`가 누락되었거나(잘못되었거나 취소되었거나 만료된 키에는 `401`이 반환됨),
            `transactions: write` 권한이 없는 범위 제한 키이거나, 특정 워크플로 또는 승인된 세션으로 제한된
            키이거나(이러한 키는 거래 모니터링 데이터에 절대 접근할 수 없음), 키의 IP 허용 목록 외부에서 발생한 요청입니다.
            애플리케이션의 이벤트 수집이 비활성화된 동안 `code: event_monitoring_disabled`와 함께 반환되기도
            합니다. 이 경우 아무것도 저장되지 않으며, 검사는 본문 검증 전에 실행됩니다.
          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.
        '429':
          description: >-
            속도 제한 초과: 거래 생성 및 이벤트 수집(`POST /v3/transactions/`, `POST
            /v3/events/`, `POST /v3/events/batch/`)은 다른 모든 쓰기 요청이 공유하는 300개와
            별도로, API 키당 분당 600개의 요청 한도를 공유합니다. `Retry-After`초 동안 대기한 후 재시도하세요.
          headers:
            Retry-After:
              description: 재시도가 다음 기간에 이루어지도록 올림 처리한 재시도 대기 시간(초).
              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/batch/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "events": [
                  {"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"}},
                  {"event_id": "deposit-2026-10-17-000002", "event_category": "payment", "action_type": "deposit_completed",
                   "occurred_at": "2026-10-17T09:16:40.000Z", "subject": {"vendor_data": "user-42"},
                   "transaction_context": {"amount": "100.00", "currency": "EUR", "payment_reference_id": "dep_736"},
                   "payload": {"payment_method": "card", "status": "completed"}}
                ]
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.monitoring_events.create_batch(
                events=[{
                    "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",
                    },
                }, {
                    "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",
                        "payment_reference_id": "dep_736",
                    },
                    "payload": {"payment_method": "card", "status": "completed"},
                }],
            )
            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.createBatch({
              events: [{
                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",
                },
              }, {
                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",
                  payment_reference_id: "dep_736",
                },
                payload: { payment_method: "card", status: "completed" },
              }],
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.CreateBatch(ctx, didit.MonitoringEventsCreateBatchParams{\n\tEvents: []didit.MonitoringEventCreateRequest{{\n\t\tEventID:       \"login-2026-10-17-000001\",\n\t\tEventCategory: \"auth\",\n\t\tActionType:    \"login\",\n\t\tOccurredAt:    time.Date(2026, 10, 17, 9, 15, 2, 0, time.UTC),\n\t\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\t\tVendorData: \"user-42\",\n\t\t},\n\t}, {\n\t\tEventID:       \"deposit-2026-10-17-000002\",\n\t\tEventCategory: \"payment\",\n\t\tActionType:    \"deposit_completed\",\n\t\tOccurredAt:    time.Date(2026, 10, 17, 9, 16, 40, 0, time.UTC),\n\t\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\t\tVendorData: \"user-42\",\n\t\t},\n\t\tTransactionContext: didit.Some(didit.MonitoringEventCreateRequestTransactionContext{\n\t\t\tAmount:             didit.String(\"100.00\"),\n\t\t\tCurrency:           didit.String(\"EUR\"),\n\t\t\tPaymentReferenceID: didit.String(\"dep_736\"),\n\t\t}),\n\t\tPayload: didit.Some(map[string]any{\"payment_method\": \"card\", \"status\": \"completed\"}),\n\t}},\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.List;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.MonitoringEventCreateRequest;

            import me.didit.types.MonitoringEventsCreateBatchParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.monitoringEvents().createBatch(MonitoringEventsCreateBatchParams.builder()
                    .events(List.of(
                            MonitoringEventCreateRequest.builder()
                                    .eventId("login-2026-10-17-000001")
                                    .eventCategory(MonitoringEventCreateRequest.EventCategory.of("auth"))
                                    .actionType("login")
                                    .occurredAt(OffsetDateTime.parse("2026-10-17T09:15:02.481Z"))
                                    .subject(MonitoringEventCreateRequest.Subject.builder()
                                            .vendorData("user-42")
                                            .build())
                                    .build(),
                            MonitoringEventCreateRequest.builder()
                                    .eventId("deposit-2026-10-17-000002")
                                    .eventCategory(MonitoringEventCreateRequest.EventCategory.of("payment"))
                                    .actionType("deposit_completed")
                                    .occurredAt(OffsetDateTime.parse("2026-10-17T09:16:40Z"))
                                    .subject(MonitoringEventCreateRequest.Subject.builder()
                                            .vendorData("user-42")
                                            .build())
                                    .transactionContext(MonitoringEventCreateRequest.TransactionContext.builder()
                                            .amount("100.00")
                                            .currency("EUR")
                                            .paymentReferenceId("dep_736")
                                            .build())
                                    .payload(Map.of("payment_method", "card", "status", "completed"))
                                    .build()))
                    .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->createBatch([
                'events' => [[
                    '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',
                    ],
                ], [
                    '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',
                        'payment_reference_id' => 'dep_736',
                    ],
                    'payload' => ['payment_method' => 'card', 'status' => 'completed'],
                ]],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.monitoring_events.create_batch(
              events: [{
                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",
                },
              }, {
                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",
                  payment_reference_id: "dep_736",
                },
                payload: { payment_method: "card", status: "completed" },
              }]
            )
            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.CreateBatchAsync(new
            MonitoringEventsCreateBatchParams

            {
                Events = new MonitoringEventCreateRequest[]
                {
                    new()
                    {
                        EventId = "login-2026-10-17-000001",
                        EventCategory = "auth",
                        ActionType = "login",
                        OccurredAt = DateTimeOffset.Parse("2026-10-17T09:15:02.481Z"),
                        Subject = new()
                        {
                            VendorData = "user-42",
                        },
                    },
                    new()
                    {
                        EventId = "deposit-2026-10-17-000002",
                        EventCategory = "payment",
                        ActionType = "deposit_completed",
                        OccurredAt = DateTimeOffset.Parse("2026-10-17T09:16:40Z"),
                        Subject = new()
                        {
                            VendorData = "user-42",
                        },
                        TransactionContext = new MonitoringEventCreateRequestTransactionContext
                        {
                            Amount = "100.00",
                            Currency = "EUR",
                            PaymentReferenceId = "dep_736",
                        },
                        Payload = new Dictionary<string, object> { ["payment_method"] = "card", ["status"] = "completed" },
                    },
                },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    MonitoringEventCreateRequest:
      type: object
      description: >-
        모든 카테고리에 동일하게 적용되는 이벤트 엔벨로프입니다. camelCase 별칭도 허용됩니다: `eventId`,
        `eventCategory`(또는 `category`), `actionType`, `occurredAt`,
        `timeZone`(또는 `zoneId`), `deviceContext`(또는 `device`),
        `transactionContext`, `customValues`(또는 `props`). `subject` 내부:
        `vendorData`, `entityType`, `fullName`. `session` 내부: `sessionId`,
        `pageUrl`. `transaction_context` 내부: `paymentReferenceId`.
      required:
        - event_id
        - event_category
        - action_type
        - occurred_at
        - subject
      properties:
        event_id:
          type: string
          maxLength: 128
          description: >-
            애플리케이션별로 고유한 이벤트 식별자입니다. 멱등성 키 역할을 합니다. 동일한 키로 동일한 `event_category`,
            `action_type`, `occurred_at`, `subject.vendor_data`, `payload`를 다시
            전송하면 재전송으로 처리되며, 다른 내용이 전송되면 충돌이 발생합니다.
          example: login-2026-10-17-000001
        event_category:
          type: string
          enum:
            - auth
            - session
            - gameplay
            - bonus
            - affiliate
            - payment
            - dispute
            - security
            - responsible_gambling
            - custom
          description: 이벤트 카테고리입니다.
          example: auth
        action_type:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            카테고리 내에서 발생한 내용입니다. 개방형 어휘이며, [이벤트
            수집](https://docs.didit.me/ko/transaction-monitoring/events)에 나열된 관리형
            작업(예: `login`, `deposit_completed`, `chargeback_opened`)을 사용하면 형식화된
            검증 및 관리형 규칙 필드가 활성화됩니다. 앞뒤 공백은 제거됩니다.
          example: login
        occurred_at:
          type: string
          format: date-time
          description: >-
            귀하 측에서 이벤트가 발생한 시점, ISO 8601(오프셋이 없는 값은 UTC로 해석됨) 형식입니다. 과거 7일 이내,
            미래 5분 이내여야 합니다.
          example: '2026-10-17T09:15:02.481Z'
        time_zone:
          type: string
          nullable: true
          maxLength: 64
          description: >-
            귀사 측에서 발생한 시점의 시간대(예: `Europe/Madrid`)입니다. 이벤트와 함께 저장되며, 조회
            endpoint에서는 반환되지 않습니다.
        subject:
          type: object
          description: >-
            이벤트가 속한 사용자 또는 기업입니다. 애플리케이션에서 해당 `vendor_data`를 가진 사용자(또는 기업)로
            확인되며, 없는 경우 새로 생성됩니다.
          required:
            - vendor_data
          properties:
            vendor_data:
              type: string
              minLength: 1
              maxLength: 255
              description: 대상에 대한 귀하의 id입니다.
              example: user-42
            entity_type:
              type: string
              maxLength: 32
              default: individual
              description: >-
                `company`는 대상을 기업으로 확인합니다. 다른 값(기본값 `individual`)은 개인으로 확인합니다.
                동일한 `vendor_data`로 각각 하나씩 지정할 수 있습니다.
              example: individual
            full_name:
              type: string
              nullable: true
              maxLength: 512
              description: 표시 이름이며, 이 이벤트로 사용자 또는 기업을 생성할 때만 사용됩니다.
            email:
              type: string
              format: email
              nullable: true
              description: 이메일 주소로서 유효성이 검증되었습니다. 이벤트에 저장되지 않습니다.
            phone:
              type: string
              nullable: true
              maxLength: 32
              description: 검증되었습니다. 이벤트에 저장되지 않습니다.
            country:
              type: string
              nullable: true
              maxLength: 3
              description: 검증되었습니다. 이벤트에 저장되지 않습니다.
        business:
          type: object
          description: 이벤트가 속한 기업입니다(대상과 다른 경우). `vendor_data`만 읽습니다.
          additionalProperties: true
          properties:
            vendor_data:
              type: string
              maxLength: 255
              description: 기업에 대한 귀하의 id입니다. `business_vendor_data`로 필터링할 수 있습니다.
              example: merchant-7
        session:
          type: object
          description: 이벤트에 대한 귀하의 세션 컨텍스트입니다.
          properties:
            session_id:
              type: string
              nullable: true
              maxLength: 255
              description: 귀하의 세션 식별자입니다. 필터링 가능하며 `session_id`로 반환됩니다.
            sequence:
              type: integer
              nullable: true
              description: 세션 내 이벤트의 위치입니다. `session_sequence`로 반환됩니다.
            page_url:
              type: string
              nullable: true
              maxLength: 2048
              description: 검증되었습니다. 이벤트에 저장되지 않습니다.
            referrer:
              type: string
              nullable: true
              maxLength: 2048
              description: 검증되었습니다. 이벤트에 저장되지 않습니다.
        device_context:
          type: object
          additionalProperties: true
          description: >-
            전송된 그대로 저장되고 `GET /v3/events/{event_uuid}/`에 의해 반환되는 기기 및 네트워크
            컨텍스트입니다. 이 서버 레인에서는 Didit이 최종 사용자의 연결을 직접 확인하지 않으므로, 규칙에서 보강되고 사용되는
            IP는 직접 전송한 `network_context.ip_address`입니다.
          properties:
            fingerprint:
              type: string
              maxLength: 255
              description: 기기 핑거프린트입니다. `device_fingerprint`로 필터링할 수 있습니다.
            persistent_device_id:
              type: string
              maxLength: 255
              description: 귀하의 영구 기기 식별자입니다.
            bot_score:
              type: integer
              description: 자체 감지 기능에서 산출된 봇 점수(정수)입니다.
            network_context:
              type: object
              additionalProperties: true
              properties:
                ip_address:
                  type: string
                  maxLength: 64
                  description: 최종 사용자의 IP 주소입니다. 공용 주소는 고유 주소당 한 번씩 보강됩니다.
                  example: 203.0.113.42
        transaction_context:
          type: object
          description: 금액 컨텍스트입니다. 여기에 비어 있지 않은 값이 있으면 작업의 필수 payload 키도 충족됩니다.
          properties:
            amount:
              type: string
              nullable: true
              description: 십진수 문자열 형태의 금액입니다(숫자도 허용됨).
              example: '1000.00'
            currency:
              type: string
              nullable: true
              maxLength: 10
              description: 통화 코드입니다.
            direction:
              type: string
              nullable: true
              maxLength: 16
              description: '자금 이동의 방향입니다(예: `inbound` 또는 `outbound`).'
            payment_reference_id:
              type: string
              nullable: true
              maxLength: 255
              description: 귀하의 결제 참조값입니다. `payment_reference_id`로 필터링할 수 있습니다.
        payload:
          type: object
          additionalProperties: true
          description: >-
            JSON 인코딩 시 최대 16384바이트인 카테고리의 도메인 필드입니다. 일부 작업에는 키(`payload` 또는
            `transaction_context`)가 필요합니다: `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_initiated`,
            `payment.deposit_completed`, `payment.withdrawal_requested` 및
            `payment.withdrawal_completed`에는 `payment_reference_id`, `amount`,
            `currency`, `payment_method`, `status`가 필요합니다.
            `payment.withdrawal_address_changed`에는 `withdrawal_address_hash`가
            필요합니다. `dispute.chargeback_opened`, `dispute.chargeback_won` 및
            `dispute.chargeback_lost`에는 `payment_reference_id` 및 `dispute_id`,
            `chargeback_id` 중 하나가 필요합니다. `session.bot_signal_observed`에는
            `telemetry_schema_version` 및 `bot_score`, `actions_per_minute`,
            `timing_variance_ms`, `pointer_entropy`, `keystroke_entropy`,
            `reaction_time_ms_p50` 중 하나가 필요합니다.
            `responsible_gambling.self_exclusion_match`에는 `registry_source`,
            `exclusion_status`, `identity_match_ref`가 필요합니다. `_changed`로 끝나는 모든
            `security` 작업에는 `changed_field`가 필요하며, 필드가 `password`, `mfa_method`,
            `mfa`, `email`, `phone`, `withdrawal_address`, `payout_method`,
            `api_key`인 경우 `previous_reference_hash` 또는 `new_reference_hash`가 추가로
            필요합니다. 카드 번호, 전체 출금 주소, 비밀번호 해시 또는 MFA 시크릿은 절대 전송하지 말고 해시 및 참조를
            전송하십시오.
        custom_values:
          type: object
          description: >-
            규칙에서 `custom_values.<key>` 형태로 참조할 수 있는 최대 100개의 커스텀 키입니다. 값은
            스칼라(문자열, 숫자, 불리언 또는 null)여야 하며, 중첩된 객체 및 배열은 거부됩니다.
          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
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Business Console의 Developers -> API keys에서 발급받은 귀하 애플리케이션의 API 키입니다. 기본
        키는 전체 접근 권한을 갖습니다. 이름이 지정된 키는 리소스별 none, read, write 범위로 권한을 제한할 수 있으며
        특정 워크플로나 승인된 세션, IP 주소 목록, 만료일 등으로 제한할 수도 있습니다. 401은 키가 잘못되었거나 폐기되었거나
        만료되었음을 의미합니다. 403은 키가 전송되지 않았거나, 키에 해당 리소스나 작업에 대한 접근 권한이 없거나, 요청이 허용된
        IP 목록 외부 주소에서 발생했음을 의미합니다. 세션 경로에서의 404는 해당 세션이 키의 허용 워크플로 또는 상태 범위를
        벗어났음을 의미합니다. 미디어 접근 권한이 없는 키는 이미지, 비디오, PDF URL을 null로 수신하며, 세션 write
        권한이 없는 키는 세션 링크와 token을 null로 수신합니다.
        https://docs.didit.me/console/api-keys 를 참고하십시오.

````

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