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

# 모니터링 SDK 토큰 발급 API

> API 키를 노출하지 않고 앱에서 모니터링 이벤트를 전송할 수 있도록, 한 주체에 묶인 단기 기기 자격 증명을 발급합니다. Didit 제공.



Mint 모니터링 SDK 토큰 발급 API 프롬프트
        프롬프트를 클립보드에 복사



      
      

\<pre>

\`Mint a short-lived device credential so my web or mobile app can send monitoring events for one user straight to Didit.

Endpoint:
POST https://verification.didit.me/v3/events/sdk-token/

Authentication:
Use the x-api-key header with my Didit API key. This call runs on MY BACKEND only - the API key must never ship in an app. Only the returned monitoring_token travels to the device. A scoped key needs transactions: write.

Goal:
\- Get a monitoring_token for the signed-in user. The app sends it in the X-Monitoring-Token header to the device lane (POST /v1/events/ and POST /v1/events/batch/).

Request body (application/json):
\{
"vendor_data": "user-42",                                  // required - the subject every event belongs to
"entity_type": "individual",                               // optional - company binds a company; any other value an individual (default)
"allowed_event_categories": ["auth", "session", "gameplay"], // optional - omit or [] for every category
"ttl_seconds": 900,                                        // optional - 60 to 86400, default 900
"max_uses": 1000,                                          // optional - events it may submit, default 1000, null for no cap
"bind_to_origin": "https://app.example.com"                // optional - browser Origin must match exactly
}
camelCase aliases (vendorData, entityType, allowedEventCategories, ttlSeconds, maxUses, bindToOrigin) are also accepted.

Behavior:
\- The subject is bound server-side: whatever subject the app sends is overwritten with vendor_data.
\- One use per submitted event, also inside a batch: a 500-event flush spends 500 uses, and events the device lane rejects spend uses too.
\- An event outside allowed_event_categories is rejected by the device lane with 400.
\- With bind_to_origin set, a device request with a different Origin, or none, is refused.
\- Minting does not create a user.
\- Event ingestion must be switched on for the application, otherwise this call returns 403 with code event_monitoring_disabled.

Example call:
curl -X POST "https://verification.didit.me/v3/events/sdk-token/" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"vendor_data":"user-42","allowed_event_categories":["auth","session","gameplay"],"ttl_seconds":900,"max_uses":1000}'

What to read from the response:
\- monitoring_token - hand it to the app; treat it as a secret for its lifetime.
\- expires_at - mint a fresh credential per user session before it expires.
\- allowed_event_categories ([] means every category), max_uses (null means no cap), bind_to_origin.

Failure modes:
\- 400 - missing vendor_data, ttl_seconds outside 60-86400, max_uses below 1, or an unknown category.
\- 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.

Side effects: creates one credential. Nothing else changes.

For the full client-side submission guide, see /transaction-monitoring/sdk-event-submission.`

\</pre>



      
      

붙여넣을 곳

이 자격 증명은 [SDK 이벤트 제출](https://docs.didit.me/ko/transaction-monitoring/sdk-event-submission.md)에서 설명하는 기기 경로에서 사용됩니다. 해당 페이지에서는 모든 기기 요청에 대해 서버가 적용하는 조건과, 백프레셔 상황에서 손실되어도 안전한 이벤트도 확인할 수 있습니다.


## OpenAPI

````yaml ko/openapi-25.json POST /v3/events/sdk-token/
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/sdk-token/:
    post:
      tags:
        - Monitoring Events
      summary: 모니터링 SDK token 발급
      description: >-
        단일 주체에 바인딩된 단기 기기 자격 증명을 발급하여, 웹 또는 모바일 앱이 API 키 없이 해당 사용자의 이벤트를 Didit으로
        직접 전송할 수 있도록 합니다. 앱은 반환된 `monitoring_token`을 `X-Monitoring-Token` 헤더에 담아
        기기 레인(`POST /v1/events/` 및 `POST /v1/events/batch/`)으로 전송합니다. 여기서 주체는 항상
        이 `vendor_data`로 덮어쓰여지고, `allowed_event_categories` 외의 이벤트는 거부되며, 제출된 각
        이벤트는 사용 횟수를 1회 소진하고, `Origin`이 `bind_to_origin`과 일치하지 않는 요청은 거절됩니다. 반드시
        백엔드에서만 호출하십시오. 발급 시 자격 증명만 생성되며 다른 작업(사용자 생성 등)은 수행되지 않습니다. 애플리케이션에 이벤트
        수집이 활성화되어 있어야 하며, 그렇지 않은 경우 쓸 수 없는 자격 증명을 발급하는 대신 이 endpoint는 `code:
        event_monitoring_disabled`와 함께 `403`을 반환합니다. 범위 지정 API 키에는
        `transactions: write`가 필요합니다. [SDK 이벤트
        제출](https://docs.didit.me/ko/transaction-monitoring/sdk-event-submission)을
        참조하십시오.
      operationId: create_monitoring_event_sdk_token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: >-
                camelCase 별칭이 허용됩니다: `vendorData`, `entityType`,
                `allowedEventCategories`, `ttlSeconds`, `maxUses`,
                `bindToOrigin`.
              required:
                - vendor_data
              properties:
                vendor_data:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: 이 자격 증명으로 제출된 모든 이벤트가 속한 대상에 대한 귀하의 id입니다.
                entity_type:
                  type: string
                  maxLength: 32
                  default: individual
                  description: >-
                    `company`는 기업 대상을 바인딩합니다. 다른 값(기본값 `individual`)은 개인을
                    바인딩합니다.
                allowed_event_categories:
                  type: array
                  items:
                    type: string
                    enum:
                      - auth
                      - session
                      - gameplay
                      - bonus
                      - affiliate
                      - payment
                      - dispute
                      - security
                      - responsible_gambling
                      - custom
                  description: 자격 증명이 제출할 수 있는 카테고리. 생략하거나 `[]`를 전송하면 모든 카테고리를 허용합니다.
                ttl_seconds:
                  type: integer
                  minimum: 60
                  maximum: 86400
                  default: 900
                  description: 자격 증명의 유효 기간(초 단위)입니다.
                max_uses:
                  type: integer
                  minimum: 1
                  nullable: true
                  default: 1000
                  description: >-
                    자격 증명이 제출할 수 있는 이벤트 수입니다(배치는 이벤트당 1회 사용량을 차감합니다). 유효 기간 내에
                    제한을 두지 않으려면 `null`을 전송하십시오.
                bind_to_origin:
                  type: string
                  maxLength: 255
                  nullable: true
                  description: >-
                    설정된 경우 모든 디바이스 요청의 브라우저 `Origin` 헤더가 이 값과 정확히 일치해야 합니다.
                    `Origin`이 없는 요청은 거부됩니다.
            example:
              vendor_data: user-42
              allowed_event_categories:
                - auth
                - session
                - gameplay
              ttl_seconds: 900
              max_uses: 1000
              bind_to_origin: https://app.example.com
      responses:
        '201':
          description: >-
            자격 증명이 발급되었습니다. 앱에 `monitoring_token`을 전달하고 `expires_at`까지 비밀로
            취급하세요.
          content:
            application/json:
              schema:
                type: object
                required:
                  - monitoring_token
                  - expires_at
                  - allowed_event_categories
                  - max_uses
                  - bind_to_origin
                properties:
                  monitoring_token:
                    type: string
                    description: >-
                      기기 자격 증명(43자의 URL-safe token)입니다. `X-Monitoring-Token` 헤더에
                      담아 전송하세요.
                  expires_at:
                    type: string
                    format: date-time
                    description: 자격 증명이 더 이상 허용되지 않는 시점입니다.
                  allowed_event_categories:
                    type: array
                    items:
                      type: string
                      enum:
                        - auth
                        - session
                        - gameplay
                        - bonus
                        - affiliate
                        - payment
                        - dispute
                        - security
                        - responsible_gambling
                        - custom
                    description: 자격 증명이 제출할 수 있는 카테고리. `[]`는 모든 카테고리를 의미합니다.
                  max_uses:
                    type: integer
                    nullable: true
                    description: 자격 증명의 이벤트 예산입니다. null은 한도가 없음을 의미합니다.
                  bind_to_origin:
                    type: string
                    nullable: true
                    description: 자격 증명이 바인딩된 오리진(Origin) 또는 null입니다.
              example:
                monitoring_token: q7ZtR2xKp9VbN4mWc8LdH1sYfJ3gT6uEaQ0oPiXzBkC
                expires_at: '2026-10-17T09:30:02.481000Z'
                allowed_event_categories:
                  - auth
                  - session
                  - gameplay
                max_uses: 1000
                bind_to_origin: https://app.example.com
        '400':
          description: >-
            검증 실패: `vendor_data` 누락, 60~86400 범위를 벗어난 `ttl_seconds`, 1 미만의
            `max_uses`, 또는 알 수 없는 카테고리(배열 내 위치를 키로 지정)입니다.
          content:
            application/json:
              examples:
                Missing vendor_data:
                  value:
                    vendor_data:
                      - This field is required.
                ttl_seconds too short:
                  value:
                    ttl_seconds:
                      - Ensure this value is greater than or equal to 60.
                Unknown category:
                  value:
                    allowed_event_categories:
                      '1':
                        - '"login" is not a valid choice.'
        '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`, `PATCH`, `DELETE`)은 API 키당 분당 300개의 요청 한도를
            공유합니다. `Retry-After`초 동안 대기한 후 재시도하세요.
          headers:
            Retry-After:
              description: 재시도하기 전 대기할 시간(초)입니다.
              schema:
                type: integer
                minimum: 1
                example: 30
          content:
            application/json:
              examples:
                Throttled:
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST 'https://verification.didit.me/v3/events/sdk-token/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "vendor_data": "user-42",
                "allowed_event_categories": ["auth", "session", "gameplay"],
                "ttl_seconds": 900,
                "max_uses": 1000,
                "bind_to_origin": "https://app.example.com"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.monitoring_events.create_sdk_token(
                vendor_data="user-42",
                allowed_event_categories=["auth", "session", "gameplay"],
                ttl_seconds=900,
                max_uses=1000,
                bind_to_origin="https://app.example.com",
            )
            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.createSdkToken({
              vendor_data: "user-42",
              allowed_event_categories: ["auth", "session", "gameplay"],
              ttl_seconds: 900,
              max_uses: 1000,
              bind_to_origin: "https://app.example.com",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.CreateSDKToken(ctx, didit.MonitoringEventsCreateSDKTokenParams{\n\tVendorData:             \"user-42\",\n\tAllowedEventCategories: didit.Some([]didit.MonitoringEventsCreateSDKTokenParamsAllowedEventCategories{\"auth\", \"session\", \"gameplay\"}),\n\tTTLSeconds:             didit.Int(900),\n\tMaxUses:                didit.Int(1000),\n\tBindToOrigin:           didit.String(\"https://app.example.com\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.util.List;

            import me.didit.Didit;

            import me.didit.types.MonitoringEventsCreateSdkTokenParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.monitoringEvents().createSdkToken(MonitoringEventsCreateSdkTokenParams.builder()
                    .vendorData("user-42")
                    .allowedEventCategories(List.of(MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of("auth"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of("session"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of("gameplay")))
                    .ttlSeconds(900L)
                    .maxUses(1000L)
                    .bindToOrigin("https://app.example.com")
                    .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->createSdkToken([
                'vendor_data' => 'user-42',
                'allowed_event_categories' => ['auth', 'session', 'gameplay'],
                'ttl_seconds' => 900,
                'max_uses' => 1000,
                'bind_to_origin' => 'https://app.example.com',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.monitoring_events.create_sdk_token(
              vendor_data: "user-42",
              allowed_event_categories: ["auth", "session", "gameplay"],
              ttl_seconds: 900,
              max_uses: 1000,
              bind_to_origin: "https://app.example.com"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.MonitoringEvents.CreateSdkTokenAsync(new
            MonitoringEventsCreateSdkTokenParams

            {
                VendorData = "user-42",
                AllowedEventCategories = new MonitoringEventsCreateSdkTokenParamsAllowedEventCategories[] { "auth", "session", "gameplay" },
                TtlSeconds = 900,
                MaxUses = 1000,
                BindToOrigin = "https://app.example.com",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  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.